Я получил проект для решения, который использует Enums, и я немного застрял. Это игра в крестики-нолики, в которой есть перечисления, в которых хранятся местоположения ячеек в таблице сетки 3х3, и перечисления, в которых хранится состояние ячеек (пусто, X или O). Кроме того, у меня есть интерфейс для GameBoard, который возвращает CellState: getCellState (CellLocation cellLocation);

Моя задача - написать только интерфейс Consultant, и я не могу ничего изменить в предоставленном мне коде. Я пытаюсь проверить состояние Board перед каждым шагом.

Моя идея состояла в том, что X запускает игру, я использую цикл for для шагов и на каждом шаге я проверяю if nrOfSteps%2==0. Если да , я устанавливаю cellState для игрока О. Проверьте, находимся ли мы на выигрышной позиции, выиграли ли мы или есть ничья. Если нет, я предложу переехать. Например.

if (nrOfSteps%2!=0){
    cState =CellState.OCCUPIED_BY_X;
      if (isWon(cState, board)){
        throw new IllegalStateException("Player X won!");
      } else if (draw(board, locations)){
        throw new IllegalStateException("No more empty fields!");
      } else
        for (int remainingCells = 0; remainingCells <9; remainingCells++) {
            if (board.equals(locations[remainingCells]) && 
            cState==CellState.EMPTY){
            availableCells[index] = locations[remainingCells];
            index++;
        }
        CellLocation cellToTake = availableCells[(int)(Math.random()*
        (availableCells.length-1))];
        return cellToTake;
}

Теперь моя проблема в том, что я попробовал следующее для метода isWon (частичный код проверяет только первую строку):

private boolean isWon(CellState player, GameBoard board){
if (board.equals(CellLocation.TOP_LEFT) && cState==player &&
    board.equals(CellLocation.TOP_CENTRE) && cState==player && 
    board.equals(CellLocation.TOP_RIGHT) && cState==player){
  return true;
}

return false;
}

Но я понял, что текущий статус платы не может быть равен только одной ячейке, как я проверяю в приведенном выше коде. И это, очевидно, не может быть равно 3 различным "только одна клетка" -s. И я даже не уверен, смогу ли я проверить, была ли на доске только одна клетка, занятая игроком X:

board.equals (CellLocation.TOP_LEFT) && cState==player

Может, кто-нибудь подскажет, как я могу объединить оба CellState и CellLocation в один запрос? Должен ли я использовать массивы? например CellState[][] ?

2
Vero 28 Май 2017 в 20:29

2 ответа

Лучший ответ

Вы можете рассчитать суммы ячеек в матрице (для каждого столбца, строки и диагонали). Как это:

import java.io.IOException;
import java.util.Arrays;
import java.util.Random;

public class CrossAndZeros {
    private static CellState winner;
    private static Enum[][] field = new Enum[3][3];

    public static void main(String[] args) throws IOException {

        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
                field[i][j] = CellState.values()[new Random().nextInt(3)];
            }
        }

        for (Enum[] enums : field) {
            System.out.println(Arrays.toString(enums));
        }
        System.out.println();

        System.out.println("Winner is found: " + isWinnerFound());

        System.out.println(winner == null ? "No winner, GAME OVER" : winner);
    }

    private static boolean isWinnerFound() {
        int[] result = calculate();
        int count = 0;

        for (int win : result) {
            if (win == 3) {
                winner = CellState.OCCUPIED_BY_X;
                return true;
            } else if (win == -12) {
                winner = CellState.OCCUPIED_BY_O;
                return true;
            } else if (win == -9 || win == -2 || win == -3) { // This means that the line is spoilt
                count++;
            }
        }
        return count == 8; // If all the lines are spoilt, the game is over
    }

    private static int[] calculate() {
        int[] result = new int[8];

        for (int i = 0; i < field.length; i++) {
            for (int j = 0; j < field[i].length; j++) {
            result[i] += getCellOwner(field[j][i]); // a column
            result[i + 3] += getCellOwner(field[i][j]); // a row
        }
        result[field.length * 2] += getCellOwner(field[i][i]); // diagonal
        result[field.length * 2 + 1] += getCellOwner(field[i][field.length - i - 1]); // diagonal

        }

        System.out.println(Arrays.toString(result));

        return result;
    }

    private static int getCellOwner(Enum cell) {
        switch ((CellState) cell) {
            case OCCUPIED_BY_O:
                return -4;
            case OCCUPIED_BY_X:
                return 1;
            case EMPTY:
            default:
                return 0;
        }
    }

    public enum CellState {
        /**
         * this cell is occupied by player X
         */
        OCCUPIED_BY_X,

        /**
         * this cell is occupied by player O
         */
        OCCUPIED_BY_O,

        /**
         * this cell is Empty
         */
        EMPTY
    }
}
2
Yuri Heiko 31 Май 2017 в 06:49

Перечисление CellLocation:

public enum CellLocation {
    /** The Cell in the top row and leftmost column */
    TOP_LEFT,

    /** The Cell in the top row and centre column */
    TOP_CENTRE,

    /** The Cell in the top row and rightmost column */
    TOP_RIGHT,

    /** The Cell in the centre row and leftmost column */
    CENTRE_LEFT,

    /** The Cell in the centre row and centre column */
    CENTRE_CENTRE,

    /** The Cell in the centre row and rightmost column */
    CENTRE_RIGHT,

    /** The Cell in the bottom row and leftmost column */
    BOTTOM_LEFT,

    /** The Cell in the bottom row and centre column */
    BOTTOM_CENTRE,

    /** The Cell in the bottom row and rightmost column */
    BOTTOM_RIGHT;
}

Перечисление CellState:

public enum CellState {
/** this cell is occupied by player X */
OCCUPIED_BY_X,

/** this cell is occupied by player O */
OCCUPIED_BY_O,

/** this cell is Empty */
EMPTY;

}

1
Vero 29 Май 2017 в 20:59