Table of Contents

Minesweeper

Autor: Alexe Alexandra Alexe

Introducere

Proiectul constă în realizarea jocului Minesweeper, controlat prin butoane cu afișaj pe un ecran LCD. Se va calcula si se va afisa score-ul in fiecare moment, iar la fiecare acțiune a jucătorului se va auzi un sunet corespunzător. La începerea jocului va fi nevoie de introducerea unui username, cu ajutorul unui joystick care ciclează printre litere.

Ideea jocului este de a descoperi toate pătrățelele dintr-o grilă evitându-le pe cele care ascund o mină sub ele. Când un pătrățel este dezvăluit, se afișează un număr care indică numărul de mine învecinate. Acest joc testează abilitățile logice și capacitatea de a face deducții. Ideea jocului a venit din dorința de a realiza un joc cu ajutorul unei plăcuțe si am ales Minesweeper, fiind unul dintre preferatele mele. Așadar consider ca jocul este util deoarece antrenează gândirea logică, dar reprezintă și o modalitate de relaxare în același timp.

Descriere generală

Pentru începerea jocului este necesar ca utilizatorul să își introducă numele cu ajutorul joystick-ului. Jocul începe prin inițializarea tablei de joc cu un număr default de mine. Cu ajutorul celor 6 butoane, jucătorul se deplasează pe tablă și descoperă pătratele. Jocul se termina într-o notă pozitivă, emisă de buzzer, dacă toate pătratele au fost descoperite evitându-se minele, altfel se va auzi un sunet corespunzător eșecului.

Hardware Design

Componente:

Pinii de dezvoltare Arduino:

Schema electrica a proiectului

Am folosit:

Următoarea poză ilustrează implementarea hardware a proiectului la momentul deadline-ului. Așa cum se poate observa, am testat funcționalitatea ecranului LCD.

Adaug o poza a hardware-ului final, în care am stabilizat totul pe o placa de metal și am adăugat imagini sugestive pentru folosirea butoanelor.

Software Design

Mediul de dezvoltare folosit a fost Arduino IDE, iar librăria folosită este TFT.h, care include intern și librăria SPI.h, ambele fiind necesare pentru gestionarea comunicarea cu LCD-ul.

FLOW-UL JOCULUI

IMPLEMENTAREA

Am scris destul de multe linii de cod astfel ca în explicațiile de mai jos, voi insera cele mai importante funcții. În schimb încarc arhiva cu întreagă implementare la secțiunea Download.

1. Definirea pinilor, constantelor și a variabilelor

Configurarea pinilor pentru butoane, joystick, ecran și buzzer am realizat-o folosindu-mă de schema electrică. Am avut nevoie de 2 matrici pentru evidența tablei de joc:

int stateBoard[table_rows][table_cols] = { 0 };
int board[table_rows][table_cols] = { 0 };

Matricea board reprezintă matricea în starea inițială, așa cum este văzută de către utilizator, în timp ce stateBoard reține pozițiile exacte ale minelor și reține valorile numerice din celule. Tot aici am declarat alte variabile necesare de-a lungul implementării.

2. Funcția setup

În funcția de setup am apelat funcțiile de inițializare pentru ecran, buzzer, joystick și butoane, având grijă să activez rezistențele de pullup din cod. De asemenea, m-am folosit de 2 funcții proprii pentru desenarea literelor și a chenarului în care va fi afișat numele.

void setup() {
  TFTscreen.begin();
  clean_background();
  // initializare joystick-ul
  pinMode(SW, INPUT);
  digitalWrite(SW, HIGH);
  // initializare buzzer-ul
  pinMode(buzzerPin, OUTPUT);
  digitalWrite(buzzerPin, HIGH);
  // initializare butoane
  pinMode(BUTTON_PIN_1, INPUT_PULLUP);
  pinMode(BUTTON_PIN_2, INPUT_PULLUP);
  pinMode(BUTTON_PIN_3, INPUT_PULLUP);
  pinMode(BUTTON_PIN_4, INPUT_PULLUP);
  pinMode(BUTTON_PIN_5, INPUT_PULLUP);
  pinMode(BUTTON_PIN_6, INPUT_PULLUP);
  // desenare initiala tabla
  drawAlphabetScreen();
  drawBorder(enteredName);
  randomSeed(analogRead(3));
}

