Гид по технологиям

Игра «Память» на Python с Tkinter

6 min read Python Обновлено 06 Apr 2026
Игра «Память» на Python с Tkinter
Игра «Память» на Python с Tkinter

Неоновый розовый мозг на чёрном фоне

Игра «память» (matching game) — простой и увлекательный способ потренировать внимание, рабочую память и скорость реакции. Игрок открывает по две плитки подряд, пытаясь запомнить расположение символов и найти пары. Когда все пары найдены, игра завершается победой.

В этой инструкции вы найдёте готовый код на Python с описанием всех частей, примечания по локализации, идеи для улучшений и список тестов для приёмки.

Что понадобится

  • Python (версия 3.x). Убедитесь, что у вас установлен Python и настроено окружение.
  • Библиотека Tkinter для графического интерфейса. На большинстве установок Python Tkinter уже доступен. В исходном материале предлагается команда для установки:
pip install tkinter

Примечание: на некоторых системах Tkinter устанавливается как часть пакета Python (например, в Linux через пакетный менеджер). Если команда pip не сработает, установите Tkinter через системный менеджер пакетов вашей ОС.

  • Встроенный модуль random для перемешивания набора значков/слов.

Краткая структура программы

Основные части программы:

  • Инициализация окна Tkinter.
  • Подготовка списка пар (например, названия фруктов) и их перемешивание.
  • Создание кнопок-плиток и механики клика по плитке.
  • Логика проверки пары и подсчёта побед.
  • Функция сброса и меню с действиями «Reset Game» и «Exit Game».

Ниже — исходный код, взятый из примера. Сохранил все блоки кода без изменений, чтобы вы могли скопировать и запустить их напрямую.

from tkinter import *  
import random  
from tkinter import messagebox  
  
root = Tk()  
root.title('Memory Tile Game')  
root.geometry("760x550")

Далее объявляем глобальные переменные и формируем список пар. В примере используются 6 пар (12 кнопок).

global winner, matches  
winner = 0  
matches = ["apple","apple","banana","banana", "orange","orange", "blueberry","blueberry","mulberry","mulberry", "grapes","grapes"]  
random.shuffle(matches)  
my_frame = Frame(root)  
my_frame.pack(pady=10)  
count = 0  
answer_list = []  
answer_dict = {}

Функция reset очищает экран и возвращает кнопки в исходное состояние.

def reset():  
    my_label.config(text="")  
    button_list = [b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11]  
    for button in button_list:  
        button.config(text=" ", bg="SystemButtonFace", state="normal")

Функция win показывает сообщение о победе и подсвечивает все плитки в зелёный цвет.

def win():  
    my_label.config(text="Congratulations! You Win!")  
    button_list = [b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11]  
    for button in button_list:  
        button.config(bg="#90EE90")

Главная логика обработки клика по плитке находится в button_click. Она показывает текст на плитке, сохраняет выбор и проверяет, совпадает ли пара.

def button_click(b, number):  
    global count, answer_list, answer_dict, winner  
    if b["text"] == ' ' and count < 2:  
        b["text"] = matches[number]  
        answer_list.append(number)  
        answer_dict[b] = matches[number]  
        count += 1

Когда выбрано две плитки, выполняется проверка на совпадение. В случае совпадения — плитки блокируются и подсчитывается победа. Если не совпало — показывается окно с уведомлением и плитки скрываются снова.

    if len(answer_list) == 2:  
        if matches[answer_list[0]] == matches[answer_list[1]]:  
            my_label.config(text="It's a Match!")  
            for key in answer_dict:  
                key["state"] = "disabled"  
            count = 0  
            answer_list = []  
            answer_dict = {}  
            winner += 1  
            if winner == 6:  
                win()
        else:  
            count = 0  
            answer_list = []  
            messagebox.showinfo("Incorrect!", "Incorrect")  
            for key in answer_dict:  
                key["text"] = " "  
            my_label.config(text=" ")  
            answer_dict = {}

Далее создаются 12 кнопок и размещаются в сетке 3×4.

