Домашнее задание к занятию "Массивы многомерные"
Описание
Возьмём за основу игру крестики-нолики с вебинара и допишем метод проверки победы одного из игроков, переписав его на циклы. Так он будет работать при любом значении SIZE.
Образ результата
- Вы дописываете метод
isWinтак, что он работает для любого значенияSIZE - Удаляете содержимое метода
main, заполняете его кодом, запуск которого демонстрирует правильную работу вашего методаisWinна разных примерах (пример вывода программы дан ниже); - На проверку отправляете реплит, в котором есть статическое поле
SIZEсо значением 5 (остальные статические поля оставляете как есть), методisWinи методmain, в котором вы демонстрируете работу этого метода на разных видах полей; остальные методы и код можно удалить. - Общаться с пользователем (спрашивать у него что-то, делать ходы и тп) не нужно
Пример вывода при запуске main
ДЕМОНСТРАЦИЯ
O O O - -
X X X X X
X O X O X
O O - O X
O - O X X
ПОБЕДИЛИ КРЕСТИКИ
X O - - -
- X O - -
X - X O -
O O - X -
O - - X X
ПОБЕДИЛИ КРЕСТИКИ
O O O O O
X X X - -
X - X X X
O - - - X
O - - - -
ПОБЕДИЛИ НОЛИКИ
X O X O X
O X O X O
- - X - -
- - - - -
- - - - -
НИКТО НЕ ПОБЕДИЛ
Код игры в крестики-нолики
import java.util.Scanner; public class Main { public static final int SIZE = 3; public static final char EMPTY = '-'; public static final char CROSS = 'X'; public static final char ZERO = 'O'; public static void main(String[] args) { char[][] field = new char[SIZE][SIZE]; for (int i = 0; i < SIZE; i++) { for (int j = 0; j < SIZE; j++) { field[i][j] = EMPTY; } } Scanner scanner = new Scanner(System.in); boolean isCrossTurn = true; while (true) { printField(field); System.out.println("Ходят " + (isCrossTurn ? "крестики" : "нолики") + "!"); String input = scanner.nextLine(); // "2 3" String[] parts = input.split(" "); // ["2" , "3"] int r = Integer.parseInt(parts[0]) - 1; // 2-1 = 1 int c = Integer.parseInt(parts[1]) - 1; // 3-1 = 2 if (field[r][c] != EMPTY) { System.out.println("Сюда ходить нельзя"); continue; } field[r][c] = isCrossTurn ? CROSS : ZERO; if (isWin(field, isCrossTurn ? CROSS : ZERO)) { printField(field); System.out.println("Победили " + (isCrossTurn ? "крестики" : "нолики")); break; } else { if (isCrossTurn) { isCrossTurn = false; } else { isCrossTurn = true; } //isCrossTurn = !isCrossTurn; } } System.out.println("Игра закончена!"); } // !!ВНИМАНИЕ!! // Работает только для 3x3 // Этот метод вам и надо переписать public static boolean isWin(char[][] field, char player) { if (field[0][0] == player && field[0][1] == player && field[0][2] == player) return true; if (field[1][0] == player && field[1][1] == player && field[1][2] == player) return true; if (field[2][0] == player && field[2][1] == player && field[2][2] == player) return true; if (field[0][0] == player && field[1][0] == player && field[2][0] == player) return true; if (field[0][1] == player && field[1][1] == player && field[2][1] == player) return true; if (field[0][2] == player && field[1][2] == player && field[2][2] == player) return true; if (field[0][0] == player && field[1][1] == player && field[2][2] == player) return true; if (field[2][0] == player && field[1][1] == player && field[0][2] == player) return true; return false; } public static void printField(char[][] field) { for (char[] row : field) { for (char cell : row) { System.out.print(cell + " "); } System.out.println(); } } }
Советы по реализации
- Для начала всмотритесь в этот метод и найдите повторяющиеся закономерности. Если вы плохо себе представляете какие ячейки тут проверяются, нарисуйте поле на листочке и посмотрите на клетки поля каждой строки кода на рисунке.
- Рассмотрим на примере проверки заполненности строк. Мы видим, что первые три условные оператора повторятся с точностью до первого индекса (номер строки), поэтому мы можем сделать цикл:
for (int row = 0; row < SIZE; row++) { // обратите внимание, что мы поставили SIZE, а не 3, чтобы работало с любым значением if (field[row][0] == player && field[row][1] == player && field[row][2] == player) return true; }
- Того что мы сделали недостаточно, тк если в строке будет больше трёх клеток, то наш
ifвсё равно проверит лишь первые три. Для этого и условный оператор надо переписать на вложенный цикл. Идея его такова: заведём переменную для подсчёта количестваplayerв строке, изначально она будет 0. Пробежимся по всем клеткам строки, для каждой клетки, если тамplayer, увеличим эту переменную на 1. После цикла по клеткам строки, сравним эту переменную сSIZE. Если она не будет равнаSIZE, значит не во всех клетках былplayer; если будет равна, значитplayerпобедил и возвращаемtrue. - На проверку предоставляем только метод
isWinс демонстрацией его работоспособности вmain.