Table of Contents

Andreea-Bianca OPREA (78497) - Nu te supăra, frate!

Autorul poate fi contactat la adresa: Login pentru adresa

Introducere

Proiectul reprezintă versiunea electronică a jocului “Nu te supara, frate!” cu 2 jucatori, cu mici modificari.

Vor exista 2 jucatori: RED si GREEN. Cei patru pioni ai fiecarui jucator vor fi simulati prin led-uri in culorea specifica (rosu sau verde). Aruncarea zarului va fi simulata la apasarea unui buton si numarul generat va fi afisat pe display.

La inceput, in dreptul fiecarui jucator se vor lumina 3 led-uri in cercurile colţului “B” (cele 4 led-uri separate de restul matricii) şi un led în cercul “A” (led-ul cel mai din stanga pe prima coloana). Scopul jocului este de a înconjura planşa de joc cu cei patru pioni pentru a ajunge cu toţi pionii în cerculeţele “1”, “2”, “3”, “4” ale culorii corespunzatoare jucatorului.

Reguli

  1. Fiecare jucător va simula prin apasarea unui buton aruncarea cu zarul o singură dată. Dupa afisarea numarului, jucatorul trebuie sa selecteze cu ce pion din cei aflati pe tabla va juca aceasta runda. Selectarea se face prin mutarea stanga, sus, dreapta, stanga folosind butoane. Dupa alegerea pionului, va apasa butonul de select si pionul respectiv va fi mutat automat in functie de numarul generat.
  2. Pionul aflat in “B” poate fi mutat în “A” numai atunci când, aruncând cu zarul, s-au nimerit 6 puncte. Întotdeauna zarul cu 6 puncte obligă la această mutare. Numai în cazul în care nu mai exista niciun pion în “B” se poate înainta cu orice alt pion
  3. In timpul jocului, cand se nimereste cu zarul 6, jucatorul are dreptul la încă o aruncare
  4. Când se ajunge pe un cerc ocupat de alt jucător pionul acestuia va fi scos şi readus în “B” de unde nu va putea fi repus în joc decât printr-o aruncare cu zarul de 6 puncte
  5. Se poate sări peste pionii proprii sau al celuilalt jucător socotind însă cercurile sărite
  6. Nu se poate intra în cercurile finale “1”, “2”, “3”, “4” decât aruncând cu zarul un număr corespunzător cercurilor libere. Dacă iese un număr mai mare şi nu exista un alt pion care sa fie mutat, se va aştepta până când nimereste numărul potrivit. În interiorul acestor cercuri nu pot intra decât pionii care au culoarea corespunzatoare.

Modificări

Cele 4 cercuri finale nu sunt asezate conform jocului original, pozitionarea lor este ca in imaginea de mai jos. Datorita acestei modficari, in cadrul jocului a aparut urmatoarea regula:

  1. Daca jucatorul este pozitionat pe aceeasi linie cu pozitiile “1” sau “2” si a nimerit unul din aceste numere, se va verifica daca poate intra (pozitia este libera). In caz contrar, acesta va putea merge mai departe doar daca exista mai putini de 2 jucatori care au trecut de aceasta linie pentru ca dincolo de ea exista doar 2 pozitii finale “3” si “4”.
  2. Ultima verificare mentionata mai sus se face si daca pozitia finala obtinuta prin mutara pionului depaseste linia.

Descriere generală

Hardware Design

Lista de piese
Schema electrica

Fiecare jucator se va pozitiona pe tabla de joc folosind cele 4 butoane: UP, DOWN, LEFT, RIGHT. Dupa alegerea unui pion, il va selecta folosind butonul SELECT corespunzator. Simularea zarului se face la apasarea butonului DICE, iar numarul va fi afisat pe display.

Pentru ca numarul de porturi necesare controlarii ledurilor a fost de departe insuficient, catodurile comune ale ledurilor RGB de pe aceeasi linie au fost legate intre ele, iar anodurile corespunzatoare fiecarei culori au fost legate pe coloane. Numarul de porturi disponibile fiind in continuare prea mic, am folosit registre de deplasare 74HC595 astfel:

  1. 2 shift registers au fost legate in cascada pentru a controla coloanele matricii
  2. 1 shift register a fost folosit pentru a controla liniile