b0 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b0, 0), relief="groove")  
b1 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b1, 1), relief="groove")  
b2 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b2, 2), relief="groove")  
b3 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b3, 3), relief="groove")  
b4 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b4, 4), relief="groove")  
b5 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b5, 5), relief="groove")  
b6 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b6, 6), relief="groove")  
b7 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b7, 7), relief="groove")  
b8 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b8, 8), relief="groove")  
b9 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b9, 9), relief="groove")  
b10 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b10, 10), relief="groove")  
b11 = Button(my_frame, text=' ', font=("Helvetica", 20), height=4, width=8, command=lambda: button_click(b11, 11), relief="groove")
b0.grid(row=0, column=0)  
b1.grid(row=0, column=1)  
b2.grid(row=0, column=2)  
b3.grid(row=0, column=3)  
b4.grid(row=1, column=0)  
b5.grid(row=1, column=1)  
b6.grid(row=1, column=2)  
b7.grid(row=1, column=3)  
b8.grid(row=2, column=0)  
b9.grid(row=2, column=1)  
b10.grid(row=2, column=2)  
b11.grid(row=2, column=3)
my_label = Label(root, text="")  
my_label.pack(pady=20)  
  
my_menu = Menu(root)  
root.config(menu=my_menu)  
option_menu = Menu(my_menu, tearoff=False)  
my_menu.add_cascade(label="Options", menu=option_menu)  
option_menu.add_command(label="Reset Game", command=reset)  
option_menu.add_separator()  
option_menu.add_command(label="Exit Game", command=root.quit)
root.mainloop()

Если собрать всё вместе, у вас выйдет простая настольная версия игры «память» с графическим интерфейсом.

Выводы и поведение программы (скриншоты)

На запуске вы увидите 12 пустых кнопок и пункт меню Options. Нажатие Reset Game возвращает интерфейс в начальное состояние.

Вывод: начальное состояние игры с 12 пустыми кнопками

При совпадении двух плиток кнопки становятся disabled, а метка сообщает, что выбор правильный.

Вывод: правильная пара, кнопки отключены

При неправильном выборе появляется всплывающее окно с сообщением, и плитки скрываются.

Вывод: неправильная пара, сообщение об ошибке

Когда найдены все пары, все плитки окрашиваются в зелёный, и появляется сообщение о победе.

Вывод: все пары найдены, экран победы

Когда этот подход не подходит

  • Если вам нужна сложная графика, анимация или плавный рендер — Tkinter ограничен. Для насыщенной графики лучше Pygame, Kivy или движки на C++/C#.
  • На мобильных устройствах настольное приложение Tkinter неудобно. Для мобильных приложений используйте Kivy или веб-решения.
  • Если планируется сетевой режим или многопользовательская логика — потребуются дополнительные библиотеки и архитектура клиента/сервера.

Важно: Tkinter подходит для простых игр и учебных проектов. Не рассчитывайте на высокую производительность при сотнях объектов.

Альтернативные подходы

  • Pygame — если нужна кастомная графика и звук. Подходит для 2D-игр с анимацией.
  • Веб-версия на HTML/CSS/JavaScript — кроссплатформенная, работает в браузере и на мобильных устройствах.
  • Kivy — кроссплатформенная библиотека для создания UI, поддерживает мобильные платформы.

Выбор зависит от целевой платформы и требований к визуалу.

Идеи для улучшения (сниппеты и рекомендации)

  1. Добавить счёт и таймер. Поддерживает соревновательную механику: меньше времени = больше очков.
  • Идея: показывать таймер, который стартует при первом клике. По завершении — показать время и счёт.
  • Технически: использовать root.after для обновления таймера каждую секунду.

Примерная логика обновления таймера (псевдокод):

# Псевдокод, интегрируйте в основной код
seconds = 0
running = False

def start_timer():
    global running
    if not running:
        running = True
        update_timer()

def update_timer():
    global seconds, running
    if running:
        seconds += 1
        timer_label.config(text=str(seconds))
        root.after(1000, update_timer)
  1. Увеличивать сложность: больше пар, разные темы (иконки, изображения). При использовании изображений замените текст на PhotoImage.

  2. Анимация переворота плитки: в Tkinter это можно имитировать сменой цвета или постепенным показом символа.

  3. Сохранение результатов: записывать лучший рекорд в файл JSON или SQLite.

Мини-методология разработки (шаблон)

Шаги для быстрого создания и тестирования игры:

  1. Прототип: вызовите root, создайте несколько кнопок и убедитесь, что они реагируют на клики.
  2. Механика: реализуйте matches и button_click, проверьте логику совпадений вручную.
  3. UI: добавьте Label для сообщений и Menu для опций.
  4. Тесты: напишите чек-листы и пройдите их вручную.
  5. Улучшения: добавьте таймер, счёт, уровни.
  6. Рефакторинг: вынесите повторяющийся код в функции, документируйте.

