Meeting Old Friend, Karel the Robot

Ciele

  1. Zopakovať si riadenie robota Karla prostredníctvom jednoduchých programov.
  2. Naučiť sa vytvárať nové funkcie v programovacom jazyku C.
  3. Naučiť sa vetviť tok programu na základe podmienok v programovacom jazyku C.
  4. Naučiť sa preložiť a spustiť vytvorený program v prostredí operačného systému Linux.

Úvod

Na tomto cvičení si pripomeniete svet robota Karla a zopakujete si, ako ovládať Karla príkazmi, ktorým rozumie od výroby. Zopakujete si, ako vytvárať nové príkazy (vlastné funkcie), pomocou ktorých rozšírite Karlove schopnosti a zjednodušíte si svoju prácu pri písaní programov. Taktiež naučíte robota Karla rozhodovať sa vo svojich programoch na základe senzorov, ktoré obsahuje.

Postup

Krok č. 1

V tomto kroku si zopakujete prácu s robotom Karlom a svetom, v ktorom sa nachádza, s využitím vlastných funkcií. Následne sa naučíte, ako program v jazyku C preložiť a spustiť v prostredí operačného systému Linux.

Úloha 1.1:

Prihláste sa na server omega.tuke.sk so svojimi prihlasovacími údajmi.

Úloha 1.2:

Vo svojom domovskom priečinku si vytvorte priečinok s názvom Karel, do ktorého budete ukladať svoje kódy programov pre robota Karla.

Úloha 1.3:

Stiahnite si súbor sveta empty.kw, do ktorého Karla umiestníte, a v ktorom bude problém riešiť.
Pre stiahnutie súboru z internetu môžete využiť nástroj wget v tvare:
                    $ wget http://www.server.sk/cesta/k/vasmu/suboru
                    

Úloha 1.4:

Pomocou textového editora (napr. Vim, mcedit alebo joe) vytvorte súbor marker.c a vložte do neho tieto riadky, ktoré budú predstavovať kostru programu:
                    #include <karel.h>
                    
                    int main(){
                        
                        return 0;
                    }

Úloha 1.5:

Vytvorte program, pomocou ktorého Karel označkuje všetky štyri rohy sveta. Karel sa na začiatku nachádza na pozícii [1,1] a je nasmerovaný na východ. Po označení všetkých rohov sa vráti na svoju východziu pozíciu.
Počiatočná situácia:
Koncová situácia:
Pri riešení tejto úlohy využite tieto Karlove príkazy, ktoré už poznáte z predmetu Úvod do programovania a sietí:
  • movek() - Presunie Karla o jednu pozíciu vpred vzhľadom na smer, ktorým je Karel otočený. Pokiaľ sa Karel pokúsi pohnúť smerom, ktorým nemôže (v ceste stojí prekážka alebo sa nachádza na okraji sveta), program sa zastaví.
  • putBeeper() - Pokiaľ má Karel vo svojom batohu značku, položí ju na pozíciu, na ktorej sa aktuálne nachádza.
  • turnLeft() - Po zadaní tohto príkazu sa Karel otočí na mieste o 90 stupňov vľavo.
  • turnOn() - Príkaz, ktorý Karla zapne. Príkaz má jeden povinný parameter, ktorým je umiestnenie sveta, v ktorom Karel bude riešiť svoju úlohu. Príklad zapnutia Karla a jeho umiestnenia do sveta nachádzajúceho sa v súbore empty.kw môže teda vyzerať nasledovne:
                                    turnOn( "empty.kw" );
                                
  • turnOff() - Po vykonaní všetkých úloh tento príkaz zabezpečí korektné ukončenie Karlovej úlohy.
Poznámka:  Korektné ukončenie Karla zabezpečuje funkcia turnOff(). Ak sa Karel neukončí korektne, zadajte príkaz reset.

Úloha 1.6:

Preložte vytvorený program pomocou prekladača gcc. V prípade, že prekladač objaví chyby, opravte ich.
Program preložíte nasledovne:
                    $ gcc marker.c -o karel -lkarel -lcurses
                    
pričom:
  • súbor marker.c predstavuje vami vytvorený program pre Karla,
  • prepínač -o zabezpečí, aby sa výsledný súbor, ktorý bude reprezentovať spustiteľný program, volal karel,
  • voľba -lkarel zabezpečí, aby bola pri preklade použitá knižnica pre prácu s robotom Karlom, a
  • voľba -lcurses zabezpečí, aby bola pri preklade použitá aj knižnica ncurses pre vykresľovanie sveta, v ktorom sa Karel bude nachádzať.
Poznámka:  Pokiaľ by ste pri preklade nepoužili prepínač -o, výsledný spustiteľný program by sa nachádzal v súbore a.out.
Poznámka:  Znak $ nie je súčasťou príkazu, ale symbolizuje len použitie príkazového riadku. Pri zadávaní (alebo kopírovaní) uvedeného príkazu ho preto vynechajte.
Poznámka:  Ak chcete programovať na vlastnom počítači s nainštalovaným operačným systémom Linux, potrebujete mať nainštalovaný balíček libncurses5-dev.

Úloha 1.7:

