Skip to content
 
 

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 

Repository files navigation

🎮 Гра "3 в ряд" (STM32 Hardware Engine)

📌 Опис проєкту

Цей проєкт — мікроконтролерна реалізація логічної гри "3 в ряд" (Match-3) для плати серії STM32F0. Уся логіка гри, математика, анімація гравітації та збереження прогресу виконуються безпосередньо на апаратному рівні (MCU), а зв'язок з комп'ютером (графічним клієнтом) відбувається через UART-протокол.


💻 Вимоги до системи та середовище розробки

PC Client (Клієнт)

  • ОС: Windows 10 / Windows 11 (64-bit).
  • Середовище: Visual Studio Code / PyCharm.
  • Стек: Python 3.11+ (рекомендовано 3.12), pygame-ce latest (графіка), pyserial 3.5+ (зв'язок).

Hardware Server (Мікроконтролер)

  • Плата: STM32F0Discovery (або аналогічна, напр. STM32F103).
  • Мікроконтролер: STM32F051R8 (ARM Cortex-M0).
  • IDE: STM32CubeIDE.
  • Компілятор: GCC for ARM Embedded Processors (arm-none-eabi).

⚙️ Технічна Архітектура

  • Шаблон: Клієнт-Сервер (ПК — "Режисер/Монітор", STM32 — "Фізичний рушій").
  • Апаратна логіка: Всі прорахунки збігів (Match-3), гравітації, генерації поля та перевірки на глухий кут (Deadlock) виконуються на STM32.
  • Анімації: Покрокова анімація падіння (Гравітація) транслюється асинхронно зі швидкістю 300 мс на крок для забезпечення плавного відображення на стороні клієнта (Python).

🧩 Механіка та правила гри

  • Розмір поля: Стандартний розмір поля становить 8 на 8 клітинок (64 кульки).
  • Кольори: У грі використовується 6 кольорів.

Генерація поля

Поява об'єктів на новому полі відбувається випадково. Автоматична генерація готових ліній при старті заборонена. При генерації виконується перевірка: $$A_{xy(1)} = A_{xy(2)} = x$$ Де $x$ — це колір нової кульки, а $A$ — кольори двох попередніх. Якщо утворюється лінія з 3-х однакових кульок, алгоритм підбирає інший колір.

Нарахування балів

Бали нараховуються за спалювання ліній однакових кульок. Мінімальна згоряєма кількість — 3 кульки.

  • 3 кульки: 30 балів (Базовий збіг)
  • 4 кульки: 60 балів (Бонус х2 за складність)
  • 5 і більше кульок: 100 балів (Супер-бонус)

💾 Енергонезалежна пам'ять (NVM Flash)

Проєкт використовує Flash-пам'ять мікроконтролера (адреса 0x0800FC00) для збереження ігрового прогресу без зовнішніх SD-карт.

  • Підтримка слотів: Реалізовано збереження у 3 незалежні слоти (0, 1, 2) в межах однієї сторінки пам'яті (1 КБ).
  • Збереження даних: У кожен слот записується: "Магічне число" (валідація), Рахунок, Ім'я гравця (до 15 символів) та поточний стан поля (64 байти).
  • Захист: Функція Load_Game автоматично перевіряє цілісність слота перед завантаженням.

📡 Протокол обміну (Binary UART Protocol)

Зв'язок здійснюється через UART (BaudRate: 38400, 8N1). Обмін даними відбувається бінарними пакетами фіксованої довжини — 6 байт. Таймаут прийому — 10 мс.

📦 Структура пакету

Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5
CMD ADDR_H ADDR_L DATA_H DATA_L CRC-8
Команда Рядок 1 / Чанк / Слот Стовпчик 1 / Дані Рядок 2 / Колір / Дані Стовпчик 2 / Статус / Дані Checksum

🔐 Валідація та CRC-8

Контрольна сума розраховується за алгоритмом CRC-8 (Поліном: 0x07, Init: 0x00). Якщо CRC від клієнта не збігається, STM32 ігнорує команду і повертає діагностичний пакет: EE [Calc_CRC] [RX_CRC] EE EE [CRC].

📋 Таблиця команд

HEX Команда Напрямок Опис дії та формат даних
0x10 NEW GAME PC -> MCU Ініціалізує нове поле. Обнуляє рахунок.
Відповідь: [10 00 00 00 AA CRC] + дамп всього поля через пакети 0x16.
0x11 SWAP PC -> MCU Запит на хід гравця. Байти 1-4 містять координати: r1, c1, r2, c2.
Відповідь (Byte 4):
AA — Успіх (запускається покроковий каскад).
EE — Помилка (немає лінії 3-в-ряд).
DD — Deadlock (ходів більше немає).
0x12 FINISH PC→MCU Завершити гру, записати у лідерборд. Відповідь: AA=потрапив у топ-5, BB=ні
0x14 GET CELL PC -> MCU Запит кольору конкретної клітинки. Байти 1-2 містять r, c.
Відповідь: У Байті 3 повертається ID кольору. Байт 4 містить статус AA або EE.
0x15 GET SCORE PC -> MCU Запит поточного рахунку.
Відповідь: Рахунок (uint32_t) розбивається на 4 байти і передається у Байтах 1, 2, 3, 4.
0x16 UPDATE CELL MCU -> PC Асинхронна команда! Плата сама надсилає цей пакет під час падіння кубиків. Байти 1-2: r, c. Байт 3: Новий колір. Байт 4: AA.
0x20 SET NAME PC -> MCU Передача імені гравця на плату по 3 символи. ADDR_H = номер чанка (0-5). Байти 2,3,4 = символи ASCII.
0x30 SAVE GAME PC -> MCU Зберегти поточну гру у Flash-пам'ять. ADDR_H = номер слота (0, 1 або 2).
Відповідь: [30 <slot> 00 00 AA CRC]
0x31 LOAD GAME PC -> MCU Завантажити гру. ADDR_H = номер слота (0, 1 або 2).
Відповідь: [31 <slot> 00 00 AA CRC]. Після цього плата відправляє ім'я (0x32), рахунок (0x15) та дамп поля (0x16). Якщо слот порожній — статус EE.
0x32 GET NAME MCU -> PC Відправка імені гравця з плати на ПК (відбувається автоматично при завантаженні 0x31). Передається чанками по 3 символи.
0x40 GET LEADERS PC -> MCU Отримання топ-5 гравців з Flash-пам'яті (Відповідь серією пакетів 0x41,0x43,0x44,0x45,0x46 (ім'я) + 0x42 (score)

