Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2014:ant-run

Hra Ant Run na LED 8x8

Zadanie

  • Realizujte hru Ant Run na 8×8 RGB LED matici s použitím vývojové desky FRDM-KL25Z
  • Ovládání bude řešeno akcelerometrem

Rozbor

Porovnanie originálnej predlohy hry Ant Run a zjednodušenej verzie školského projektu Obr. 1. Obr. 1 - Originál hry Ant Run na PC

Hra Ant Run

  • Originálna verzia je určená na PC (Obr 2.)
  • Cieľom hry je udržať mravca v pohybe vytváraním bludiska
  • Bludisko je zostavené z blokov pre priamy smer, križovatku alebo zákrutu
  • Bloky sa otáčajú iba sa pokiaľ na nich nenachádza mravec
  • Po prechode mravca sú použité bloky označené a nefunkčné
  • Použité bloky sa obnovia po určitom čase prechodom „hranou“ bludiska

 Obr. 2 - Porovnanie PC hry a projektu

Zjednodušenie hry pre LED RG 8x8 panel

Zjednodušenie je potrebné pre konverziu hry na trojfarebný displej s obmedzeným počtom pixelov (8×8 LED panel).

  • 4×4 blokov bludiska
    • Každý blok predstavuje 2×2 pixelov
  • Použité políčka sa zreaktivujú po prechode cez okraj bludiska
  • 3 druhy blokov bludiska s možnosťou otáčania
    • 1 druh pre priamy smer
    • 2 druhy pre zákrutu
  • Zelená farba predstavuje cestičku labyrintu
  • Oranžová farba znázorňuje použitý blok
  • Červená farba znázorňuje mravca
  • Aktuálne vybratý blok bliká

Bloky labyrintu sú zobrazené na obrázku Obr. 3. Šípky v blokoch naznačujú chod mravca cez jednotlivé bloky a šípky mimo blokov zobrazujú otáčanie bloku počas hry.  Obr. 3 - Bloky labyrintu

Výslednú interpretáciu zjednodušenej hry približuje nasledujúci obrázok Obr. 4  Obr. 4 - Ukážka práce s blokmi

Počítanie skóre

Výška skóre závisí od počtu správne prejdených blokov labyrintu. Za každý blok labyrintu, ktorý mravec opustí je pripočítaný jeden bod. Body sa ku skóre pripočítajú až prechodom mravca „okrajom“ labyrintu. Skóre sa vynuluje vždy s novou hrou ale aj počas pauzy hry.

Hardware

Z dostupného hardware-ového vybavenia projektu (doska KL25Z a LED shield) boli využité nasledujúce časti (Obr. 5)

 Obr. 5 - Blokové zapojenie HW

  • Vývojová doska FRDM-KL25Z
    • MMA8451Q - 3-osý akcelerometer
    • 19x GPIO výstup pre shield
    • 2x GPIO vstup pre shield
    • PWM pre RGB LED
  • Zobrazovacie zariadenie LED 8×8
    • LED 8×8 RG panel
    • 2x tlačidlá

Software

Program bol písaný pomocou online vývojového prostredia www.mbed.org. Celý kód je zverejnený na stránkach mbed tu MPOA_ant_run V nasledujúcej kapitole sú popísané základné funkcie a princípy programu.


Zobrazovanie na 8x8 LED RG panel

Funkcia zobrazovania je volaná periodicky, s periódou 0,01 s. Zobrazuje sa matica uint8_t matrix[8][8]. Každý prvok tejto matice predstavuje jeden pixel - jednu RG LED. Prvky majú definované stavy

#define led_used    3 // color orange
#define led_lab     2 // color green
#define led_ant     1 // color red
#define led_free    0 // off

,ktoré sú pri vysvecovaní panelu rozkódované a priradené jednotlivým výstupným pinom. Samotné vysvecovanie sa riadi algoritmom popísaným nasledujúcim vývojovým diagramom (Obr. 6). Obr. 6 - Vývojový diagram funkcie show_matrix

Zobrazovacia funkcia riadi jas panelu (použitým oneskorením) aj blikanie kurzoru.


Funkcia napĺňania matice

