🧨 Minesweeper – un joc clasic de logică, reinventat pentru platforme embedded!
🧠 Scopul proiectului: Jucătorul explorează o matrice de celule, evitând bombele 💣 și marcându-le corect cu steaguri 🚩. Am pornit de la ideea jocului original de pe PC și l-am adaptat pe un sistem embedded, pentru a-l face mai interactiv. Este un joc care antrenează logica și atenția, fiind în același timp o demonstrație practică a integrării între hardware și software.
🎮 Implementare joc Minesweeper pe un LCD grafic.
Placa de dezvoltare utilizată este compatibilă cu Arduino UNO R3 și controlează un ecran LCD TFT ST7735S pentru afișarea grafică a jocului. Navigarea în matricea 8×8 se face cu ajutorul joystick-ului analogic, iar cele 2 butoane permit plasarea steagurilor, opțiunea de selecție a numelui și opțiunea de a pune pe pauza/a ieși din joc. Buzzer-ul oferă feedback auditiv în cazul declanșării unei bombe sau a terminarii jocului. Logica jocului este implementată în software pe Arduino, care actualizează afișajul și răspunde în timp real la interacțiunile jucătorului.
🧩 Bill of Materials
Componenta | Link achiziție | Cantitate | Preț |
---|---|---|---|
Buton Alb | Buton | 2 | 1,99 lei |
Buton Albastru | Buton | 2 | 1,99 lei |
Joystick analogic | Joystick | 1 | 4,96 lei |
LCD, 1.8”, 128×160 TFT, SPI Serial | Display | 1 | 54,99 lei |
Arduino UNO R3 și cablu 50cm | Placă de dezvoltare | 1 | 39,37 lei |
Buzzer Pasiv 5V | Buzzer | 1 | 1,40 lei |
Fire rigide | Set fire rigide | 1 | 12,49 lei |
Fire tată-tată | Set fire tată-tată | 4 | 2,85 lei |
Breadboard HQ (400 Points) | Breadboard | 1 | 4,56 lei |
Cost total componente: 137,13 lei |
📐 Schema circuit
🔌 Conexiuni pini
Arduino Pin | Tip | Conectat la | Note |
---|---|---|---|
D10 | Digital | LCD CS | Chip-Select SPI |
D9 | Digital | LCD RST | Reset display |
D8 | Digital | LCD RS/DC | Data/Command select |
D11 | Digital (MOSI) | LCD SDA | SPI MOSI |
D13 | Digital (SCK) | LCD SCL | SPI Clock |
5V | Power | LCD VCC, Joystick VCC (+) | +5 V alimentare |
GND | Power | LCD GND , Joystick GND (–), buzzer “–” | Masă comună |
A0 | Analog | Joystick VRx | X-axis voltage |
A1 | Analog | Joystick VRy | Y-axis voltage |
D2 | Digital | Joystick SW | Switch intern joystick → când apeși conectează D2 la GND; se folosește `INPUT_PULLUP` |
D4 | Digital | Buton 1 | Buton la +5 V, rezistor extern de pull-down (~10 kΩ) la GND |
D6 | Digital | Buton 2 | Buton la +5 V, rezistor extern de pull-down (~10 kΩ) la GND |
D3 | Digital / PWM | Buzzer | Buzzer pasiv 5 V, minus la GND; poate fi modulat cu PWM |
🕹️ Configurația finală realizată fizic
Planificarea etapelor:
ID | Activitate | Descriere |
---|---|---|
A | Specificare cerințe | Stabilirea cerințelor hardware/software, interfață cu joystick, afișaj TFT, butoane, buzzer |
B | Design arhitectură | Împărțirea codului pe module: input (joystick/butoane), game loop, generare hartă, afișare grafică, sunet |
C | Implementare module de bază | Scrierea funcțiilor de citire joystick, debounce, tone buzzer |
D | Generare hartă și logică de joc | Algoritmi pentru plasarea bombardelor, flood-fill, verificare câștig/pierdere |
E | Grafică și UI | Funcții drawGrid(), drawHeader(), ecran de selecție nume, splash-screen, elemente decorative (bombe, steaguri, lopate) |
F | Testare și optimizare | Măsurarea timpilor de răspuns și optimizarea redraw-ului |
G | Documentație și prezentare | Redactarea README, diagrame, grafice Gantt, concluzii |
Relații de dependență:
Proiectul a fost dezvoltat în mediul Arduino IDE, utilizând limbajul C/C++. Codul a fost încărcat pe placa Arduino UNO R3 și testat pe hardware real. Pentru afișarea grafică pe LCD-ul TFT ST7735S, au fost utilizate următoarele biblioteci:
Jocul rulează pe o matrice 8×8 în care fiecare celulă stochează starea proprie: bombă, descoperită, steag sau număr de vecini cu bombe.
Pozițiile bombelor sunt generate aleator, iar valorile vecinilor sunt calculate automat. Utilizatorul se poate deplasa prin matrice cu joystick-ul analogic și poate interacționa prin butoane:
Funcții implementate:
Pentru funcțiile de draw am utilizat diverse apeluri grafice printre care:
tft.fillRoundRect(x, y, w, h, r, color)
tft.fillTriangle(x0, y0, x1, y1, x2, y2, color)
tft.drawTriangle(x0, y0, x1, y1, x2, y2, color)
Funcțiile grafice utilizate în cod:
Funcție | Ce face |
---|---|
fillScreen | curăță tot ecranul într-o culoare |
fillRect | umple un dreptunghi |
drawRect | contur dreptunghi |
fillCircle | cerc solid |
drawCircle | contur cerc |
drawFastHLine | linie orizontală |
drawLine | linie oblică |
fillTriangle | triunghi solid |
drawTriangle | contur triunghi |
fillRoundRect | dreptunghi cu colțuri rotunjite solid |
setCursor | poziționează „cursorul” pentru text |
setTextSize | setează mărimea fontului |
setTextColor | setează culoarea textului |
Logica din funcția de loop() constă într-un switch care jongleaza cu stările posibile:
enum GameState {STATE_SPLASH, STATE_SETTINGS, STATE_ENTER_NAME, STATE_PLAY, STATE_CONFIRM_QUIT};
Laboratoare folosite | Funcționalitate | Cod |
---|---|---|
GPIO | citire / scriere de pini digitali | configurePinsWithRegisters() folosind regiștrii |
UART | comunicație serială | Nu este explicit în cod, dar am folosit pentru afișajul în consola pentru debug |
Timere & PWM | generare ton și temporizări | startTone(uint16_t freq) si stopTone() folosind Timer0 pe 8 biti pentru PWM |
ADC | conversie analog‐digitală | fastAnalogReadA0() și fastAnalogReadA1() pentru citirea poziției joystick-ului folosind regiștrii |
SPI | interfațare display TFT | tft.initR(INITR_BLACKTAB) + toate comenzile tft.xxx folosesc SPI pentru comunicare cu ecranul ST7735 |
Scurt demo 🎥 de prezentare poate fi gasit pe linkul de YouTube
Proiectul Minesweeper realizat pe Arduino a fost o experiență foarte reușită și satisfăcătoare. A reușit să aducă laolaltă funcționalitatea completă a jocului, grafică interactivă și control prin joystick și butoane, toate integrate pe un ecran TFT. Faptul că totul rulează în timp real m-a ajutat să înțeleg mai bine ce înseamnă să optimizezi interfața și logica jocului pentru resurse limitate.
Mi-a plăcut în mod special partea de redare continuă a ecranului, care mi-a amintit de temele de la cursul de grafică. M-am bucurat să regăsesc acolo concepte precum bucla de render, actualizarea doar a zonelor modificate și controlul precis asupra afișajului. A fost interesant să văd cum acele noțiuni se aplică și într-un context diferit, pe un microcontroler, cu constrângeri reale de memorie și procesare.
Pe lângă partea grafică, m-a ajutat mult și pe partea de hardware: am lucrat cu pini GPIO, citirea joystick-ului prin ADC, comunicația SPI cu display-ul. Toate astea m-au făcut să înțeleg mai bine ce înseamnă să îmbini partea software cu cea hardware într-un mod funcțional și coerent.
În final, proiectul ăsta mi-a dat un plus de încredere și clar mi-a trezit interesul pentru proiecte embedded mai complexe.
Arhivă cu tot conținutul proiectului.
🗓️03.05.2025 – 📄 Am început redactarea documentației proiectului: am completat secțiunile Introducere și Descriere generală și am încărcat schema bloc în pagina wiki, completând lista de componente pe care le voi utiliza și ideea de start a design-ului software.
🗓️ 05.05.2025 – 📄 Am cumpărat piesele menționate în lista de componente hardware.
🗓️ 10.05.2025 – 📄 Componentele au fost livrate și am început montajul hardware.
🗓️11.05.2025 – 📄 Am finalizat implementarea hardware a proiectului. Am realizat schema circuitului pe breadboard și am desenat schema electrică completă, documentând conexiunile între toate componentele utilizate.
🗓️ 18.05.2025 – 📄 Am realizat implementarea software-ului.
🗓️ 20.05.2025 – 📄 Am terminat ultimele retușuri, am finalizat pagina de ocw, am creat repo-ul de GitHub și am încărcat un demo intuitiv pe YouTube
Hardware Related
Software Related