Table of Contents

Wordle

Introducere

  • Proiectul vine de la jocul Wordle, un joc implementat de New York Times in care trebuie sa ghicesti un cuvant de 5 litere in 6 incercari. Ca indicii, se va efectua o colorare a literelor care sunt in cuvant, dar nu pe aceeasi pozitie ca si cuvantul cautat, cu galben, iar cu verde literele din cuvant pe aceeasi pozitie. Cele care nu exista in cuvant vor fi colorate cu gri.
  • Scopul proiectului este de a implementa acest joc in format fizic.
  • Este important sa avem un vocabular cat mai extins, dar poate fi greu sa il mentinem.
  • Jocul ajuta mentinerea si chiar extinderea acestui vocabular.

Descriere generală

Schema Bloc:

Descriere:

  • Jocul primeste input de la tastatura(un cuvant de 5 litere)
  • Il prelucreza si transmite literele care sunt in cuvant(conform regulilor descrise mai devreme)
  • Jocul se termina cand a ghicit cuvantul sau cand ramane fara incercari

Hardware Design

Listă de piese:

  • 1 x Arduino UNO
  • 1 x LCD de 2.8'' cu SPI și Controller ILI9341
  • 1 x Keyboard
  • 1 x Translator de Nivel Bidirectional cu 4 Canale

Schema Electrica:

Rolul LCD-ului este de a arata interfata pe care se va joca Wordle. Pentru conectarea LCD-ului am folost pinii:

Rolul tastaturii este de a putea insera caractere intr-un mod cat mai usor. Pentru conectarea tastaturii am taiat cablul acesteia si am conectat 4 fire:

Implementare fizica

wordle_without_keyboard.jpeg

Pentru functionarea ecranului LCD ili9341 a trebuit sa folosesc un Translator de Nivel Bidirectional cu 4 Canale, pentru CLK, MOSI, RES si DC, deoarece display-ul functiona pe 3v3, iar placuta arduino pe 5v. De asemenea, am realizat un divizor de tensiune pentru CS1, deoarce acesta este un canal unidirectional si nu aveam nevoie sa translatam in ambele parti.

wordle_with_keyboard_wide.jpeg

Pentru keyboard, am taiat cablul de ps/2 de la tastatura si am vazut cele 4 fire descrise si mai sus. Dupa ce le-am identificat si am facut un test cu osciloscopul ca trimite bine semnalele, am conectat-o la arduino.

playing_mode.jpeg

Tot ce tine de logica jocului si design-ul acestuia este realizat din software si descris mai jos.

Final Look

wordle_in_box.jpeg

Software Design

Acest cod este un exemplu de implementare a jocului Wordle folosind o placă Arduino și un ecran TFT ILI9341, controlate prin intermediul unei tastaturi PS2. Iată o scurtă descriere a codului:

Mediul de Dezvoltare

Codul este scris în limbajul C++ și este destinat să fie rulat pe o placă Arduino. Utilizează librăriile PS2Keyboard, SPI, Adafruit_GFX, și Adafruit_ILI9341 pentru a comunica cu tastatura PS2 și afișajul TFT ILI9341.

Diagrama de Stari a jocului

Pentru a putea alege intre cele doua optiuni din meniu se vor folosi sagetile de la tastatura (UP si DOWN).

Algoritmi și Structuri Implementate:

Surse și Funcții Implementate:

Codul implementează funcții pentru inițializarea și resetarea jocului, desenarea meniului, afișarea regulilor jocului, gestionarea feedback-ului pentru ghicirea cuvântului, precum și gestionarea intrărilor de la tastatură. Implementează un ciclu loop() care verifică disponibilitatea intrărilor de la tastatură și gestionează comenzile utilizatorului în funcție de starea jocului și a meniului.

resetGame():

Această funcție este responsabilă pentru resetarea jocului la începutul unei sesiuni noi. Alege un cuvânt ascuns aleatoriu din lista de cuvinte și resetează toate variabilele necesare pentru următoarea încercare de ghicire.

void resetGame() {
targetWord = wordList[random(0, wordCount)];
currentGuess = 0;
charIndex = 0;
memset(guess, 0, sizeof(guess));
gameOver = false;
// Clear the display and redraw the grid
display.fillScreen(ILI9341_BLACK);
display.setTextColor(ILI9341_WHITE);
display.setTextSize(2);
// Draw empty grid for guesses
for (int i = 0; i < maxGuesses; i++) {
  for (int j = 0; j < 5; j++) {
    display.drawRect(gridStartX + j * (boxWidth + boxSpacing), gridStartY + i * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_WHITE);
  }
}

}

drawMenu():

Această funcție este responsabilă pentru desenarea meniului pe ecran. Afișează titlul jocului și opțiunile de meniu disponibile.