🏆 Система лідерборду

  • Рекорди зберігаються виключно у Flash-пам'яті мікроконтролера — не залежать від наявності комп'ютера.
  • При підключенні до нової плати клієнт автоматично завантажує актуальні рекорди.
  • При виході з гри через MENU MCU виконує Update_Leaderboard() → Flash Erase → Flash Write (~20 мс).
  • Клієнт чекає підтвердження запису перед відображенням оновленої таблиці.

🔧 Відомі обмеження

  • Максимальний score: 16 777 215 (3 байти у протоколі 0x42).
  • Максимальна довжина імені: 15 символів (ASCII).
  • Підтримка ОС клієнта: Windows 10/11 (через COM-порти).
  • Baudrate фіксований: 38400 (налаштовується в обох частинах).

🚀 Як скомпілювати та прошити проєкт (Мікроконтролер)

  1. Відкрийте проєкт: Запустіть STM32CubeIDE та імпортуйте папку з проєктом.
  2. Перевірте архітектуру: Переконайтеся, що модулі підключені правильно (main.c для UART, game.c для логіки, save.c для роботи з Flash-пам'яттю).
  3. Компіляція (Build): Натисніть іконку молотка (Build) або виконайте make -j16 all. Дочекайтеся повідомлення 0 errors.
  4. Прошивка (Flash): Підключіть плату через USB-кабель (ST-LINK) та натисніть кнопку Run (зелений трикутник). Плата готова до роботи.

🖥 Як налаштувати та запустити клієнтську частину (Комп'ютер)

1. Встановлення залежностей

Для роботи графічного інтерфейсу та зчитування даних з USB/UART порту потрібен Python. Відкрийте термінал (cmd або PowerShell) та встановіть потрібні бібліотеки:

pip install pygame pyserial
  1. Запустіть .game.exe

⚠️ Якщо Windows показує «Захист SmartScreen» — натисніть Додаткові відомості → Все одно виконати.

  1. Кнопками < / > виберіть COM-порт плати (помічений [BOARD DETECTED])
  2. Натисніть CONNECT
  3. Клієнт автоматично завантажить лідерборд з Flash MCU

📜 Ліцензія

MIT License. Вільне використання з посиланням на автора.


Розроблено як навчальний проєкт · STM32F051R8 + Python/pygame

About

Hardware-accelerated Match-3 game. The STM32 microcontroller handles game logic, gravity, and non-volatile memory saving (Wear Leveling), while a Python/Pygame client provides the GUI. Communication via double-buffered UART protocol.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages