Karel the Robot Implementation

Ciele

  1. 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)    East
alebo nasledovne:
POSITION = [1,2] - East
alebo ľ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

  1. 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.
  2. 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().
  3. Podobne, ako ste vytvorili funkcie (senzory) frontIsClear() a frontIsBlocked() vytvorte aj funkcie leftIsClear(), leftIsBlocked(), rightIsClear() a rightIsBlocked().
  4. Vytvorte funkcie (senzory) facingNorth(), notFacingNorth(), facingSouth(), notFacingSouth(), facingEast(), notFacingEast(), facingWest() a notFacingWest().
  5. 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.
  6. 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.
$Id$