Как сделать крестики нолики на python
Как-то раз я смотрел лекции университета Беркли по структурам данных (так и не досмотрел со всеми этими блогами), и нашло на меня вдохновение мáлое — подумал «дай думаю напишу крестики-нолики». Лектор как раз про игровые деревья рассказывал, а примером выбрал крестики-нолики, tic-tac-toe по-ихнему — на доске показывал. Еще он пару алгоритмов привел: старый добрый минимакс и α-β-поиск. Но до альфа-бета-поиска у меня руки не дошли, так что я написал минимакс-процедуру, которая говорит кто победит в партии.
Почему я об этом пишу? Оно того стоит, я думаю. Уж больно красивый получился код. С моей колокольни, конечно; но после того как я написал этот код, я для себя отметил на будущее, что в общем, понимаю причину по которой в MIT выбрали питон первым языком — он достаточно хорош для этого. И по-моему, этот код послужит отличным доказательством тому факту, что для многих, очень многих не сильно сложных функциональных программ питон — лучший выбор в плане понятности, нежели Scheme.
Приведенный выше код достаточно прост и не нуждается в комментариях. Но это еще не все. Без примеров использования он будет не полон. Они тоже весьма неплохи, на мой вкус.
Примечательно, что почти в тот же день на хабре выложили статью по игровым деревьям с крестиками-ноликами в примерах.
# Tic tac toe — крестики-нолики по шагам (статическая реализация интерфейса)
В данном примере проекта приводится игра крестики-нолики с четырьмя кнопками. Пример использует упрощенную модель 2х2, которая помогает понять какие шаги необходимо пройти для реализации полной версии программы.
Задание:
Названия переменных должны быть корректными:
- существующие английские слова;
- имя переменной всегда начинается с имени существительного отражающее суть/смысл переменной;
- соединение двух и/или более слов через нижнее подчеркивание.
Создать окно с названием версии и виджеты Button() .
- реализовать отображение четырех кнопок.
Рекомендации:
В названиях кнопок можно использовать цифры обозначающие место положение соответствующей кнопки: "button_11", где первая единица означает столбик, а вторая — строка.
Для задания размеров кнопки лучше использовать параметры grid() : ipadx= и ipady= , т.к. данный способ не вызывает ошибки при подключенной библиотеки ttk.
# 2. Реализация нажатия кнопок
Добавляем функции нажатия кнопок и отображение "Х".
Задание:
Изменить версию в заголовке окна.
Названия функций должны быть корректными:
- существующие английские слова;
- название начинается всегда с глагола отражающие суть/смысл функции;
- соединение двух и/или более слов через нижнее подчеркивание: "кнопка_нажата".
Создать четыре функции нажатия кнопок для отображения значка "Х".
Рекомендации:
- Тело созданных функций желательно делать максимально похожими, это необходимо для понимания универсальности функций.
# 3. Смена ввода "Х" на "О"
Задание:
- Изменить версию в заголовке окна.
- Добавить глобальную переменную для отслеживания очереди хода игрока.
- Изменить тело функций, учитывая очередность:
- при последующем нажатии кнопки происходило чередование выводимых символов "Х" и "О".
- на этом шаге символы в кнопках могут заменять друг друга.
Рекомендации:
- Тело созданных функций желательно делать максимально похожими.
- Для отслеживания состояния переключения можно воспользоваться функцией print() .
# 4. Проверка ввода
Задание:
- Изменить версию в заголовке окна.
- Изменить тело функций, добавив проверку на пустоту:
- при последующем нажатии кнопки, если в кнопке ещё не задан символ, то происходило вывод символа "Х" или "О", в зависимости от очередности.
- на этом шаге символы, выведенные в кнопках, не могут заменять друг друга.
Рекомендации:
- Тело созданных функций желательно делать максимально похожими.
- Для отслеживания состояния переключения можно воспользоваться функцией print() .
- Создать дополнительные функции и переменные не требуется.
# 5. Кнопка "новая игра"
Для дальнейшего удобства проверки работы программы добавим кнопку "новая игра".
Задание:
- Изменить версию в заголовке окна.
- Добавим кнопку "NEW GAME".
- Напишите функцию создания новой игры, которая убирает все символы с кнопок.
# 6. Составление условий победы
Для начала реализации проверки победителя составим логические выражения для проверки победы игрока символом "Х".
Задание:
- Изменить версию в заголовке окна.
- Напишите функцию проверки победителя:
- вызов функции происходит после хода каждого игрока;
- используя функцию print() выводите все состояния победных комбинаций: горизонтали, вертикали и диагонали;
- проверьте правильность работы всех условий.
Рекомендации:
Для удобства в консоли выводите текст вида: "Row 1: True" или "Diagonal 12-21: True" и т.п.
Не забывайте использовать f""-строку.
# 7. Проверка победы "Х"
В этом шаге добавляем проверку условия и если выпала выигрышная комбинация, то в консоль выводиться: "X — won!"
Задание:
- Изменить версию в заголовке окна.
- Измените функцию проверки победителя:
- создайте одну "условную" конструкцию if;
- добавьте логические выражения проверки "Х" в условие, соединив логические выражения;
- при появлении выигрышной комбинации в консоль выводиться "X — won!"
- Проверьте правильность работы нескольких комбинаций.
Рекомендации:
- Лучше проверить все возможные выигрышные комбинации для исключения ошибки.
# 8. Проверка победы "ХО"
В этом шаге добавляем проверку условия и если выпала выигрышная комбинация, то в консоль выводиться: "X — won!" или "О — won!"
Задание:
- Изменить версию в заголовке окна.
- Измените функцию проверки победителя:
- изменить условие при котором будет проверяться соответствие выигрышных комбинаций "Х" или "О";
- при появлении выигрышной комбинации в консоль выводится "X — won!" или "О — won!" в соответствии с игровым полем.
- Проверьте правильность работы нескольких комбинаций.
Рекомендации:
- Лучше проверить все возможные выигрышные комбинации для исключения ошибки для "Х" и "О".
# 9. Конец игры
При выигрыше одним из игроков реализуем блокировку кнопок. При создании новой игры блокировка должна отключаться.
Крестики-нолики на Python
Статьи
Введение
В статье напишем игру “Крестики-нолики” на Python.
Крестики-нолики — логическая игра между двумя соперниками на квадратном поле 3×3 клетки, или бо́льшего размера. Один из игроков играет за “крестики”, а второй за “нолики”.
Рисуем игровое поле
Начнём с того, что нарисуем само игровое поле для игры.
Для начала сгенерируем список с числами от одного, до 9:
Создадим функцию draw_board(), аргументом которой будет board:
В функции выводим первую строку состоящую из 13 символов “тире”, после чего, в цикле прорисовываем остальные края поля.
При вызове функции будет следующий вывод:
Игровое поле “Крестики-нолики”
Принимаем ввод пользователя
Теперь нам нужно создать функцию для приёма ввода.
Создадим функцию take_input() с аргументом player_token:
Внутри функции сначала задаётся переменная valid, которая равняется False, после чего идёт цикл while, который не закончится, пока valid не примет значение True. В цикле производится ввод пользователем определённой клетки, в которую будет ставиться крестик, либо нолик. Если же пользователь ввёл, а какой-либо другой символ, выведется ошибка.
Далее в условии проверяется, занята ли введённая клетка. Если клетка занята, то выведется соответствующая ошибка, если же введено число не в диапазоне от 1, до 10 – будет так же выведено соответствующее сообщение.
Проверка, выиграл ли игрок
Создадим функцию check_win(), в которой будем проверять, выиграл ли игрок. Аргументом функции будет board:
Внутри функции создаётся кортеж win_coord, в котором хранятся победные комбинации. В цикле производится проверка на победу игрока, если он побеждает, то выводится сообщение о победе, если же нет – возвращается False, и игра продолжается.
Создание главной функции
Теперь создадим функцию main() с аргументом board:
Внутри функции, после обозначения переменных, создаётся цикл, который закончится после победы одного из игроков, или ничьей. Внутри цикла проводится проверка, какой игрок сходил, после чего вызывается функция take_input() с соответствующим символом игрока. Далее идёт проверка, какой игрок выиграл, или вышла ничья.
Итоговый код игры “Крестики-нолики” на Python
Заключение
В статье мы с Вами написали игру “Крестики-нолики” на Python! Надеюсь Вам понравилась статья, желаю удачи и успехов!
Играем в Крестики-Нолики с Python и GTK
Новый блог GTK+ порадовал статьёй для начинающих и я решил попробовать что-то более простое, чем C++/C. Python оказался как нельзя кстати. Объём кода на Python для работы с GTK значительно меньше чем на C++, что не может не радовать.
PyGTK
PyGTK — биндинг библиотеки GTK для языка Python, PyGTK используется во многих открытых программах (например IM Gajim). Библиотека может быть очень интересна для Python программистов, поскольку проста в обращении и полностью скрывает реализацию GTK.
Под катом пример приложения.
Пример приложения
Для изучения PyGTK я решил написать простой пример — игру Крестики-Нолики.
Окно игры будет максимально простым — квадрат из кнопок 3×3.
Окно игры: 
Итак приступим к реализации. В программе есть пара классов: XO_Field и XO_Win, первый хранит информацию о поле, второй создаёт GUI для приложения и обрабатывает события.
Я использовал для примера модуль pygtk, установленный из пакетного менеджера в Ubuntu, на других системах стоит воспользоваться пакетами или python easy-install, а для Windows есть инсталлятор.
Используем модуль pygtk версии 2.0 или старше:
Создадим простое окно, по закрытию которого будем прерывать и цикл событий GTK. Функция destroy будет приведена чуть позже.
Для окна воспользуемся вертикальной компоновкой из трёх строк с горизонтальной.
Так кнопки будут расположены как раз в виде квадрата 3×3. Для каждой из кнопок добавляется обработчик события «clicked», синтаксис добавления очень похож на сигналы и слоты в Qt.
Функция, создающая кнопку:
Запуск основного цикла событий GTK и уничтожение окна:
По нажатию на кнопки происходит установка знака в указанную позицию и переход хода к следующему игроку, если ещё не определён победитель. Если игра завершена, результат выводится в заголовок окна.
Сама игра в Крестики-Нолики и её реализация довольно тривиальна, ссылка на исходный код приведена ниже. Больший интерес представляет сам цикл работы приложения Python в связке с GTK, так например сборщик мусора при сборке ссылок на объекты GTK также вызывает деструкторы для них, поскольку элементы UI содержат много ссылок на ресурсы.