Viaceré funkcie vyžadujú naplnenie matice zobrazovania naraz. Využívajú pri tom funkciu fill_matrix. Do nej vstupuje uint64_t temp a uint8_t color.

  • Temp predstavuje zakódovaný obrazec definovaný v úvode kódu. Panel LED má 8×8 pixelov ⇒ 64 bitov reprezentujúcich, či je príslušný pixel aktívny
  • Color definuje farbu aktívneho pixelu

Pre každý pixel panelu sa zisťuje, či má byť pixel aktivovaný a v prípade že áno, priradí sa mu farba pomocou nasledujúceho kódu.

for(uint8_t j = 0; j < 8;j++)
{
   for(uint8_t i = 0; i < 8;i++)
   {
      matrix[j][i] = color * ( 0 < (temp & (0x8000000000000000>>((8*j)+i))));  // print template to the matrix 
   }
}

Postupuje sa od MSB, preto sa temp maskuje 0x8000000000000000. Definované sú dve predlohy:

#define template_fill (~0) 
  • Aktívne sú všetky pixely
  • Používa sa na zhasnutie celého panelu (rovnovážny stav pre TEST alebo vyčistenie obrazovky pred zobrazením skóre) alebo na naplnenie panelu použitými blokmi (generácia nového bludiska)
#define template_arrow 0x12244848241200
  • Vykreslí šípku
  • Otočenie šípky zabezpečuje funkcia rotate_matrix, ktorá jednoducho pretočí maticu o 90º.

Stavový automat

Hra je postavená na princípe stavového automatu. Ten beží v nekonečnej slučke funkcie main. Na jednoduchú indikáciu stavov slúži indikačná RGB LED na doske KL25Z. Po zapnutí sa zariadenie dostáva do prvého stavu TEST. Prepojenie medzi jednotlivými stavmi odpovedá nasledujúcemu stavovému diagramu (Obr. 7).  Obr. 7 - Diagram stavového automatu

Stav - TEST

Indikačná dióda – ORANŽOVÁ
Funkcia ľavého tlačidla – Prechod do stavu SAVE
Funkcia pravého tlačidla – Prechod do stavu READY
Ovládanie akcelerometrom – Demonštrácia ovládania

Popis – V stave TEST zariadenie prezentuje ovládanie hry. Po nahnutí zariadenia na niektorú zo strán o 25º sa pohyb zaznamená, čo sa potvrdí vysvietením červenej šípky v smere pohybu. Pre potvrdenie pohybu je potrebné vrátiť sa do východiskovej polohy Idle (uhol natočenie pod 10º). Potvrdenie pohybu je indikované zmenou farby šípky na zelenú.

Stav - SAVE

Indikačná dióda – ZELENÁ (svieti krátko)
Funkcia ľavého tlačidla – Bez funkcie
Funkcia pravého tlačidla – Bez funkcie
Ovládanie akcelerometrom – Bez funkcie

Popis – Rovnovážna (Idle) poloha ovládanie akcelerometrom(popísané v stave TEST) je v určitom rozsahu definovateľná používateľom. Rozsah súvisí z tým, že ovládanie je prepočítavané z ôs rovnobežných na dosku KL25Z. Po uložení nového Idle stavu ovládania sa zariadenie vracia do stavu TEST.

Stav - READY

Indikačná dióda – ORANŽOVÁ (svieti krátko)
Funkcia ľavého tlačidla – Bez funkcie
Funkcia pravého tlačidla – Bez funkcie
Ovládanie akcelerometrom – Bez funkcie

Popis – Stav READY je určený na generovanie nového labyrintu. Generovanie je na panely sprevádzané úvodným obrázkom. Úvodný obrázok je poskladaný z oranžových blokov a bloku „štart“ z ktorého vychádza mravec. Úvodný obrázok je nahradený náhodne vygenerovanými políčkami labyrintu a zariadenie prechádza do stavu PAUSE.

Stav - PAUSE

Indikačná dióda – ČERVENÁ
Funkcia ľavého tlačidla – Prechod do stavu GAME
Funkcia pravého tlačidla – Prechod do stavu READY
Ovládanie akcelerometrom – Bez funkcie

Popis – Stav PAUSE je typická pauza hry. Hra v okamihu prechodu to tohto stavu „zamrzne“ (nebliká ani kurzor výberu bloku *popísaný v stave GAME) . Zo stavu PAUSE môže užívateľ buď pokračovať v hre alebo začať novú hru vygenerovaním nového bludiska.