3. Funcția loop

Acestă funcție este împărțită in 2 părți, prima fiind responsabilă de ecranul care permite introducerea numelui jucătorului. Se citesc datele de la joystick și de la butoanele OK și X, modificând-se astfel indicii pentru cursor. Cursorul indica litera selectată și se evidențiază prin culoarea roșu. Accesarea literelor se face cu ajutorul matricei alphabetMatrix[cursorRow][cursorCol]. Butonul OK modifică string-ul enteredName care reține numele, iar butonul X apelează funcția clean_background(); prin care este eliminată ultima litera introdusă. Cea de-a doua parte se declanșează prin modificare variabilei startPage în false și reprezintă jocul propriu-zis de Minesweeper. Mă asigur de faptul că funcțiile de inițializare a matricilor și a variabilelor necesare sunt setate prin codul de mai jos:

if (!gameStarted) {
    score = 0;
    initializeMinesweeperBoard();
    drawScore(enteredName);
    gameStarted = true;
    prevCursorRow = tableCursorRow;
    prevCursorCol = tableCursorCol;
    redrawCursor();
 }

În fiecare moment primesc date de la cele 4 butoane ce indică direcțiile și modific variabilele ce rețin indicii cursorului. De această dată cursorul este indicat printr-un chenar de culoare distinctă. Butonul OK este sugestiv pentru descoperirea celulelor și prin apăsarea lui este apelată funcția revealCell(..) prin care se face descoperirea și funcția drawScore(enteredName) prin care este updatat scorul. Apăsarea butonului X duce la apelarea toggleFlag și drawFlag care sunt responsabile cu marcarea celului cu F (flag) sugerând prezența unei mine acolo. Nu uit să verific cu ajutorul funcției checkWin daca tabla de joc a fost completată corect, ceea ce ar duce la câștigarea jocului.

4. Funcții auxiliare

Următoarele funcții sunt utilizate pentru partea inițială în care se cere introducerea numelui. Trebuie menționat faptul că prin apăsarea directă a butonului OK, se poate evita acest pas.

Următoarele funcții sunt responsabile de sunetele emise de buzzer pe parcursul jocului:

Următoarele funcții ajută la pregătirea jocului propriu-zis:

Următoarele funcții sunt utilizate în marcarea unei celule cu F(flag):

Următoarele funcții ajută la descoperirea unei celule sau la descoperire în masă:

Următoarele funcții sunt utile în verificarea finalului jocului și în afișajele finale, în funcție de caz:

Rezultate Obţinute

Am realizat tot ceea ce mi-am propus, cu precizarea că dacă aș schimba ceva ar fi buzzer-ul activ. Lucrând la acest proiect am învățat diferențele între un buzzer activ și unul pasiv, astfel că unul pasiv mi-ar fi permis să personalizez mai mult sunetul ce însoțește jocul. Atașez poze în diferite momente ale jocului și un video demonstrativ:

Concluzii

Acesta a fost un proiect din care am învățat noțiuni teoretice despre proiectarea cu microprocesoare, pe care la-am pus în practică, dar am învățat și ce de fapt nimic nu e ceea ce pare: deși am fost temătoare la început cu privire la realizarea acestui proiect, s-a dovedit a fi o plăcere să lucrez la el!

Download

alexe_alexandra.zip

Jurnal

26.04.2024 - Comandarea pieselor.

5.05.2024 - Realizarea documentației inițiale.

17.05.2024 - Realizarea hardware-ului

23.05.2024 - Finalizarea implmentarii software

Bibliografie/Resurse

Resurse Hardware

Resurse Software