Проблема в логике опредления победителя и ничьи
Создаю свой проект "крестики-нолики" для упражнения в разных аспектах программирования. После написания бота возникла проблема с логикой игры, так как если заполняются все поля И кто-то выигрывает, то выводит два окна, что игра закончилась ничьей И другим - выиграл игрок 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 шт):
По представленному коду не совсем понятно, как именно проверяется выигрыш каждого игрока, так как такую проверку следует делать после каждого "полухода".
Выигрывает тот, кто первым заполняет три элемента, и если этого добился игрок, начавший игру, она должна сразу завершиться, а не давать возможность закончить свой полуход второму игроку.
Следовательно, проверка на заполнение всего поля нужна фактически лишь для проверки ничейного исхода (хотя ничью можно вычислить и по-другому).
Таким образом, логику можно переопределить следующим образом:
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;
}
}
}