Stav - GAME

Indikačná dióda – ZELENÁ
Funkcia ľavého tlačidla – Prechod do stavu PAUSE
Funkcia pravého tlačidla – Otoč vybratý blok o 90º
Ovládanie akcelerometrom – Ovládanie kurzoru (výber bloku bludiska, ktorý je potrebné otočiť)

Popis – Princípom hry je udržať mravca v pohybe. Mravec sa po bludisku pohybuje sám, úlohou hráča je tvorba priechodnej cesty bludiskom. Priechodná cesta bludiskom sa vytvára otáčaním jednotlivých blokov bludiska. Hráč môže otáčať iba čisté bloky labyrintu. To znamená bloky, ktoré ešte neboli použité, alebo v nich už mravec nie je. Prechodom mravca sa blok zaradí medzi použité, a mravec po nich už nemôže viac ísť. Jediným spôsobom, ako bloky zreaktivovať je prechod „cez okraj labyrintu“. Po takomto prechode je mravec prenesený na protiľahlú stranu labyrintu (pokiaľ je protiľahlý blok správne natočený) a všetky použité bloky labyrintu sú opäť náhodne vygenerované.

Hra začína vždy blokom „štart“ na rovnakom mieste (druhý blok zľava, druhý blok zhora) rovnakým smerom pohybu mravca (nadol). Kurzor je vždy na začiatku hry umiestnený pod blok „štart“, hráč môže teda hneď správne nasmerovať prvý blok. (toto rozloženie je zabezpečené pri generovaní labyrintu v stave READY). Hráč pohybuje doskou, čím ovláda pohyb kurzoru, ktorý predstavuje blikajúce políčko. Keď sa hráč premiestni kurzorom na políčko, ktoré potrebuje otočiť aby vytvoril správnu cestu labyrintom, použije pravé tlačidlo ovládania.

Hra končí narazením mravca na zle otočený alebo použitý blok. Po skončení hry sa zariadenie prechádza do stavu SCORE.

Stav - SCORE

Indikačná dióda – ČERVENÁ/MODRÁ (preblikávanie)
Funkcia ľavého tlačidla – Prechod do stavu READY
Funkcia pravého tlačidla – Bez funkcie
Ovládanie akcelerometrom – Bez funkcie

Popis – Stav SCORE nastáva po prehre v hre. Prehrá nastane ak

  • Mravec narazí na nesprávne otočený blok labyrintu do ktorého nemôže vojsť
  • Mravec narazí na použitý blok

V tomto stave je na LED panely vyobrazené skóre hráča. Na počítanie skóre je vyhradená premenná dátového typu uint32_t.

Handbook http://developer.mbed.org/handbook/C-Data-Types unsigned int uint32_t 0 .. 4,294,967,295

Vysvietiť celé takto dlhé číslo je na 8×8 LED matici nemožné (čitateľne pre normálneho bežného človeka). Preto skóre rotuje po zobrazovacom panely v smere zľava doprava. Pre lepšiu prehľadnosť a kompaktnejšie zobrazenie nie sú čísla oddelené medzerou, ale farbou. Farby sú tri, čo pomáha k oddeleniu tisícok, desať tisícok a miliónov (gratulujem hráčovi s takým skóre, ja som nahral max 88). Každé číslo je definované v úvode kódu 24 bitovým kódom (3 stĺpce a 8 riadkov). Čísla sú vysvecované po stĺpcoch. Prevod čísla na znak zabezpečuje funkcia uint32_t translate(uint8_t number). Princíp vyobrazovania skóre je popísaný nasledujúcim vývojovým diagramom ( Obr. 8).

 Obr. 8 - Zobrazovanie skóre

Stav hry - LEARN

*nejedná sa o stav stavového automatu ale o mód v ktorom zariadenie pracuje

Popis – Hra Ant Run nie je veľmi známa. Vlastne asi vôbec. Preto je zložité novému hráčovi vysvetliť celý princíp hry, hlavne z dôvodu tak trochu obrátenej logiky hrania (mravec sa pohybuje sám, treba mu postaviť nekonečnú cestu bludiskom). Preto bol do hry zavedený výučbový mód.

Pre vstup do tohto módu je potrebné počas štartu mikroprocesoru držať naraz obe tlačidlá. Užívateľ je o vstupe do výučbového módu informovaný indikačnou LED, ktorá svieti na modro.