void drawMenu() {
display.fillScreen(ILI9341_BLACK);
// Draw "WORDLE" title
display.setTextSize(4);
display.setTextColor(ILI9341_WHITE);
for (int i = 0; i < 6; i++) {
  display.fillRect(menuX + i * (boxWidth + 4), menuY - titleSpacing, boxWidthMenu, boxHeightMenu, ILI9341_GREEN);
  display.setCursor(menuX + i * (boxWidth + 4) + 4, menuY - titleSpacing + 8);
  display.print("WORDLE"[i]);
}
// Draw menu options
display.setTextSize(2);
display.setTextColor(ILI9341_WHITE);
display.setCursor(menuX, menuY + titleSpacing);
for (int i = 0; i < menuOptionCount; i++) {
  if (i == currentOption) {
    display.setTextColor(ILI9341_GREEN); // Highlight current option
  } else {
    display.setTextColor(ILI9341_WHITE);
  }
  display.println(menuOptions[i]);
  display.setCursor(menuX, menuY + titleSpacing + (i + 1) * menuSpacing);
  }
}
startWordleGame():

Această funcție conține logica jocului Wordle. Așteaptă intrările de la tastatură, validează ghicirile utilizatorului și oferă feedback vizual pentru fiecare încercare de ghicire.

void startWordleGame() {
// Reset the game
resetGame();
// Game loop
while (!gameOver) {
  if (keyboard.available()) {
    char c = keyboard.read();
    if (c >= 'a' && c <= 'z') {
      c = c - 'a' + 'A'; // convert to uppercase
    }
    if (charIndex < 5 && c >= 'A' && c <= 'Z') {
      guess[charIndex] = c;
      display.setCursor(gridStartX + charIndex * (boxWidth + boxSpacing) + 8, gridStartY + currentGuess * (boxHeight + boxSpacing) + 8);
      display.print(c);
      charIndex++;
    }
    if (c == PS2_ENTER && charIndex == 5) {
      guess[5] = '\0'; // Null-terminate the guess
      // Determine box colors based on the guess
      for (int i = 0; i < 5; i++) {
        if (guess[i] == targetWord[i]) {
          display.fillRect(gridStartX + i * (boxWidth + boxSpacing), gridStartY + currentGuess * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_GREEN);
        } else if (strchr(targetWord, guess[i])) {
          display.fillRect(gridStartX + i * (boxWidth + boxSpacing), gridStartY + currentGuess * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_YELLOW);
        } else {
          display.fillRect(gridStartX + i * (boxWidth + boxSpacing), gridStartY + currentGuess * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_DARKGREY);
        }
        display.setCursor(gridStartX + i * (boxWidth + boxSpacing) + 8, gridStartY + currentGuess * (boxHeight + boxSpacing) + 8);
        display.setTextColor(ILI9341_WHITE);
        display.print(guess[i]);
      }
      if (strcmp(guess, targetWord) == 0) {
        showPopup("You Win!", "");
        gameOver = true;
        return;
      }
      currentGuess++;
      charIndex = 0;
      memset(guess, 0, sizeof(guess));
      if (currentGuess == maxGuesses) {
        char buffer[30];
        sprintf(buffer, "The word is: %s", targetWord);
        showPopup("You lose!", buffer);
        gameOver = true;
        return;
      }
    }
    if (c == PS2_BACKSPACE && charIndex > 0) {
      charIndex--;
      guess[charIndex] = '\0';
      display.fillRect(gridStartX + charIndex * (boxWidth + boxSpacing), gridStartY + currentGuess * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_BLACK);
      display.drawRect(gridStartX + charIndex * (boxWidth + boxSpacing), gridStartY + currentGuess * (boxHeight + boxSpacing), boxWidth, boxHeight, ILI9341_WHITE);
    }
  }
 }
}

Rezultate Obţinute

Rezultatele obținute în urma realizării proiectului a fost implementarea efectiva a jocului Wordle.

Funcționalitatea Jocului Wordle:
Interfața Grafică și Interacțiunea cu Utilizatorul:
Meniul și Opțiunile de Joc:

Concluzii

Proiectul a demonstrat că este posibil să fie implementat un joc interactiv și educativ pe o platformă de microcontrolere, utilizând ecranul TFT și tastatura PS2.

De asemenea, de la inceput am vrut ca jocul sa fie cat mai usor de jucat, de aceea am implementat inserarea cuvintelor prin tastatura.

Sper ca prin acest proiect o sa invete si alti oameni de acest joc si o sa fie placut surprinsi de el ^_^.

Download

wordle.zip

Jurnal

  1. 05.05.2024 : A creat pagina de wiki intitulata Wordle
  2. 05.05.2024 : Am comandat piesele
  3. 15.05.2024 : Am incercat sa leg display-ul si tastatura(aici aveam tastatura usb si incercam sa o leg cu un cablu de usb mama taiat)
  4. 15.05.2024 : Realizat ca nu ajunge curent la tastatura, comandat tastatura ps/2
  5. 22.05.2024 : Implementat pentru display un level shifter ca sa poata mearga display-ul si intr-un final a mers si tastatura
  6. 22.05.2024-ongoing : Implementat software descris mai sus.
  7. 27.05.2024 : Prezentare proiect PM Fair.

Bibliografie/Resurse

Export to PDF