Karel the Robot Implementation
Ciele
- Naučiť sa vytvárať funkcie, ktoré vracajú hodnoty.
Úvod
Na tomto cvičení vytvoríte funkcie movek() a turnLeft(), ktoré predstavujú základné primitívy pre robota Karla. Okrem nich vytvoríte taktiež senzory frontIsBlocked() a frontIsClear().
Postup
Krok č. 1
V prvom kroku vytvoríte niekoľko premenných, pomocou ktorých budete
vedieť opísať Karlov aktuálny stav. Jedná sa o polohu a orientáciu
robota Karla. Taktiež upravíte funkciu draw(),
aby ste vedeli robota Karla správne vykresliť vzhľadom na jeho
stav.
Úloha 1.1:
Vytvorte premenné karel_x a
karel_y, ktoré budú reprezentovať x-ovú a
y-ovú súradnicu umiestnenia robota Karla.
Úloha 1.2:
Vytvorte premennú karel_direction, ktorá
bude reprezentovať orientáciu, resp. smer robota Karla.
Táto premenná môže nadobúdať iba nasledovné hodnoty:
- 0 - východ
- 90 - sever
- 180 - západ
- 270 - juh
Úloha 1.3:
Aktualizujte funkciu turnOn() tak, aby na základe
hodnôt v premennej map správne rozpoznala
pozíciu a smer robota Karla a nastavila podľa nich premenné
karel_x, karel_y a
karel_direction.
Úloha 1.4:
Upravte funkciu draw() tak, aby pri vykresľovaní
sveta vykreslila na správnu pozíciu aj robota Karla.
Pre vykreslenie aktuálnej polohy robota Karla na obrazovku vzhľadom
na jeho orientáciu, použite nasledujúce znaky:
- '>' - Karel je orientovaný na východ
- '^' - Karel je orientovaný na sever
- '<' - Karel je orientovaný na západ
- 'v' - Karel je orientovaný na juh
Úloha 1.5:
Rozšírte funkciu draw() o stavový riadok,
v ktorom vypíšete informáciu o aktuálnej pozícii a orientácii
robota Karla.
Stavový riadok môže vyzerať napr. nasledovne:
CORNER FACING (1, 2) Eastalebo nasledovne:
POSITION = [1,2] - Eastalebo ľubovoľne inak.
Úloha 1.6:
Overte si správnosť svojej implementácie.
Svoju implementáciu si môžete overiť na nasledujúcom svete:
char* map = "########|#--#---#|#---*--#|#--#**-#|##-#---#|#---*#-#|#----->#|########";Výsledný svet spolu so stavovým riadkom bude potom vyzerať nasledovne:
CORNER FACING (6,1) East ######## # # # # # # # # ## # # # # # # ># ########
Poznámka:
Pri reprezentácii sveta a robota Karla v ňom si dajte pozor na to,
s akým počiatkom súradnicového systému budete pracovať. Pri reprezentácii
sveta uloženého v premennej map dochádza ku
jeho vykresľovaniu postupne po riadkoch v smere zhora nadol. To
teda znamená, že bod (0,0) je prvým znakom nachádzajúcim sa v
premennej map (teda map[0]).
V uvedenom príklade by to teda znamenalo, že karel sa v skutočnosti
nachádza na pozícii (6,6). Pre nás ľudí je však prirodzenejšie
pozerať sa na počiatok súradnicového systému do ľavého dolného
rohu. Preto pozíciu robota Karla budeme uvádzať vzhľadom na tento
bod.
Krok č. 2
V tomto kroku implementujete funkciu turnLeft(),
pomocou ktorej budete môcť robota Karla otočiť o 90 stupňov vľavo.
Úloha 2.1:
Vytvorte funciu turnLeft(), pomocou ktorej
otočíte Karla o 90 stupňov vľavo. Po otočení Karla rovno vykreslite
zavolaním funkcie draw().
Pri otáčaní nezabudnite, že hodnoty Karlovej orientácie môžu byť len
0, 90, 180 a
270. Výsledok niektorých otočení preto bude potrebné
upraviť.
Úloha 2.2:
Overte si správnosť svojej implementácie.
Svoje riešenie si môžete overiť umiestnením robota Karla na ľubovoľné
miesto na mape a jeho postupným otáčaním okolo svojej vlastnej osi.
Overte taktiež, či sa Karel bude otáčať správnym smerom aj vtedy, ak
sa budete otáčať okolo svojej osi viackrát.
Poznámka:
Pri opätovnom vykresľovaní sveta na obrazovku nedochádza k jeho
prekresleniu, ale k vykresleniu scény nanovo pod predchádzajúcu scénu.
Toto môže byť dosť mätúce najmä v prípade, ak máte malú mapu a
veľkú obrazovku textovej konzoly, kde sa vám vojde niekoľko za
sebou vykreslených krokov. Pre odstránenie tohto problému je
možné napr.:
- vytvoriť vlastnú funkciu, ktorá vypíše na obrazovku dostatočný počet prázdnych riadkov, čím vznikne dojem jej vyčistenia; alebo
- zavolať funkciu system(), ktorá umožňuje spustiť príkaz z príkazového riadku (na zmazanie obrazovky je možné použiť príkaz cmd /c cls v operačnom systéme Windows a clear v operačnom systéme Linux).
- použiť na to určenú funkciu určitej špecifickej knižnice (napr. funkciu clear() knižnice curses.h)
Krok č. 3
V tomto kroku implementujete dva nové senzory pre robota Karla,
a to
frontIsClear() a
frontIsBlocked(). Tieto senzory budete môcť
neskôr použiť pre overenie karlovho pohybu - či sa môže presunúť
na danú pozíciu alebo nie.
Úloha 3.1:
Vytvorte funkciu frontIsClear(), ktorá vráti
hodnotu 1 (true), ak sa Karel
môže posunúť vpred. V opačnom prípade vráti hodnotu 0
(false).
Pri vytváraní funkcie dajte pozor na to, aby ste vedeli rozhodnúť vždy
správne vzhľadom na orientáciu robota Karla. Senzor vráti hodnotu
0 (false) vtedy, ak je pred Karlom
umiestnená stena alebo sa pred Karlom nachádza hranica sveta. V
opačnom prípade vráti senzor hodnotu 1
(true).
Úloha 3.2:
Vytvorte senzor frontIsBlocked(), ktorý
bude opakom senzora frontIsClear().
Senzor bude vracať hodnotu 1 (true),
ak sa Karel nemôže posunúť vpred. Ináč bude vracať hodnotu
0 (false).
Úloha 3.3:
Overte si správnosť svojej implementácie.
Pre overenie správnosti implementácie začnite Karla postupne otáčať vľavo,
až kým sa nedostanete do východzej polohy. Pri každom otočení si nechajte
zobraziť výsledok senzorov frontIsClear()
a frontIsBlocked().
Krok č. 4
V tomto kroku implementujete funkciu movek(),
pomocou ktorej budete vedieť robota Karla posunúť o jeden krok
vpred.
Úloha 4.1:
Vytvorte funkciu movek(), ktorá posunie robota
Karla o jeden krok vpred v prípade, že sa pred Karlom nenachádza
žiadna stena alebo sa Karel nenachádza na okraji sveta.
Pre zistenie, či sa Karel môže alebo nemôže posunúť vpred, môžete s
výhodou použiť vytvorený senzor frontIsClear(),
resp. jeho variáciu frontIsBlocked().
Po úspešnom posunutí robota Karla ho rovno vykreslite zavolaním funkcie
draw().
Ak sa Karel na danú pozíciu nemôže presunúť, vypíšte na obrazovku
vhodnú správu a ukončite beh programu zavolaním funkcie
exit(). Funkcia exit() pri svojom volaní požaduje parameter, ktorý reprezentuje tzv. exit status programu. Pre lepšiu prenositeľnosť kódu používajte nasledujúce hodnoty (makrá):
- EXIT_SUCCESS - toto makro použite vtedy, ak sa program ukončil úspešne (hodnota 0).
- EXIT_FAILURE - toto makro použite vtedy, ak sa program ukončil neúspešne (hodnota 1).
Poznámka:
Aby nedochádzalo k okamžitému vykresleniu robota Karla pri jeho
posúvaní, môžete ho spomaliť zavolaním funkcie
- usleep() v operačnom systéme Unix/Linux, pričom jej deklarácia sa nachádza v hlavičkovom súbore unistd.h a jej parametrom je počet mikrosekúnd, alebo
- Sleep() v operačnom systéme Windows, pričom jej deklarácia sa nachádza v hlavičkovom súbore windows.h a jej parametrom je počet milisekúnd.
Úloha 4.2:
Overte si správnosť svojej implementácie .
Pre overenie implementácie môžete použiť vybrané úlohy z predchádzajúcich
cvičení. Musíte si však vytvoriť vlastné mapy svetov, pretože syntax
máp pre vašu súčasnú implementáciu je rozdielna, ako ste používali
počas prvých cvičení.
Doplňujúce úlohy
- Vytvorte počítadlo vykonaných krokov robota Karla. Za krok sa bude považovať len volanie funkcií movek() a turnLeft(). Počet krokov sa vypíše vždy spolu so zobrazením mapy (pri volaní funkcie draw()) v stavovom riadku.
- Upravte zobrazenie počtu vykonaných krokov robota Karla tak, aby sa okrem informácie o počte krokov zobrazil aj názov posledne vykonaného kroku. Zobrazujte názvy iba týchto príkazov: movek(), turnLeft() a turnOn().
- Podobne, ako ste vytvorili funkcie (senzory) frontIsClear() a frontIsBlocked() vytvorte aj funkcie leftIsClear(), leftIsBlocked(), rightIsClear() a rightIsBlocked().
- Vytvorte funkcie (senzory) facingNorth(), notFacingNorth(), facingSouth(), notFacingSouth(), facingEast(), notFacingEast(), facingWest() a notFacingWest().
- Upravte svoju implementáciu funkcie turnOn() tak, aby vedela rozpoznávať aj znak '@' ako pozíciu robota Karla. Tým sa stane formát mapy kompatibilný so Sokoban formátom. Predvolený smer pre takto zadaného Karla nech je sever.
-
Pridajte do Vášho riešenia komentáre a vygenerujte k nemu dokumentáciu
vo formáte html prostredníctvom nástroja Doxygen.
Poznámka: Základné informácie k nástroju Doxygen nájdete na jeho webovej stránke, v pokynoch k vypracovaniu zadania č. 1 a v referenčnej príručke na stránkach predmetu Programovanie.
Ďalšie zdroje
- Rudolf Pecinovský: Základy algoritmizace
- Pavel Herout: Učebnice jazyka C (1. díl) - 5.6, 9.2, 12
$Id$