Vo výučbovom móde funguje celé zariadenie rovnako ako v štandardnom stave, hru však nie je možné prehrať. Pokiaľ hráč zle zostaví labyrint, mravec príde na poslednú pozíciu ktorú mu cesta labyrintom umožní a čaká na správne natočenie ďalšieho bloku. V stave LEARN sa teda ani nepočíta skóre, ide o zoznámenie so základnými princípmi hry.


Ovládanie

Hra je ovládaná kombináciou tlačidiel a pohybov doskou. Pohyb doskou je periodicky snímaný akcelerometrom MMA8451Q z dosky KL25Z a prepočítaný na údaje o natočení dosky. O periodické vyčítanie údajov sa stará prerušenie Ticker acc_scan. Perióda vyčítania bola určená ako 100 ms, čo zaručuje dostatočne citlivé ovládanie. Pohyb je rozdelený do dvoch akcii.

  • V prvom kroku je to výber smeru otočením dosky o uhol viac ako 25º (od rovnovážnej polohy)
  • V druhom kroku je potrebné pohyb potvrdiť návratom dosky do rovnovážnej polohy

Užívateľ si môže zvoliť rovnovážnu polohu v stave TEST, ktorý je určený na oboznámenie s ovládaním po zapnutí dosky. Smer pohybu je reprezentovaný premennou acc_dir typu

typedef enum  {idle, left, up, right, down} direction_t;

Na obrázku Obr. 9 je zobrazený princíp vyhodnocovania dát z akcelerometra.

Obr. 9 - Vyhodnocovanie dát z akcelerometra

Funkcia confrim_dir potvrdzuje návrat do rovnovážnej polohy vykreslením zelenej šípky so správnym natočením alebo maže údaje vysvietené na panely v prípade, že užívateľ doskou nepohol.

Funkcia move_cursor v hre pohybuje s Funkcia confrim_dir potvrdzuje návrat do rovnovážnej polohy vykreslením zelenej šípky so správnym natočením alebo maže údaje vysvietené na panely v prípade, že užívateľ doskou nepohol. blokom (kurzorom ⇒ aktuálnym výberom). Pohyb kurzoru je nekonečný ⇒ ak prejde hráč „za okraj“ kurzor sa objaví na protiľahlej strane.


Generovanie labyrintu

Generovanie labyrintu zaobstaráva funkcia reload_matrix ktorá je volaná v dvoch prípadoch. Generácia nového labyrintu na začiatku hry a generácia nových blokov namiesto použitých po prechode mravca „okrajom“ bludiska. V rámci funkcie sa prejde každý blok labyrintu. Pokiaľ je blok označený ako použitý – všetky bloky matice sú označené ako led_used, vygeneruje sa za tento blok nový blok labyrintu. Ten je náhodne určený a náhodne otočený. Bloky sú preddefinované v úvode kódu. Ich definícia v šestnástkovej sústave šetrí miesto a umožňuje jednoduché pretáčanie bloku pomocou bitového posunu.

#define lab_turn_big    0x0D  /* 
                               *  x x
                               *  . x 
                               */
 
#define lab_turn_small  0x08   /* 
                               *  x .
                               *  . . 
                               */
 
#define lab_straight    0x0A   /* 
                                *  x .
                                *  x . 
                                */

Funkcia reload_matrix obsahuje aj inkrementáciu skóre. Jeden vygenerovaný blok znamená zvýšenie počítadla skóre o jeden bod.

void reload_matrix(void)
{
    // blocks horizontal
    for(uint8_t j = 0; j < 4;j++)
    {
        // blocks vertical
        for(uint8_t i = 0; i < 4;i++)
        {
            int8_t block;   // random block type
            int8_t shift;   // random block turn
 
            // if labyrint part == used => generate new part 
            if((matrix[j*2][i*2] == led_used) && (matrix[(j*2) + 1][i*2] == led_used) 
            && (matrix[(j*2) + 1][(i*2) + 1] == led_used) && (matrix[j*2][(i*2) + 1] == led_used))    
            {
                 // random block selection
                 switch( rand() % 3 )
                 {
                    case 0:
                        block = lab_turn_big;
                        break; 
                    case 1:
                        block = lab_turn_small;
                        break;
                    case 2:
                        block = lab_straight;
                        break; 
                 }
 
                 // random shift 0-0st, 1-90st, 2-180-st, 3-270st
                 shift = rand() % 4;
                 matrix[2*j][2*i]         = led_lab * ( 1 & block >>  (shift % 4));       //  0 
                 matrix[2*j][(2*i)+1]     = led_lab * ( 1 & (block >> (++shift % 4)));    //  1
                 matrix[(2*j)+1][2*i]     = led_lab * ( 1 & (block >> (++shift % 4)));    //  2
                 matrix[(2*j)+1][(2*i)+1] = led_lab * ( 1 & (block >> (++shift % 4)));    //  3
 
                // score counter, one block == one point
                if(game_state == game)
                    score_cnt++;
            }
        }
    }
}

