Gra w zapamiętywanie kolorów

Mając naszą wiedzę do dyspozycji, zbudujemy prostą, ale wciągającą grę.

Jak to działa?

Celem projektu było wykorzystanie jak największej ilości elementów zawartych w Starter Kicie. A czym ów projekt jest? Jak sam tytuł wskazuje, to gra polegająca na zapamiętaniu sekwencji kolorów wyświetlanych za pomocą diody LED RGB, a następnie odtworzeniu jej. Na początku sekwencja składa się z 3 kolorów, potem stopień trudności wzrasta – za każdym razem jest dodawany kolejny kolor do zapamiętania. Pewnym ułatwieniem jest fakt, że do każdego koloru jest przypisany dźwięk o innym tonie – podczas wyświetlania danego koloru odpowiadający mu dźwięk jest emitowany z dołączonego głośniczka, tak więc gra angażuje dwa zmysły: wzrok i słuch. Interfejs użytkownika stanowi wspomniana już dioda RGB, linijka diod LED informująca, który z kolei kolor ustawiamy oraz dwa przyciski typu microswitch. Wciskając oba naraz uruchamiamy grę, lewym wybieramy kolor, a prawym zatwierdzamy. Są jeszcze dwie diody LED informujące, czy udało nam się poprawnie odtworzyć sekwencję. Jeśli zaświeci się lewa – znaczy, że tak, w przeciwnym wypadku zaświeci się prawa dioda.

Zmontowany na płytce stykowej układ prezentuje się tak:

Schemat

Poniżej natomiast jest schemat tego układu wykonany we Fritzingu:

Schemat układu

Co do kwestii technicznych, wszystkie rezystory umieszczone na płytce mają wartość 220Ω, zaś układ scalony w centralnej części płytki to rejestr przesuwający 74HC595, dzięki któremu możemy sterować ośmioma diodami, zużywając na to jedynie trzy cyfrowe wyprowadzenia Arduino.

Kod

Jeśli już mamy wszystko podłączone, teraz należałoby to jakoś oprogramować. Na początku trzeba zadeklarować, co gdzie podłączamy (do których wejść/wyjść). Odpowiada za to ten fragment kodu:

int latchPin = 8, clockPin = 12, dataPin = 3; //rejestr 
                                              //przesuwający
byte data = 0; //dane do wysłania na rejestr
int led8 = 7, led9 = 6; //dodatkowe LEDy
int ledR = 11, ledG = 10, ledB = 9; //LED RGB
int buttonLeft = 5, buttonRight = 4; //przyciski
int speakerPin = 13; //głośniczek

Teraz następuje inicjalizacja – ustawienie funkcji wyprowadzeń, włączenie rezystorów podciągających, itd.:

void setup()
{
  Serial.begin(57600);
  for(int i=3;i<=13;i++) // ustawienie wszystkich pinów
    pinMode(i, OUTPUT); // od 3 do 13 jako wyjścia
  pinMode(buttonLeft, INPUT); // ustawienie pinów przycisków
  pinMode(buttonRight, INPUT); // jako wejścia

  digitalWrite(buttonLeft, HIGH); // włączenie wewnętrznych
  digitalWrite(buttonRight, HIGH); // rezystorów podciągających
  randomSeed(analogRead(0)); // zainicjalizowanie generatora 
  // liczb pseudolosowych wartością odczytaną z niepodłączonego
  // analogowego pinu 0 - przy każdym uruchomieniu będzie ona 
  // inna
  clearLeds();
}

W tym miejscu należy wyjąsnić pewną kwestię, otóż w paru miejscach w kodzie programu pojawia się taki dziwny zapis:

a ? b : c

Jeśli ktoś na co dzień nie programuje w języku C, może być tym nieco zdezorientowany, tym bardziej, że w „Language Reference” na oficjalnej stronie Arduino nie wyjaśniono tego. Jest to tak zwany operator wyrażenia warunkowego. Jeśli warunek podstawiony w miejscu „a” jest spełniony (lub zmienna w miejscu „a” ma wartość TRUE), zostanie zwrócona liczba „b”. W przeciwnym wypadku – „c”. Ot i cała filozofia.

Wróćmy do właściwego programu. Główna pętla wygląda następująco:

void loop()
{
  effect();
  clearLeds();
  if(waitForButton() == 3)
    return;

  for(int j=3;j<=8;j++)
    if(!playLevel(7, j))
      return;
}

Kolejno: na początku, funkcją effect() uruchamiane są dźwiękowe i świetlne „fajerwerki”, a funkcja clearLeds gasi wszystkie diody. Następnie, o ile użytkownik nie wciśnie dwóch przycisków naraz, co spowoduje reset, funkcja playLevel rozpoczyna kolejne poziomy gry, za każdym obiegiem pętli for z drugim parametrem (ilość świateł do zapamiętania) zwiększonym o 1. Pierwszy parametr natomiast jest na sztywno ustawiony jako 7, czyli kolory do zapamiętania losowane są spośród ośmiu (od 0 do 7). Można oczywiście zmniejszyć tę ilość, ale wtedy gra stanie się zbyt prosta. Zdecydowanie lepiej pomanipulować funkcją setColor, dodając kolejne kolory (wystarczy zmienić parametry w setRGB). Mając kilka dodanych kolorów, możemy ich liczbę (mniejszą o 1, bo numeracja jest od 0!) wpisać jako pierwszy parametr funkcji playLevel. Wtedy rozgrywka stanie się trudniejsza, czyli ciekawsza ;).

W kodzie możecie znaleźć mnóstwo komentarzy dzięki czemu mamy nadzieję, że wszystko będzie jasne dla osób początkujących.