Всем привет, сегодня, с помощью библиотеки Kivy напишем игру Крестики-Нолики за 15 минут!
Kivy - это открытая Python библиотека для быстрой разработки приложений. У нее много преимуществ, например, кросс-платформенность, открытость а также использование GPU для ускорения отрисовки графических интерфейсов.
Для начала работы нам потребуется библиотека kivy. Установить ее можно с помощью команды (Windows):
pip install kivy
Либо с помощью команды (Linux, Python 3):
pip3 install kivy
Импортируем необходимые нам элементы:
С помощью Config и функции set зададим параметры нашего окна:
Мы установили размер окна 300х300 и указали что окно нельзя перерастягивать.
Нам нужно, чтобы при каждом новом ходе крестик сменялся ноликом и наоборот. Для этого создадим класс нашего приложения, и назовем его MainApp. Оно должно наследоваться от класса kivy – App. Внутри класса создадим переменную self.switch, и определим ее в функции __init__:
Строчка с super() нужна для того, чтобы инициализировать родительский класс App.
Внутри класса мы также объявим 3 функции: tic_tac_toe, restart и build:
Поговорим подробнее о каждой из них.
tic_tac_toe: функция, которая будет исполнять всю логику нашего приложения, с английского tic tac как раз и означает крестики-нолики
restart: функция, которую мы будем вызывать для того, чтобы перезапустить игру, по сути сбросив все значения кнопок и переменных до начального состояния
build: важная функция, она определена в самом App, но ее поведение мы должны "перегрузить"
Начнем как раз с функции build.
self.title это название нашего окна, далее создадим объект BoxLayout, он будет являться своеобразным контейнером для всех наших кнопок. Также создадим переменную GridLayout, и укажем число колонок = 3. На рисунке ниже ее область будет показана красным цветом. После того, как отрисуем область сетки, добавим внизу кнопочку Restart (показана синим цветом).
self.buttons = []
После этого, в цикле мы добавим в лист 9 объектов класса Button. Каждый такой объект имеет цвет, размер шрифта и другие переменные. При нажатии на такую кнопку вызывается метод tic_tac_toe, о котором мы поговорим чуть позднее. В конце цикла не забываем добавить полученные в ходе тела цикла кнопки в наш лист self.buttons, кроме того, добавляем новый виджет в grid:
Также добавим виджет для кнопки Restart:
Весь код функции build целиком:
Поскольку мы добавили кнопку Restart, давайте поговорим об ее функционале. Добавим в функцию restart следующий код:
Переменная switch = True показывает, что ход снова возвращается к крестикам, как и было указано в начале игры. Далее мы проходимся в цикле по всем кнопкам, возвращая им цвет по умолчанию и стирая текст. Модификатор disabled показывает, что теперь вы снова можете нажать на кнопку.
Но вернемся к функции tic_tac_toe. Для начала укажем снова глобальную переменную switch. Как вы помните, она переключается в обратное положение каждый раз после нажатия кнопки, чем символизирует переключение хода на другого игрока. В этой функции аргумент arg будет как раз являться нашим конкретным button.
При нажатии на кнопку, согласно с логикой приложения, мы должны выключить возможность нажать на нее второй раз. Для этого необходимо указать arg.disabled = True.
Теперь проверим в каком положении стоит наш self.switch, и в зависимости от этого, определим переменную arg.text крестиком либо ноликом:
Фактически, выражение 'X' if self.switch else 'O' означает 'X' в случае если self.switch = True и 'O' в случае если self.switch = False.
После этого, разумеется, мы должны переключить ход:
self.switch = not self.switch
Далее начнется самое сложное. Нам необходимо задать все возможные координаты кнопок, которые дадут выигрыш:
coordinate = (
(0,1,2),(3,4,5),(6,7,8), # X
(0,3,6),(1,4,7),(2,5,8), # Y
(0,4,8),(2,4,6), # D
)
Также зададим и возможные вектора самих нажатых кнопок (в них будет храниться буквы 'X' либо 'O'). Легче всего это сделать, написав короткую лямбда-функцию, которая будет возвращать список букв для каждого набора координат:
vector = lambda item: [self.buttons[x].text for x in item]
Такой объект является анонимной функцией, при выполнении которой возвратится список в котором будут храниться буквы. Если в таком списке все 3 буквы одинаковые, это означает выигрыш!
Определим переменную win = False, а также цвет кнопок в результате выигрыша:
win = False
color = [0,1,0,1] # Зеленый
Теперь напишем цикл, который будет определять победную комбинацию нажатых кнопок. В переменной coordinate есть 8 комбинаций с победными сочетаниями кнопок. Пройдемся по ним в цикле:
Если в таком векторе функция count посчитает 3 раза буквы 'X' либо 'O', значит игрок победил, в таком случае окрашиваем победную комбинацию кнопок в зеленый цвет.
Также необходимо залочить все кнопки в случае победы:
Внимательный читатель мог заметить, что переменная win в принципе и не нужна, а последний цикл можно переместить в цикл после перекрашивания цвета кнопок в зеленый. Полный код функции tic_tac_toe после рефакторинга:
Весь код целиком — https://pastebin.com/VywZQB2g.
Понравилась статья? Не забудь подписаться и оставить свое мнение в комментариях, обязательно прочту и отвечу.
Читайте также: