Добавить в корзинуПозвонить
Найти в Дзене
Программы от меня

Крестики-нолики на Java (которые потом мы перенесем на Android)

Доброго времени суток, дорогие друзья, падаваны и магистры, маленькие дети, а также дети младшего, среднего, старшего, очень старшего и пожилого возраста! Снова сегодня на арене игра "Крестики-нолики", но на этот раз будем использовать язык программирования Java. Правила игры "Крестики-нолики" известна нам еще со школы. Рисуется игровое поле из клеток, размером 3х3 (3 клетки в ширину, 3 клетки в высоту). Два игрока поочередно рисуют в эти клетки либо крестик, либо нолик (каждый игрок рисует "фигуры" одного типа). Задача игрока - занять своими фигурами либо три клетки на одной горизонтали, либо три клетки на одной вертикали, либо три клетки на одной диагонали. Кто первый выполнит это условие, тот и выиграл. Естественно, после выигрыша одного из игроков игра прекращается. Итак, в нашем случае игра будет консольной, за X будет играть человек (мы), за О - компьютер. Следовательно, Х будем вводить мы с клавиатуры, а О - компьютер, пользуясь собственными системами ввода, которые мы ем
Оглавление

Доброго времени суток, дорогие друзья, падаваны и магистры, маленькие дети, а также дети младшего, среднего, старшего, очень старшего и пожилого возраста! Снова сегодня на арене игра "Крестики-нолики", но на этот раз будем использовать язык программирования Java.

Правила игры

Правила игры "Крестики-нолики" известна нам еще со школы. Рисуется игровое поле из клеток, размером 3х3 (3 клетки в ширину, 3 клетки в высоту). Два игрока поочередно рисуют в эти клетки либо крестик, либо нолик (каждый игрок рисует "фигуры" одного типа). Задача игрока - занять своими фигурами либо три клетки на одной горизонтали, либо три клетки на одной вертикали, либо три клетки на одной диагонали. Кто первый выполнит это условие, тот и выиграл. Естественно, после выигрыша одного из игроков игра прекращается.

-2

Вся наша жизнь - игра!

Итак, в нашем случае игра будет консольной, за X будет играть человек (мы), за О - компьютер. Следовательно, Х будем вводить мы с клавиатуры, а О - компьютер, пользуясь собственными системами ввода, которые мы ему опишем. Но обо всём по порядку.

Создаем проект программы на Java - весь код у нас будет внутри класса Game (он public), и методом main создаем экземпляр класса Game и запускаем его методом startGame (пока конструктора класса и метода startGame нет, напишем чуть позже).

-3

С чего начать


Начнем писать код. Зададим основные константы (свойства Game): размер поля
SIZE, игроки PLAYER_X, PLAYER_0, которые играют соответственно играют крестиками PLAYER_X и ноликами PLAYER_0 и пустой символ EMPTY, который нам понадобится при первичном заполнении полей.

Задали? Отлично! Теперь создаем игровое поле board, представляющее собой двумерный массив из символов char и currentPlayer - текущий игрок.



-4

Инициация игрового поля и заполнение полей.

Ну а вот и долгожданный конструктор класса Game. В нем мы создаем поле board размером SIZExSIZE (напоминаем, SIZE=3) и инициируем поле методом initiaizeBoard.

-5

initiaizeBoard - пустой (void) метод, который ничего не возвращает, а просто через цикл заполняет элементы board значениями константы EMPTY. Ничего сложного.

-6

Ну и соответственно игровое поле нам надо выводить на печать в консоли. Создадим для этого сразу метод printBoard(). Вложенный цикл, вывод значений и псевдографики через System.out.print() и System.out.println()

-7

Победа, поражение или ничья

- Пап, а разве из палки можно попасть в человека?
- Поверь сынок, это не самое сложное. Сложнее потом доказать, что ты попал!
(из юмористической сценки об играх во дворе в 80-е)

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