Beh mravca

Najzložitejšia funkcia programu zabezpečuje beh mravca. Je volaná periodicky každých 1,2 s. Táto časová konštanta bola určená na základe testov. Dáva hráčovi dostatočný čas na tvorbu labyrintu, nie však toľko, aby hra nemala spád. Rýchlosť mravca je počas celej hry konštantná (na takto malom hracom priestore je to aj tak primerane obtiažne). V prvom rade je potrebné uvedomiť si princíp pohybu. Bloky, ktoré hra obsahuje umožňujú obmedzené množstvo pohybov. Podľa polohy mravca v bloku je možné určiť, kam má ďalej pokračovať. Možnosti pohybu v závislosti na predchádzajúcom smere pohybu sú zobrazené na tomto obrázku (Obr. 10)

 Obr. 10 - Možnosti pohybu mravca

Pohyb mravca teda definujú premenné, predstavujúce polohu (poradie stĺpca, poradie riadka) a smer pohybu (enum direction_t *rovnaký ako v ovládaní). Ich kombináciou sa dá zistiť presná poloha mravca.

Vývojový diagram pohybu mravca v labyrinte je na obrázku Obr.11.
Pre prvé určenie smeru pohybu (vpravo/vľavo alebo hore/dole) sa využíva vlastnosť dátového typu enum, v ktorom jednotlivé prvky predstavujú na čísla od 0 ďalej. Vo vývojovom diagrame pokračuje vetvenie algoritmu testom na „1. typ pohybu“. Týmto pohybom sa myslí pohyb, keď mravec v predchádzajúcom kroku vošiel do tohto bloku (nezáleží pri tom z akej strany). V obrázku vyššie tento stav zobrazujú spodné dva bloky. Prioritný pohyb je vždy v rámci bloku, ak takýto pohyb nie je možný, zisťuje sa, či je možný pohyb smerom von z bloku. Pohyb von z bloku je možný iba v prípade, že je blok labyrintu, do ktorého mravec smeruje vhodne natočený. To sa zistí tak, že pixel kam mravec mieri je označený led_lab (blok labyrintu) a vedľajší pixel (na rozhraní aktuálneho a budúceho bloku) je označený ako led_free (voľný blok). Ak mravec opúšťa blok (algoritmus mu to dovolil), môžu nastať dva prípady prechodu do vedľajšieho bloku

  • Štandardný prechod
    • Predošlý blok sa označí za použitý
  • Prechod cez okraj
    • Predošlý blok sa označí za použitý
    • Vygenerujú sa nové bloky labyrintu miesto použitých

V prípade, že nie je možný ani pohyb v bloku, ani pohyb mimo bloku, hra končí.

 Obr. 11 - Algoritmus hľadania cesty bludiskom pre pohyb mravca

Video

Hra Ant Run, v úvode je stav TEST a demonštrácia ovládania.

Hra je v móde LEARN ktorý slúži na predstavenie hry (nehrá sa na skóre)

Podsvietenie dosky

Sekanie obrazu je spôsobené automatickým zaostrovaním môjho telefónu.

Záver

Cieľom projektu bola realizácia hry Ant Run na určenom hardware-ovom vybavení. Hra funguje v dvoch módoch - vo výučbovom móde a v móde s počítaním skóre. Oba sú odtestované a fungujú, čo dokazuje aj priložené video.

Celý zdrojový kód je uverejnený na stránkach mbed MPOA_ant_run .

2014/ant-run.txt · Poslední úprava: 2015/01/18 23:42 autor: Tomáš Jankech