Чек-листы по ролям

Разработчик:

  • Создать репозиторий и базовый проект.
  • Реализовать логику совпадений и сброса.
  • Обработать ошибки (например, доступ к несуществующим индексам).
  • Добавить комментарии и README.

Тестировщик:

  • Проверить поведение при клике быстрее, чем обновляется UI.
  • Убедиться, что после победы дальнейшие клики не ломают состояние.
  • Проверить пункт меню Reset Game несколько раз подряд.
  • Проверить работу на разных платформах (Windows, macOS, Linux).

Дизайнер / UX:

  • Проверить контраст текста/фона.
  • Настроить размеры кнопок под разные разрешения.
  • Предложить понятные и локализованные метки меню.

Критерии приёмки (тесты/acceptance)

  1. При запуске выводится 12 плиток, все пустые.
  2. При выборе двух одинаковых плиток они становятся disabled и подсвечиваются.
  3. При выборе двух разных плиток появляется окно с «Incorrect!» и плитки скрываются.
  4. После нахождения всех 6 пар появляется сообщение о победе и плитки окрашиваются в зелёный.
  5. Команда Reset Game полностью сбрасывает состояние для новой игры.
  6. Непредвиденные клики не вызывают исключений.

Возможные ошибки и пути диагностики

  • Если программа не запускается и вы получаете ошибки, проверьте версию Python и наличие Tkinter. В Linux/WSL/серверных окружениях GUI может быть недоступен.
  • Если изображения (PhotoImage) не отображаются, убедитесь, что объект сохраняется в переменной и не удаляется сборщиком мусора.

Важно: всегда проверяйте трассировку ошибок (traceback) — она подскажет строку и причину.

Сравнение: Tkinter vs Pygame (коротко)

  • Tkinter: простая разметка, стандартный набор виджетов, удобен для прототипов и простых игр.
  • Pygame: больше контроля над рендерингом, звук и анимация, лучше для динамичных 2D-игр.

Выбор определяется требованиями к визуальной части и платформам.

1‑строчная глоссарий

  • Tkinter — стандартная библиотека Python для создания простых GUI.
  • random.shuffle — функция для перемешивания списка на месте.
  • root.after — метод Tkinter для отложенного выполнения функции.

Идеи для локализации и UX

  • Локализуйте метки меню и сообщения (Options → Параметры, Reset Game → Начать заново, Incorrect → Неправильно).
  • Для обучения детей используйте картинки вместо текста на плитках.
  • Для пользователей с нарушениями зрения увеличьте размер шрифта и добавьте голосовые подсказки.

Важно: в коде примера используются английские метки меню. При необходимости можно заменить label=”Options” на label=”Параметры” и т. п., но сохраняйте совместимость с ожидаемой логикой программы.

Заключение

Игра «память» — отличный учебный проект для знакомства с событиями, виджетами и простыми структурами данных в Python. Пример, приведённый выше, даёт работоспособную базу, которую можно расширять: добавить таймер, уровни сложности, сохранение рекордов и адаптацию под мобильные платформы.

Важно: начинайте с простого прототипа, затем итеративно добавляйте улучшения и тестируйте каждое изменение.

Краткое резюме результатов:

  • Рабочая игра на Tkinter с 12 плитками и 6 парами.
  • Полный код и объяснения всех функций приведены выше.
  • Включены идеи для улучшений, чек-листы и критерии приёмки.

Спасибо, что прочитали — удачи в реализации и расширении вашей версии игры «память» на Python!

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Блокировка доступа приложений к интернету — Windows 11
Безопасность

Блокировка доступа приложений к интернету — Windows 11

Habitify: старт и контроль привычек
Продуктивность

Habitify: старт и контроль привычек

Маршрутизация в React с React Router v6
Frontend

Маршрутизация в React с React Router v6

Можно ли использовать AirTag с Android?
Гаджеты

Можно ли использовать AirTag с Android?

API‑запросы в VS Code с REST Client
Разработка

API‑запросы в VS Code с REST Client

Как перенести музыку из Spotify в Apple Music
Музыка

Как перенести музыку из Spotify в Apple Music