-8

Итак, для проверки, есть ли победитель, у нас есть метод checkWin(), который во-первых запускает поиск по циклам. Проверка в циклах ведется по горизонтали и вертикали. Какие условия необходимы, чтобы сообщить, что есть победитель? Для этого первый элемент горизонтали или вертикали должен быть непустым (т.е. не первоначальное состояние board) и он должен быть равен второму и третьему элементу горизонтали или вертикали (или все элементы по горизонтали или вертикали - крестики, или они же - все нолики). Если такое состояние находится - работа метода прерывается и возвращается true.
Если же в горизонталях или вертикалях не найдены "победные" варианты, проверяем диагонали. Тут точно так же: критерий того что победитель есть, - первые элементы (0,0) и (2,0) не пустые, и они равны остальным элементам соответствующим диагоналям. Если подобные комбинации есть - работа метода также прерывается и возвращается true. Если нет - возвращается false - на данном этапе победитель не выявлен, и игра продолжается.

Проверка на состоянии ничьи
isDraw() осуществляется, если на этапе не выявлен победитель. Циклично проверяются все элементы игрового поля board на пустоту. Если есть пустые элементы (board[i][j]==EMPTY), игру можно продолжить, ничьи нет, возвращаем false. Если же нет пустых элементов, но и победитель не выявлен, метод возвращает true, и провозглашается ничья.

Ход и смена игрока

-9

Итак, поскольку проще реализовать смену игрока, её и реализуем через метод switchPlayer(). Здесь всё проще пареной репы (которую не во всяком продуктовом магазине найдешь ))) ):

currentPlayer = (currentPlayer == PLAYER_X) ? PLAYER_O : PLAYER_X;

Можно через if...else, можно короткой записью: если текущий игрок PLAYER_X (поля заполняются крестиками), то при смене он будет PLAYER_O, (при ходе поля будут заполняться ноликами) иначе при смене он будет PLAYER_X(поля снова заполняются крестиками).

Теперь проверка хода игрока. Поскольку мы с консоли будем задавать координаты того поля, где поместим наш знак(об этом позже), то вполне возможно случайно (или намеренно) попасть в поле, где есть крестик или нолик. Поэтому и введена особая проверка хода игрока makeMove(int row, int col) - если board[row][col] не пустое поле, то return false, и игроку или компьютеру надо сделать ход в другую клетку. Иначе значение клетки заполняется значением знака текущего игрока board[row][col]=currentPlayer и return true.

Долгожданный startGame

А вот и долгожданный startGame().Вначале в этом методе производится ход игрока или компьютера. Если игрок - PLAYER_X (т.е. человек), то ввод строки и столбца заполняемой клетки осуществляется с клавиатуры в консоль методом scanner.nextInt(), если же PLAYER_О (компьютер) - клетка выбирается случайным образом (методом random.nextInt() выбираются значения числового массива numbers (0,1 или 2))



-10
-11

Введенные данные проверяются на корректность ввода (makeMove()), потом, если всё корректно, на наличие победителя после хода (checkWin). Если победитель не определен, проверяется, нет ли ничьи (isDraw). Если и ничьи нет, то производится смена игрока (switchPlayer()) и игра продолжается. Для того, чтобы не вылететь из игры раньше времени, в начале метода создана переменная gameRunning=true, и игра будет продолжаться в бесконечном цикле while(gameRunning). Если выявлен победитель или ничья, после соответствующих сообщений gameRunning=false, и игра прекращается.

Запускается startGame, как мы уже говорили выше, методом main при запуске программы.

Ну и вывод частички процесса игры (в консоли):

-12

Что дальше?



То, что мы с вами сейчас создали, доступно на
gitflic по ссылке. На android посредством Android Studio мы перенесем нашу программу в следующих статьях цикла (следите за публикациями). Отсюда на андроид возьмем смену игрока, поиск победителя, проверку на ничью.