Spustite preložený program.
Pokiaľ ste spustili prekladač s parametrom -o karel, program spustíte nasledovne:
$ ./karel

Úloha 1.8:

V programe marker.c vytvorte funkciu runMile(), po zavolaní ktorej sa Karel prejde o 5 krokov vpred.

Úloha 1.9:

Upravte hlavnú funkciu programu main() tak, aby ste v nej využili volanie vytvorenej funkcie runMile().

Úloha 1.10:

Overte, ako sa Karel správa v prípadoch, keď chce prejsť cez stenu, keď sa pokúsi položiť značku a v batohu nemá žiadnu, a keď sa pokúsi vziať značku z rohu, na ktorom sa žiadna značka nenachádza.

Úloha 1.11:

Upravte program tak, aby Karel počas značkovania rohov sveta neznačkoval aj tie rohy, ktoré už sú označené.
Pre úspešné vyriešenie tejto úlohy využite nasledovné Karlove senzory:
  • beepersPresent() - Vracia hodnotu 1, ak Karel stojí na rohu, na ktorom sa nachádza značka. V opačnom prípade vracia hodnotu 0.
  • noBeepersPresent() - Vracia hodnotu 1, ak Karel stojí na rohu, na ktorom sa nenachádza značka. V opačnom prípade vracia hodnotu 0.
Svoje riešenie tejto úlohy môžete otestovať na svete empty1.kw.

Krok č. 2

Cesta vedúca do areálu Technickej univerzity je za tie roky značne poškodená a vyznačuje sa väčším (občas aj menším) počtom dier v nej. Naprogramujte preto robota Karla tak, aby každú dieru, ktorú v ceste nájde, vyplnil značkou.

Úloha 2.1:

Vytvorte analýzu uvedeného problému. Pokúste sa celý problém rozdeliť na čo najmenšie funkčné celky (funkcie).

Úloha 2.2:

Na základe analýzy vytvorte požadované funkcie, pomocou ktorých úlohu vyriešite. Cesta, ktorú má Karel vyplniť, sa nachádza v súbore road.kw. Karel sa na začiatku nachádza na počiatočnej pozícii [1,2] a po zaplnení všetkých dier sa bude nachádzať na pozícii [5,2].
Počiatočná situácia:
Koncová situácia:

Úloha 2.3:

Upravte program tak, aby Karel počas plátania dier na ceste vedúcej do areálu Technickej univerzity nevypĺňal aj tie diery, ktoré už sú vyplnené. Svoje riešenie tejto úlohy môžete otestovať na svete road1.kw.

Doplňujúce úlohy

  1. V tejto úlohe pomôžete Karlovi zúčastniť sa a uspieť v olympiáde pre robotov. Jednou z disciplín, ktorej sa je možné v rámci olympiády zúčastniť, je prekážkový beh. Napíšte preto pre Karla program, pomocou ktorého zvládne zdolať akúkoľvek prekážkovú trať, ktorú organizátori pre účastníkov olympiády pripravia. Zároveň program upravte tak, aby sa Karel zastavil, keď nájde značku. Karel bude vždy štartovať z pozície [1,1]. Tréningové prekážkové dráhy si môžete prevziať zo súborov training.kw a olympics.kw.
    Počiatočná situácia:
    Koncová situácia:
  2. Vytvorte pre Karla program, pomocou ktorého mu pomôžete vyšplhať sa po schodoch nahor, až na najvyššie poschodie. Cestou pomôžte Karlovi pozbierať všetky značky, ktoré na schodoch nájde. Pre riešenie tejto úlohy si stiahnite svet stairs.kw.
    Počiatočná situácia:
    Koncová situácia:

    Pre úspešné vyriešenie tejto úlohy využite nasledovnú funkciu:

    • pickBeeper() - Pokiaľ Karel stojí na pozícii, na ktorej sa nachádza značka, Karel ho zodvihne a vloží do svojho batohu.

    Výhodná je implementácia nasledujúcich funkcií, ktoré budú volané z hlavnej funkcie main():

    • turnRight() - Zabezpečí otočenie robota Karla o 90 stupňov vpravo, pričom dôjde k okamžitému vykonaniu otočenia Karla vpravo.
      Poznámka:  Ak nastavíte dĺžku vykonávania Karlovho kroku na hodnotu 0, dôjde k okamžitému vykonaniu otočenia Karla vpravo. Počet krokov sa však aj napriek tomu zvýši o 3. Po otočení však nezabudnite nastaviť dĺžku vykonávania kroku na pôvodnú hodnotu 1000. Uvedenú zmenu dĺžky vykonania Karlovho kroku nastavíte pomocou volania funkcie setStepDelay().
    • climbStair() - Funkcia, pomocou ktorej Karel vystúpi o jeden schod vyššie.
  3. Pokúste sa upraviť program marker.c z prvého kroku tak, aby robot Karel vedel označkovať rohy ľubovoľne veľkého sveta. Svoje riešenie tejto úlohy si môžete otestovať na svetoch empty2.kw a empty3.kw.
    Poznámka:  Riešenie tejto úlohy je vhodné pre prípravu na nasledujúce cvičenie.
$Id$