Snake 8x8 LED

Bc. Jan Divín, Bc. Petr Kříž, UREL, FEEC, VUT Brno
xdivin01stud.feec.vutbr.cz
xkrizp06stud.feec.vutbr.cz

Obsah:

  1. Úvod
  2. Realizace
  3. Závěr
  4. Literatura

Úvod

Cílem projektu bylo vytvořit aplikaci na tříbarevný maticový displej o rozsahu 8x8 LED s ovládáním pomocí čtyř tlačítek. Jedná se o hru "Had", kterou znáte například ze starých mobilních telefonů. Cílem této hry je posbírat co největší množství "jablek", než se had zamotá a kousne do sebe. Po každém snězeném jablku se had prodlouží o jeden článek.

Realizace

Celá realizace byla provedena na školní návrhové desce DEVELOPMENT BOARD ATmeg16, navrženou Jiřím Šebestou v roce 2006. K této vývojové desce byl navíc ještě přidán externí modul s tříbarevným maticovým displejem. Využívá všechny porty použitého mikroprocesoru ATmega16, kde port A je zelená barva, port C červená barva, port B výběr aktuálního řádku (tři piny) a port D tlačítka (čtyři piny).

Průběh samotného programu je poměrně jednoduchý. Po spuštění se inicializuje had na počáteční místo a je vygenerována počáteční náhodná poloha prvního jablka (bod zelené barvy). Had má v tento okamžik délku tři články a jeho "hlava" je zvýrazněna oranžovou barvou. Tato situace je zobrazena na obrázku níže.

Inicializace hada
Dále je had ovládán čtyřmi tlačítky připojenými na port D (čtyři nejnižší piny) a ovládán ve směrech podle stisknutého tlačítka. Tlačítko S1 vede hada doleva, S2 nahoru, S3 dolů a S4 doprava. Had má povoleno prostupovat zdmi a je mu zakázáno otočení o 180°, kdy by se kousnul do druhého článku (požíral by sám sebe). Ukázka rozehrané hry je uvedena nížě.
průběh hry
Na závěr hry, pokud už se nepovede hráči uřídit hada a on se kousne kdekoliv do svého těla, bude na dobu přibližně dvou sekund zobrazen tento stav s hlavou zakousnutou do těla a následně zobrazeno skóre, které je rovno počtu snědených jablíček (toto skóre je uloženo jako bitmapa pouze v datové paměti programu). Ukázka dosaženého počtu 18 bodů je uvedena níže.
zobrazení skóre
Pokud chce hráč zlepšit své závěrečné skóre, musí zmáčknout tlačítko S1 (vlevo), které opětovně spustí aplikaci.
Názornou ukázku běhu programu lze shlédnout zde.

Byly provedeny dvě funkční programové realizace, uživatel rozdíl ve výsledku nepozná.

  1. Realizace je co do rozsahu kódu objemnější, protože byla psána ve dvou souborech. V externí knihovně, která obsahuje funkce pro pohyb hada v rozměru 8x8 bodů, generování náhodné pozice jablka jako potravy pro hada a funkci, která řeší případnou kolizi, tzn. zakousnutí hada do sebe sama. V hlavním programu je poté kód, který obsluhuje aplikaci po hardwarové stránce, tzn. obsluha pro stisk tlačítka, volání pozice hada a jablka pomocí funkcí z externí knihovny pro výpis na maticový displej. Krátká ukázka kódu je uvedena níže.
  2. void tlacitka (void) //funkce na osetreni stisku tlacitka
    {
      if (horizont) //kontrolujeme,zda bylo stisknuto tlacitko ve 
      {             //vertikalnim nebo horizontalnim smeru
        if (bit_is_clear(PIND,nahoru)) //pokud bylo stisknuto tlacitko nahoru,
    	{                              //tak zmenime smer pohybu hada a promennou
    	  pohyb = nahoru;              //horizont vynulujeme, aby bylo mozno nastavit
    	  horizont = 0;                //dalsi smer pohybu vlevo nebo vpravo
    	}
    	if (bit_is_clear(PIND,dolu)) 
    	{
    	  pohyb = dolu;
    	  horizont = 0;
    	}
      }
      else
      {
        if (bit_is_clear(PIND,vlevo)) 
    	{
    	  pohyb = vlevo;
    	  horizont = 1;
    	}
    	if (bit_is_clear(PIND,vpravo)) 
    	{
    	  pohyb = vpravo;
    	  horizont = 1;
    	}
      }
    }
    	
  3. Realizace je napsána efektivněji, co do rozsahu kódu. Je psána v jednom souboru a obsahuje práci s ukazateli i s programovou pamětí. Oproti první realizaci se po fatálním zakousnutí hada navíc zobrazí dosažené skóre. Níže je uvedena ukázka kódu, který určuje, co se stane po zakousnutí hada do sebe sama.
  4. while (tik<2000);//nechá svítit nabouraného hada cca 2sec
    ukazj=&cisla[0]+(7*bodyj);//nahraje do ukazatele jednotek skóre počáteční řádek odpovídajícího čísla 
    ukazd=&cisla[0]+(7*bodyd);//nahraje do ukazatele desítek skóre počáteční řádek odpovídajícího čísla 
    for (i=0;i<7;i++)//zobrazí skóre
    {
      obrz[i] = pgm_read_byte(ukazd)<<4;//první desítky se nahrajou rovnou na čtyři horní bity
      obrz[i] |= pgm_read_byte(ukazj); //k tomu se přičtou jednotky
      obrc[i] = obrz[i]; //obraz bude oranžový
      ukazd++; //další řádek z bitmapy
      ukazj++;
    }
     obrz[7] = 0xff;//zhasnutí nevyužitého řádku skóre
     obrc[7] = 0xff;
     while (tik<800);//jen aby si uživatel užil alespoň 800ms svého skóre
      tik=0;  
      while (bit_is_set( PIND,3 )); //opětovné spuštění hry stiskem tlačítka S1
    	 

Závěr

Tento projekt byl zajímavý logický oříšek, který bylo možno řešit několika způsoby. Náš tým vytvořil dvě funkční realizace, které se od sebe sice velmi liší stylem zdrojového kódu, ale v konečném výsledku realizují stejnou věc. První realizace je dvakrát objemnější (co do rozsahu kódu) než druhá realizace a bez optimalizace zabírá 40% programové paměti. Využití datové paměti s optimalizací je u obou realizací srovnatelná- cca. 17%. Celý program pro AVR studio lze stáhnout zde (1. realizace) a zde (2. realizace). Videoukázka druhé realizace je zde.

Literatura

[1] Atmel Corporation. Datasheet ATmega16. Atmel Corporation, 2006, www.atmel.com/literature.