Software Design

Funcții implementate

Functia ludo() este cea care simuleaza rularea jocului: se verifica butonul apasat si jucatorul se va muta pe tabla in vederea selectiei pionului sau se apeleaza functiile corespunzatoare:

  1. la apasarea butonului de SELECT, se apeleaza functia make_move_RED(/GREEN)() care va muta automat pionul selectat pe tabla (cu atentie la toate regulile specificate la inceputul jocului)
  2. la apasarea butonului DICE, se va apela functia roll_the_dice() care va genera un numar aleator si il va afisa pe display
  int digitArray[7] = {0b00000000, 0b10000100, 0b11010011, 0b11010110, 0b10110100, 0b01110110, 0b01110111};
  void roll_the_dice(void)
  {
      dice = rand() % 6 + 1;
      PORTC = digitArray[dice];
  }

Mai jos se gasesc functiile de manipulare a matricei de led-uri folosind registrele de deplasare:

  void load_bit_to_register_1(unsigned int bit)
  {
      /* Set bit */
      if (bit == 1)
          PORTA |= (1 << PA2);
      else
          PORTA &= ~(1 << PA2);
          
      _delay_us(10);
      
      /* Load bit - clk front crescator */
      PORTA |= (1 << PA0);
      
      _delay_us(10);
      
      /* Reset clk */
      PORTA &= ~(1 << PA0);
  }
  /* Incarca in registru cei doi biti
   * corespunzatori aprinderii unui led 
   */
  void load_color_of_led(unsigned int R, unsigned int G)
  {
      load_bit_to_register_1(G);
      load_bit_to_register_1(R);
  }
  /* Incarcare coloana curenta */
  void load_LEDS_column_colors_for_given_row(int row)
  {
      int i = 6;
  
      /* Dezactivare latch */
      PORTA &= ~(1 << PA1);
  
      /* Incarcare coloana in registru de deplasare */
      while (i > -1) {
          
          int color = mat[row][i];
  
          if (color == RED) {
              load_color_of_led(1, 0);
          }
          else if (color == GREEN) {
              load_color_of_led(0, 1);
          }
          else if (color == YELLOW) {
              load_color_of_led(1, 1);
          }
          else {
              load_color_of_led(0, 0);
          }
  
          i--;
          
      }
  
      /* Activare latch */
      PORTA |= (1 << PA1);
  }
  /* Afisare matrice */
  void print_game_matrix(void)
  {
      int i;
      /* Incarcare linii si coloane
       * corespunzatoare fiecarei linii
       */
      for (i = 0; i < 7; i++) {
      
          PORTA &= ~(1 << PA4);
          
          int j = 6;
          while (j > -1) {
              if (j == i) {
                  load_bit_to_register_2(0);
              }
              else {
                  load_bit_to_register_2(1);
              }
      
              j--;
          }
          
          load_LEDS_column_colors_for_given_row(i);
      
          PORTA |= (1 << PA4);
      }
  }

Rezultate Obţinute

Concluzii

Lipirea tuturor pieselor a necesitat mult mai mult timp si atentie decat am crezut initial. Am petrecut peste 16h pentru a termina partea de hardware, cu tot cu ajutorul de care am avut nevoie pentru lipirea firelor. Partea de software a durat si ea destul de mult timp, a trebuit sa ma joc putin cu aprinderea ledurilor pentru a-mi da seama cum folosesc registrele de deplasare inainte de a scrie implementarea propriu-zisa.

Proiectul este final si indeplineste toate cerintele specificate.

Download

Jurnal

  1. 22 aprilie - Alegerea proiectului: descriere generala, lista de piesa, schema bloc
  2. 6 mai - Schema electrica
  3. 23 mai - Update documentatie (actualizare descriere, lista de piese, schema electrica, software si hardware design, rezultate, concluzii, arhiva cod functional single player)
  4. 24 mai - Versiune finală (arhiva cod complet functional, actualizare bibliografie/resurse)

Bibliografie/Resurse

Resurse Hardware

Resurse Software