# Multidimensionler Array - Elemente vergleichen (TicTacToe)



## Apple_Mac (7. Jul 2017)

Moin,
ich programmiere gerade TicTacToe. Nun bin ich bei der Programmierung des Computers angelangt(KI). Um immer zu verhindern,dass der Spieler gewinnt soll der Computer das Spielfeld(Array: Feld[3][3]) vergleichen und schauen ob schon 2 Kreuzen nebeneinander liegen. Wie geht das ohne jeden Fall einzeln mit einer If-Anweisung abzufragen.

lg 
Simon


----------



## lant (7. Jul 2017)

Das kannst du mit for - Schleifen machen. Du müsstest dann einmal alle vertikalen, horizontalen und diagonalen Fälle mit diesen abarbeiten. Für jeden Fall solltest du wohl immer eine separate for - Schleife verwenden.


----------



## Apple_Mac (7. Jul 2017)

Okay danke


----------



## DrZoidberg (7. Jul 2017)

Hier ist mal ein Beispiel wie man das relativ kurz schreiben kann. Ich gehe davon aus, dass eine 1 im Array für ein Kreuz steht und eine 0 für ein leeres Feld. Die Methode gibt die Koordinaten von dem Feld zurück, auf das die KI setzen muss um den Spieler zu blockieren.

```
static int[] test(int[][] array) {
    int[] comb =  {
        0,0, 0,1, 0,2,
        1,0, 1,1, 1,2,
        2,0, 2,1, 2,2,
        0,0, 1,0, 2,0,
        0,1, 1,1, 2,1,
        0,2, 1,2, 2,2,
        0,0, 1,1, 2,2,
        0,2, 1,1, 2,0
    };

    for(int i = 0; i < comb.length; i += 6) {
        int row = -1, col = -1, numCross = 0;
        for(int j = i; j < i+6; j += 2) {
            int x = array[comb[j]][comb[j+1]];
            if(x == 0) {
                row = comb[j];
                col = comb[j+1];
            } else if(x == 1) {
                numCross++;
            }
        }
        if(numCross == 2 && row >= 0 && col >= 0) {
            return new int[] {row, col};
        }
    }
    return null;
}
```


----------



## Blender3D (9. Jul 2017)

Tic Tac Toe kann man auch als 8 integer Zahlen mit nur 3 Bits interpretieren.
3 waagrecht
3 senkrecht
2 diagonal
Um dann zu überprüfen ob nur noch ein Stein fehlt nimmt man 3 integer  Bitmask die man über die Zahlen legt.
3  binär 011
5  binär 101
6  binär 110
7  binär 111 währe Spielende.
x0x
0x0
000

Hier ein Code Beispiel für eine Klasse die das realisiert.

```
import java.awt.Point;

public class TicTacToe {
    private int[] field = new int[3];

    /**
     * Diagonal numbers 6 or 7.
     *
     * @param id
     * @return int
     */
    private int diagonalNumber(int id) {
        if (id == 0)
            return (field[0] & 4) + (field[1] & 2) + (field[2] & 1);
        return (field[0] & 1) + (field[1] & 2) + (field[2] & 4);
    }

    /**
     * Number 0 - 2 == field[0-2] _____________________horizontal_____________
     * Number 3 - 4 == bit 3-1 of field[0-2] __________vertical_______________
     * Number 5 - 6 == diagonal bits of field[0-2] ____diagonal_______________
     * All in all 8 numbers (3 bit integers) representing the playing field. If
     * you get 3, 5 or 6 (011, 101, 110 ) --> one move to finish the game.
     *
     *
     * @param id
     * @return int
     */
    public int getNumber(int id) {
        if (id < 0 || id > 7)
            return -1;
        if (id < 3)
            return field[id];
        if (id < 6)
            return verticalNumber(id - 3);

        return diagonalNumber(id - 6);
    }

    /**
     * Checks if only one move is left to finish the game.
     *
     * @return Point representing coordinates of last missing stone or null.
     */
    public Point getOneMoveOverPos() {
        int[] maskForTwo = { 3, 5, 6 };// 011, 101, 110
        for (int id = 0; id < 8; id++) {
            int num = getNumber(id);
            for (int i = 0; i < maskForTwo.length; i++) {
                if ((num & maskForTwo[i]) == maskForTwo[i])
                    return getNumberLastOpenPos(id, i);
            }
        }
        return null;
    }

    private Point getNumberLastOpenPos(int id, int i) {
        if (id < 2) // horizontal numbers
            return new Point(i, id);
        if (id < 6) // vertical numbers
            return new Point(id % 3, i);
        if (id == 6 || i == 1)
            return new Point(i, i);
        // diagonal numbers
        return i == 2 ? new Point(2, 0) : new Point(0, 2);

    }

    public void reset() {
        for (int i = 0; i < field.length; i++)
            field[i] = 0;
    }

    public boolean setStone(int x, int y) {
        if (x < 0 || x > 2 || y < 0 || y > 2)
            return false;
        int xMaskPos = 4; // binary 100
        xMaskPos >>= x; // moves x bit to right side e.g. x = 2 --> 001
        field[y] |= xMaskPos;
        return true;
    }

    @Override
    public String toString() {
        String tmp = "";
        for (int y = 0; y < field.length; y++) {
            int xMaskPos = 4; // binary 100
            for (int x = 0; x < field.length; x++) {
                tmp += (field[y] & xMaskPos) != 0 ? "x" : "o";
                xMaskPos >>= 1; // move mask 1 bit right
            }
            tmp += "\n";
        }
        return tmp;
    }

    /**
     * Vertical numbers 3 - 5.
     *
     * @param x
     * @return int
     */
    private int verticalNumber(int x) {
        int xMaskPos = 4;// binary 100
        int xMaskAdd = 4;// binary 100
        xMaskPos >>= x;
        int num = 0;

        for (int y = 0; y < field.length; y++) {
            if ((field[y] & xMaskPos) != 0)
                num += xMaskAdd;
            xMaskAdd >>= 1;
        }
        return num;
    }

}
```


----------

