Проблема в логике опредления победителя и ничьи

Создаю свой проект "крестики-нолики" для упражнения в разных аспектах программирования. После написания бота возникла проблема с логикой игры, так как если заполняются все поля И кто-то выигрывает, то выводит два окна, что игра закончилась ничьей И другим - выиграл игрок N.

public class GameLogic extends HelloApplication {
    private final int[][] pole;
    public boolean allCellsFilled;

    public GameLogic(int[][] pole) {
        this.pole = pole;
    }

    public boolean allCellsFilled() {
        // Проверяем, заполнены ли все ячейки
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (pole[i][j] == 0) {
                    return false; // Если хоть одна ячейка не заполнена, возвращаем false
                }
            }
        }
        // Если все ячейки заполнены и никто не победил, возвращаем true
        return true;
    }

    public boolean checkWin(int player) {
        // Проверка строк
        for (int i = 0; i < 3; i++) {
            if (pole[i][0] == player && pole[i][1] == player && pole[i][2] == player) {
                return true;
            }
        }
        // Проверка столбцов
        for (int j = 0; j < 3; j++) {
            if (pole[0][j] == player && pole[1][j] == player && pole[2][j] == player) {
                return true;
            }
        }
        // Проверка диагоналей
        return (pole[0][0] == player && pole[1][1] == player && pole[2][2] == player) ||
                (pole[0][2] == player && pole[1][1] == player && pole[2][0] == player);
    }
}

Эту логику я отсылаю сюда (добавлено после замечания неполноты картины, поэтому проблема ничьи и выигрыша решена, но появилась новая: могут выиграть два игрока одновременно, возникает при игре с ботом)

if (gameLogic.checkWin(currentPlayer) && !gameLogic.allCellsFilled()) {
    ShowGameResult(primaryStage, "Победитель: игрок " + currentPlayer);
}
if (gameLogic.checkWin(currentPlayer) && gameLogic.allCellsFilled())
    ShowGameResult(primaryStage, "Победитель: игрок " + currentPlayer);
if (gameLogic.allCellsFilled() && !gameLogic.checkWin(currentPlayer))
    ShowGameResult(primaryStage, "Ничья!");

Как бы не пытался фиксить это, вводя дополнительные проверки, итог один - ошибка, либо та же проблема.


Ответы (1 шт):

Автор решения: Nowhere Man

По представленному коду не совсем понятно, как именно проверяется выигрыш каждого игрока, так как такую проверку следует делать после каждого "полухода".
Выигрывает тот, кто первым заполняет три элемента, и если этого добился игрок, начавший игру, она должна сразу завершиться, а не давать возможность закончить свой полуход второму игроку.

Следовательно, проверка на заполнение всего поля нужна фактически лишь для проверки ничейного исхода (хотя ничью можно вычислить и по-другому).

Таким образом, логику можно переопределить следующим образом:

Scanner sc = new Scanner(System.in);
out: while (true) { // внешний цикл для ходов
    for (int player = 1; player < 3; player++) {
        int x, y; // "координаты" ячейки для хода
        do {
            System.out.println("Ходит игрок " + player);
            x = sc.nextInt() % 3;
            y = sc.nextInt() % 3;
        } while (!game.move(player, x, y)); // move возвращает false если ход невозможен
        // вывод состояния поля после корректного хода
        game.print();

        if (game.checkWin(player)) {   // проверка выигрыша после полухода
            System.out.println("Выиграл игрок " + player);
            break out;
        } else if (game.allFilled()) { // никто не выиграл, поле заполнено
            System.out.println("Ничья!");
            break out;
        }
    }
}

Онлайн демо

→ Ссылка