Игра TicTacToe - Java
Формулировка задачи:
Привет, всем! Написал игру TicTacToe, по книге Якова Файна, но есть одна проблема. Игра запускается, играет, если первая игра выиграна или проиграна, дальше идет все нормально, но если первая игра сыграна в ничью, то игра зависает на последнем ходу. Подскажите в чем проблема. Интерфейс игры писал сам, логику игры списал с книги.
Прилагаю фото игры, здесь все нормально.
Здесь зависла на последнем ходу
Решение задачи: «Игра TicTacToe»
textual
Листинг программы
/** * Этот метод будет обрабатывать все события * * @param ActionEvent объект */ @Override public void actionPerformed(ActionEvent e) { Object theButton = e.getSource(); // Это кнопка New Game ? if (theButton == newGameButton) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { squares[i][j].setEnabled(true); squares[i][j].setText(""); squares[i][j].setBackground(Color.WHITE); } } emptySquaresLeft = 9; score.setText(" Поиграем?"); return; // выходим из метода } String winner = ""; // Это одна из клеток? for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (theButton == squares[i][j]) { squares[i][j].setText("X"); squares[i][j].setEnabled(false); winner = lookForWinner(); if (!"".equals(winner)) { endTheGame(); } else { computerMove(); winner = lookForWinner(); if (!"".equals(winner)) { endTheGame(); } } break; } } // конец цикла for } if (winner.equals("X")) { score.setText(" Вы выграли!"); while (true) { count++; break; } counter.setText(" счет: " + count + ":" + countcomp); } else if (winner.equals("O")) { score.setText(" Вы проиграли!"); while (true) { countcomp++; break; } counter.setText(" счет: " + count + ":" + countcomp); } else if (winner.equals("T")) { score.setText(" Ничья!"); counter.setText(" счет: " + count + ":" + countcomp); } } // конец метода actionPerformed /** * Этот метод вызывается после каждого хода, чтобы узнать, * есть ли победитель. Он проверяет каждый ряд, колонку * и диагональ, чтобы найти три клетки с одинаковыми надписями * (не пустыми) * * @return "X", "O", "T" – ничья, "" - еще нет победителя */ String lookForWinner() { String theWinner = ""; emptySquaresLeft--; if (emptySquaresLeft == 0) { return "T"; // это ничья. T от английского слова tie } // Проверяем ряд 1 – элементы массива 0,1,2 if (!squares[0][0].getText().equals("") && squares[0][0].getText().equals(squares[0][1].getText()) && squares[0][0].getText().equals(squares[0][2].getText())) { theWinner = squares[0][0].getText(); //так как массив двумерный, поэтому заносим индексы //из 6 цифр. Метод выделения выигрышных клеток highlightWinner(0, 0, 0, 1, 0, 2); // Проверяем ряд 2 – элементы массива 3,4,5 } else if (!squares[1][0].getText().equals("") && squares[1][0].getText().equals(squares[1][1].getText()) && squares[1][0].getText().equals(squares[1][2].getText())) { theWinner = squares[1][0].getText(); highlightWinner(1, 0, 1, 1, 1, 2); // Проверяем ряд 3 – элементы массива 6,7,8 } else if (!squares[2][0].getText().equals("") && squares[2][0].getText().equals(squares[2][1].getText()) && squares[2][0].getText().equals(squares[2][2].getText())) { theWinner = squares[2][0].getText(); highlightWinner(2, 0, 2, 1, 2, 2); // Проверяем колонку 1 – элементы массива 0,3,6 } else if (!squares[0][0].getText().equals("") && squares[0][0].getText().equals(squares[1][0].getText()) && squares[0][0].getText().equals(squares[2][0].getText())) { theWinner = squares[0][0].getText(); highlightWinner(0, 0, 1, 0, 2, 0); // Проверяем колонку 2 – элементы массива 1,4,7 } else if (!squares[0][1].getText().equals("") && squares[0][1].getText().equals(squares[1][1].getText()) && squares[0][1].getText().equals(squares[2][1].getText())) { theWinner = squares[0][1].getText(); highlightWinner(0, 1, 1, 1, 2, 1); // Проверяем колонку 3 – элементы массива 2,5,8 } else if (!squares[0][2].getText().equals("") && squares[0][2].getText().equals(squares[1][2].getText()) && squares[0][2].getText().equals(squares[2][2].getText())) { theWinner = squares[0][2].getText(); highlightWinner(0, 2, 1, 2, 2, 2); // Проверяем первую диагональ – элементы массива 0,4,8 } else if (!squares[0][0].getText().equals("") && squares[0][0].getText().equals(squares[1][1].getText()) && squares[0][0].getText().equals(squares[2][2].getText())) { theWinner = squares[0][0].getText(); highlightWinner(0, 0, 1, 1, 2, 2); // Проверяем вторую диагональ – элементы массива 2,4,6 } else if (!squares[0][2].getText().equals("") && squares[0][2].getText().equals(squares[1][1].getText()) && squares[0][2].getText().equals(squares[2][0].getText())) { theWinner = squares[0][2].getText(); highlightWinner(0, 2, 1, 1, 2, 0); } return theWinner; } void computerMove() { int selectedSquare; // Сначала компьютер пытается найти пустую клетку // рядом с двумя клетками с ноликами, чтобы выиграть selectedSquare = findEmptySquare("O"); // Если он не может найти два нолика, то хотя бы // попытается не дать оппоненту сделать ряд из 3-х // крестиков,поместив нолик рядом с двумя крестиками if (selectedSquare == -1) { selectedSquare = findEmptySquare("X"); } // если selectedSquare все еще равен -1, то // попытается занять центральную клетку if ((selectedSquare == -1) && (squares[1][1].getText().equals(""))) { selectedSquare = 1; printMove(selectedSquare, selectedSquare); } // не повезло с центральной клеткой... // просто занимаем случайную клетку if (selectedSquare == -1) { selectedSquare = getRandomSquare(); } } //печать ноликов компьютером, так как массив //кнопок имеет разные типы //нужен отдельный метод для вывода на экран ноликов int printMove(int x, int y) { squares[x][y].setText("O"); squares[x][y].setEnabled(false); return 0; } /** * Этот метод проверяет каждый ряд, колонку и диагональ * чтобы узнать, есть ли в ней две клетки * с одинаковыми надписями и пустой клеткой. * * @param передается X – для пользователя и O – для компа * @return количество свободных клеток, * или -1, если не найдено две клетки * с одинаковыми надписями */ int findEmptySquare(String player) { int weight[][] = new int[3][3]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (squares[i][j].getText().equals("O")) weight[i][j] = -1; else if (squares[i][j].getText().equals("X")) weight[i][j] = 1; else weight[i][j] = 0; } } int twoWeights = player.equals("") ? -2 : 2; // Проверим, есть ли в ряду 1 две одинаковые клетки и // одна пустая. if (weight[0][0] + weight[0][1] + weight[0][2] == twoWeights) { if (weight[0][0] == 0) //присваиваем методу индексы клетки return printMove(0, 0); else if (weight[0][1] == 0) return printMove(0, 1); else return printMove(0, 2); } // Проверим, есть ли в ряду 2 две одинаковые клетки и // одна пустая. if (weight[1][0] + weight[1][1] + weight[1][2] == twoWeights) { if (weight[1][0] == 0) return printMove(1, 0); else if (weight[1][1] == 0) return printMove(1, 1); else return printMove(1, 2); } // Проверим, есть ли в ряду 3 две одинаковые клетки и // одна пустая. if (weight[2][0] + weight[2][1] + weight[2][2] == twoWeights) { if (weight[2][0] == 0) return printMove(2, 0); else if (weight[2][1] == 0) return printMove(2, 1); else return printMove(2, 2); } // Проверим, есть ли в колонке 1 две одинаковые клетки и // одна пустая. if (weight[0][0] + weight[1][0] + weight[2][0] == twoWeights) { if (weight[0][0] == 0) return printMove(0, 0); else if (weight[1][0] == 0) return printMove(1, 0); else return printMove(2, 0); } // Проверим, есть ли в колонке 2 две одинаковые клетки // и одна пустая. if (weight[0][1] + weight[1][1] + weight[2][1] == twoWeights) { if (weight[0][1] == 0) return printMove(0, 1); else if (weight[1][1] == 0) return printMove(1, 1); else return printMove(2, 1); } // Проверим, есть ли в колонке 3 две одинаковые клетки // и одна пустая. if (weight[0][2] + weight[1][2] + weight[2][2] == twoWeights) { if (weight[0][2] == 0) return printMove(0, 2); else if (weight[1][2] == 0) return printMove(1, 2); else return printMove(2, 2); } // Проверим, есть ли в диагонали 1 две одинаковые клетки // и одна пустая. if (weight[0][0] + weight[1][1] + weight[2][2] == twoWeights) { if (weight[0][0] == 0) return printMove(0, 0); else if (weight[1][1] == 0) return printMove(1, 1); else return printMove(2, 2); } // Проверим, есть ли в диагонали 2 две одинаковые клетки // и одна пустая. if (weight[0][2] + weight[1][1] + weight[2][0] == twoWeights) { if (weight[0][2] == 0) return printMove(0, 2); else if (weight[1][1] == 0) return printMove(1, 1); else return printMove(2, 0); } // Не найдено двух одинаковых соседних клеток return -1; } // конец метода findEmptySquare() /** * Этот метод выбирает любую пустую клетку * * @return случайно выбранный номер клетки */ int getRandomSquare() { boolean gotEmptySquare = false; int selectedSquare = -1; int selectedSquare1 = 0; do { //так как у двумерного массива два индекса //поэтому создаем два рандомных числа //с помощью которых будем искать пустую клетку selectedSquare = (int) (Math.random() * 3); selectedSquare1 = (int) (Math.random() * 3); if (squares[selectedSquare][selectedSquare1].getText().equals("")) { gotEmptySquare = true; // чтобы закончить цикл } } while (!gotEmptySquare); //печатаем нолик return printMove(selectedSquare, selectedSquare1); } // конец метода getRandomSquare() /** * Этот метод выделяет выигравшую линию. * * @param первая, вторая и третья клетки для выделения */ void highlightWinner(int win1, int win2, int win3, int win4, int win5, int win6) { //выделяем клетки которые победили! squares[win1][win2].setBackground(Color.BLACK); squares[win3][win4].setBackground(Color.BLACK); squares[win5][win6].setBackground(Color.BLACK); } // Делаем недоступными клетки и доступной кнопку ”New Game” void endTheGame() { newGameButton.setEnabled(true); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { squares[i][j].setEnabled(false); } } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д