Игра 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);
- }
- }
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д