3. týždeň

Super Karel

Vlastné funkcie, dvojcestné vetvenie, logické cykly, nekončený cyklus

O čom je lab

Na tomto cvičení budete ďalej pracovať so super robotom Karlom. Vytvoríte pre Karla jednoduché programy, pomocou ktorých sa zoznámite s ďalšími príkazmi a senzormi robota. Vytvoríte tiež nekonečný cyklus.

Ciele

  1. Osvojiť si možnosti riadenia robota Karla prostredníctvom všetkých príkazov a senzorov.
  2. Rutinne používať vlastné funkcie, dvojcestné vetvenie a logické cykly.
  3. Zoznámiť sa s nekonečným cyklom.
  4. Rutinne pracovať s editorom ViM.

Postup

Krok 1: Setup

Úloha 1.1

Vytvorte adresár ~/labs/lab03.

Úloha 1.2

Do adresára ~/labs/lab03 skopírujte súbor potrebný k prekladu programu s robotom Karlom: Makefile.

Použiť môžete nasledujúce príkazy:

  • cp kopíruje súbory
  • cp -r kopíruje súbory a adresáre vrátane podadresárov
  • ls listuje obsah adresára
  • mkdir nazov vytvorí nový adresár
  • cd nazov zmení aktuálny adresár na iný (podadresár)
  • rm -r nazov maže všetko vrátane podadresárov

Upozornenie

Pomocou rm -r nazov je veľmi ľahké vymazať aj to, čo nechcete. Preto pri mazaní odporúčame najskôr zadať ls pre daný adresár, aby ste si dopredu overili, čo sa zmaže. V príkazovom riadku Kôš nenájdete.

Poznámka

Súbor Makefile nájdete v adresári z minulého cvičenia ~/labs/lab02. Nezabudnite, že je potrebné ho skopírovať do adresára ~/labs/lab03.

Krok 2: Eternal

V tomto kroku sa zoznámite s ďalšími príkazmi a senzormi robota Karla a vytvoríte nekonečnú slučku.

Úloha 2.1

Vytvorte program eternal.c, v ktorom bude Karel neustále prechádzať medzi dvoma protiľahlými stenami. Vaše riešenie otestujte na svete empty.kw.

Nekonečný cyklus je taký cyklus, v ktorom je podmienka vždy splnená. Spôsobov na riešenie tohto problému je niekoľko.

Pre zvýšenie Karlovej rýchlosti je možné použiť príkaz set_step_delay(). Platí, že čím nižšia je hodnota, tým vyššia je Karlova rýchlosť. Základná rýchlosť je set_step_delay(1000).

Úloha 2.2

Upravte program eternal tak, aby Karel neustále prechádzal zo severu na juh a opačne bez ohľadu na to, akým smerom je na začiatku otočený.

Na začiatku programu je potrebné robota otočiť smerom na sever. Použiť môžete senzor:

  • facing_north() Vráti hodnotu true, ak Karel smeruje na sever, inak vráti hodnotu false

Krok 3: Super Karel - Training

Robot Karel sa chce zúčastniť olympiády pre robotov (tzv. robolympiády). Jedna z disciplín, ktorej sa je možné v rámci olympiády zúčastniť, je prekážkový beh. Napíšte pre Karla program, pomocou ktorého zvládne zdolať rozcvičkovú prekážkovú trať training.kw. Keď to zvládne, stane sa z neho Super Karel.

Úloha 3.1

Vytvorte program training.c a stiahnite si mapu training.kw.

Úloha 3.2

Pre úspešné zvládnutie prekážkového behu vytvorte funkciu jump_over(), pomocou ktorej Karel preskočí práve jednu prekážku. Karel preskakuje ľubovoľný počet prekážok, kým nenarazí na značku vo svete.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+-----------------------+
 2 | .   .   .   .   .   . |
   |   |   |   |   |   |   |
 1 | > | . | . | . | 1 | . |
   +-----------------------+
     1   2   3   4   5   6   AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 1)   EAST       0         1
ST.+-----------------------+
 2 | .   .   .   .   .   . |
   |   |   |   |   |   |   |
 1 | . | . | . | . | > | . |
   +-----------------------+
     1   2   3   4   5   6   AVE.

Použite hlavičkový súbor superkarel.h, ktorý Vám umožní používať ďalšie senzory robota Karla:

  • no_beepers_present() Vráti hodnotu true, ak Karel stojí na pozícii bez značiek, a hodnotu false, ak sa tam nejaká značka nachádza
  • no_beepers_in_bag() Vráti hodnotu true, ak Karel nemá v batohu žiadnu značku, a hodnotu false, ak je neprázdny
  • front_is_blocked() Vráti hodnotu true, ak sa priamo pred Karlom nachádza stena, a hodnotu false, ak sa tam nenachádza
  • right_is_clear() Vráti hodnotu true, ak sa napravo od robota nenachádza žiadna stena, inak vráti hodnotu false
  • right_is_blocked() Vráti hodnotu true, ak sa napravo od robota nachádza stena, inak vráti hodnotu false
  • left_is_clear() Vráti hodnotu true, ak sa naľavo od robota nenachádza žiadna stena, inak vráti hodnotu false
  • left_is_blocked() Vráti hodnotu true, ak sa naľavo od robota nachádza stena, inak vráti hodnotu false
  • facing_east() Vráti hodnotu true, ak Karel smeruje na východ, inak vráti hodnotu false
  • not_facing_east() Vráti hodnotu true, ak Karel nesmeruje na východ, inak vráti hodnotu false
  • facing_west() Vráti hodnotu true, ak Karel smeruje na západ, inak vráti hodnotu false
  • not_facing_west() Vráti hodnotu true, ak Karel nesmeruje na západ, inak vráti hodnotu false
  • not_facing_north() Vráti hodnotu true, ak Karel nesmeruje na sever, inak vráti hodnotu false
  • facing_south() Vráti hodnotu true, ak Karel smeruje na juh, inak vráti hodnotu false
  • not_facing_south() Vráti hodnotu true, ak Karel nesmeruje na juh, inak vráti hodnotu false

Poznámka

Hlavičkový súbor superkarel.h je náhradou za karel.h, preto nie je potrebné používať obidva súčasne.

Poznámka

Namiesto -lkarel použite k prekladu prepínač -lsuperkarel.

Krok 4: Super Karel - Olympics

Karlove prípravy na RobOlympiádu vrcholia. V tomto kroku pomôžete Karlovi dotiahnuť prípravy a naučiť ho zdolať prekážky ľubovoľne od seba vzdialené aj ľubovoľne vysoké či široké prekážky.

Úloha 4.1

Vytvorte program olympics.c, ktorý bude kópiou programu training.c.

Použiť môžete príkaz:

cp training.c olympics.c

Úloha 4.2

Upravte program olympics tak, aby Karel zvládol prebehnúť cez prekážky, ktoré sú od seba ľubovoľne vzdialené. Karel svoj beh zastaví vtedy, keď nájde na značku. Riešenie overte na mape olympics.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 5 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 4 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 3 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 2 | .   .   .   .   .   .   .   .   .   . |
   |   |   |       |       |       |   |   |
 1 | > | . | .   . | .   . | 1   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (7, 1)   EAST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 5 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 4 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 3 | .   .   .   .   .   .   .   .   .   . |
   |                                       |
 2 | .   .   .   .   .   .   .   .   .   . |
   |   |   |       |       |       |   |   |
 1 | . | . | .   . | .   . | >   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Poznámka

Nezabudnite zmeniť mapu sveta vo funkcii turn_on().

Úloha 4.3

Upravte program olympics tak, aby Karel zvládol prebehnúť ľubovoľne vysoké prekážky. Riešenie overte na mapách olympics2.kw a olympics3.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |       |               |
 4 | .   .   .   . | .   . | .   .   .   . |
   |               |       |           |   |
 3 | .   .   .   . | .   . | .   .   . | . |
   |   |           |       |       |   |   |
 2 | . | .   .   . | .   . | .   . | . | . |
   |   |   |       |       |       |   |   |
 1 | > | . | .   . | .   1 | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (6, 1)   EAST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |       |               |
 4 | .   .   .   . | .   . | .   .   .   . |
   |               |       |           |   |
 3 | .   .   .   . | .   . | .   .   . | . |
   |   |           |       |       |   |   |
 2 | . | .   .   . | .   . | .   . | . | . |
   |   |   |       |       |       |   |   |
 1 | . | . | .   . | .   > | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Poznámka

Nezabudnite zmeniť mapu sveta vo funkcii turn_on().

Úloha 4.4

Upravte program olympics tak, aby Karel zvládol prebehnúť ľubovoľne široké prekážky. Riešenie overte na mapách olympics4.kw a olympics5.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST      10         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |       +-------+       |
 4 | .   .   .   . | .   . | .   . | .   . |
   |               |       |       |   |   |
 3 | .   .   .   . | .   . | .   . | . | . |
   |   +---+       |       |       |   |   |
 2 | . | . | .   . | .   . | .   . | . | . |
   |   |   |       |       |       |   |   |
 1 | > | . | .   . | .   . | .   . | 1 | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (9, 1)   EAST      10         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |               |                       |
 5 | .   .   .   . | .   .   .   .   .   . |
   |               |       +-------+       |
 4 | .   .   .   . | .   . | .   . | .   . |
   |               |       |       |   |   |
 3 | .   .   .   . | .   . | .   . | . | . |
   |   +---+       |       |       |   |   |
 2 | . | . | .   . | .   . | .   . | . | . |
   |   |   |       |       |       |   |   |
 1 | . | . | .   . | .   . | .   . | > | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Poznámka

Nezabudnite zmeniť mapu sveta vo funkcii turn_on().

Doplňujúce úlohy

Úloha A.1

Upravte program olympics tak, aby Karel skákal cez prekážky v smere zľava doprava, ak je na začiatku otočený smerom na východ a v smere sprava doľava, ak je na začiatku otočený smerom na západ. Riešenie overte na mape olympics6.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (10, 1)   WEST       0         0
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                   |                   |
 5 | .   .   .   .   . | .   .   .   .   . |
   |                   |   +-------+       |
 4 | .   .   .   .   . | . | .   . | .   . |
   |                   |   |       |       |
 3 | .   .   .   .   . | . | .   . | .   . |
   |   +-----------+   |   |       |   |   |
 2 | . | .   .   . | . | . | .   . | . | . |
   |   |           |   |   |       |   |   |
 1 | . | .   .   . | 1 | . | .   . | . | < |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 1)   WEST       0         1
ST.+---------------------------------------+
 6 | .   .   .   .   .   .   .   .   .   . |
   |                   |                   |
 5 | .   .   .   .   . | .   .   .   .   . |
   |                   |   +-------+       |
 4 | .   .   .   .   . | . | .   . | .   . |
   |                   |   |       |       |
 3 | .   .   .   .   . | . | .   . | .   . |
   |   +-----------+   |   |       |   |   |
 2 | . | .   .   . | . | . | .   . | . | . |
   |   |           |   |   |       |   |   |
 1 | . | .   .   . | < | . | .   . | . | . |
   +---------------------------------------+
     1   2   3   4   5   6   7   8   9   10  AVE.

Úloha A.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. Vytvorte program road tak, aby Karel vyplnil značkou každú dieru, ktorá ešte nie je vyplnená. Cesty, ktoré má Karel vyplniť, sa nachádzajú v súboroch road.kw a road2.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 2)   EAST       2         0
ST.+-------------------+
 2 | >   .   .   .   . |
   |---+   +---+   +---|
 1 | . | 1 | . | . | . |
   +-------------------+
     1   2   3   4   5   AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (5, 2)   EAST       1         0
ST.+-------------------+
 2 | .   .   .   .   > |
   |---+   +---+   +---|
 1 | . | 1 | . | 1 | . |
   +-------------------+
     1   2   3   4   5   AVE.

Úloha A.3

Vytvorte program stairsbuilder, pomocou ktorého Karel postaví schodisko. Na začiatku sa pred Karlom nachádza stĺpik postavený zo značiek, ktorých počet je väčší ako 1. Úlohou Karla je postaviť vpravo od tohto stĺpika schody reprezentované z ďalších značiek, pričom na každej pozícii bude vždy o jednu značku menej ako na predchádzajúcej. Karel má na začiatku dostatočný počet značiek, aby túto úlohu úspešne zvládol a vpravo od stĺpika je vždy dostatok miesta pre vytvorenie schodiska. Po vytvorení schodiska sa Karel bude nachádzať na jeho najvyššom stupni. Vaše riešenie overte na mapách stairsbuilder.kw a stairsbuilder2.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 3)   NORTH     99         0
ST.+---------------------------+
 6 | .   .   .   .   .   .   . |
   |                           |
 5 | .   .   .   .   .   .   . |
   |                           |
 4 | 5   .   .   .   .   .   . |
   |                           |
 3 | ^   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 4)    WEST     89         5
ST.+---------------------------+
 6 | .   .   .   .   .   .   . |
   |                           |
 5 | .   .   .   .   .   .   . |
   |                           |
 4 | <   4   3   2   1   .   . |
   |                           |
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Poznámka

Podstatou tejto úlohy je precvičiť si algoritmické myslenie. Daný problém by ste preto nemali riešiť pomocou premenných (ak premenné už poznáte).

Úloha A.4

V spodnej rade Karlovho sveta sú ľubovoľne rozložené značky. Karel stojí na začiatku tejto rady (je doma). Vytvorte program mirror, pomocou ktorého v rade nad tou aktuálnou robot Karel vytvorí jej zrkadlový obraz. Napr. ak bude v pôvodnej rade značka (alebo značky) na ľavej krajnej pozícii, vo výslednej rade bude (budú) na pravej krajnej pozícii. Platí, že v spodnej rade Karlovho sveta sa na každej pozícii nachádza aspoň jedna značka. Vaše riešenie overte na mapách mirror.kw a mirror2.kw.

Počiatočná situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 1)   EAST       0         1
ST.+---------------------------+
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | .   .   .   .   .   .   . |
   |                           |
 1 | >   2   3   4   5   6   7 |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Koncová situácia

 CORNER  FACING  BEEP-BAG  BEEP-CORNER
 (1, 2)   WEST       0         7
ST.+---------------------------+
 3 | .   .   .   .   .   .   . |
   |                           |
 2 | <   6   5   4   3   2   1 |
   |                           |
 1 | .   .   .   .   .   .   . |
   +---------------------------+
     1   2   3   4   5   6   7   AVE.

Poznámka

Podstatou tejto úlohy je precvičiť si algoritmické myslenie. Daný problém by ste preto nemali riešiť pomocou premenných (ak premenné už poznáte).

Úloha A.5

Programátorská práca pozostáva z nekonečného cyklu editovania zdrojového kódu a jeho prekladu. Každý program si vyžaduje osobitné pravidlá pre jeho zostavenie. Je nepraktické príkaz na zostavenie stále opakovať dookola. Opakované zostavenie programu rieši systém make, ktorý vie rozhodnúť, ktoré pravidlá na preklad je potrebné aplikovať. Napíšte si vlastné pravidlá na zostavenie programov do súboru Makefile.

Vytvorte súbor Makefile:

vim Makefile

Napíšte do súboru (prepnite sa do vkladacieho módu pomocou i):

eternal: eternal.c
	gcc -std=c11 -Wall -Werror eternal.c -lkarel -lcurses -o eternal

Upozornenie

Prvý znak musí byť TAB (nie medzery). Inak bude systém make vypisovať zmätočné hlášky.

Poznámka

Niektoré editory bez upozornenia namiesto TAB vkladajú 4 medzery, čo je ťažko zistiteľné. ViM by mal automaticky zistiť, že ide o Makefile a vyhnúť sa tejto situácii. ViM môžete prinútiť, aby stlačením TAB naozaj vkladal TAB príkazom :set noexpandtab. Všetky 4 medzery na začiatku riadku v súbore môžete nahradiť príkazom:

:%s/^    /\t/g

Význam riadkov 1-2 v Makefile je nasledovný:

  • Prvý riadok je názov pravidla. Časť pred dvojbodkou je názov dôsledku (súbor, ktorý sa má vytvoriť).
  • Časť za dvojbodkou je predpoklad (súbor, z ktorého budete čerpať).
  • Druhý riadok je telo pravidla a opisuje, ako z predpokladu urobiť dôsledok.

Význam jednotlivých parametrov prekladu je nasledovný:

  • -std=c11 Budeme používať verziu jazyka C z roku 2011
  • -Wall Zaujímať nás budú všetky upozornenia (warning), pretože nechceme, aby ste písali "len" kód, ktorý funugje, ale aby ste písali "dobrý kód" a prekladač Vás na nič špeciálne nemusel upozorňovať (program vie fungovať aj napriek tomu, že Vás prekladač niekoľkokrát upozornil)
  • -Werror Aby ste tieto upozornenia neignorovali, táto voľba ich všetky zmení na chyby, čím nedôjde ku vytvoreniu výsledného spustiteľného programu
  • eternal.c Názov súboru, ktorý má byť preložený
  • -o eternal Názov spustiteľného výsledného súboru, ktorý vznikne prekladom (nemusí mať príponu .exe)

Poznámka

Do Makefile pridajte pravidlá aj pre ostatné programy training.c a olympics.c. Ich preklad prebehne pomocou príkazov make training a make olympics.

Poznámka

Na kopírovanie riadkov v editore ViM viete využiť riadkový označovací mód (Ctrl+Shift+V). Riadky označíte, skopírujete pomocou y a vložíte pomocou p. Ak sa Vám vloženie nepodarilo na prvý pokus, zmenu vrátite pomocou u.

Poznámka

Editor ViM Vám umožňuje urýchlenie cyklu hľadania chyby a zostavenia. Program sa dá preložiť priamo z prostredia ViM a pri chybe skočí rovno na postihnutý riadok.

Doplňujúce zdroje

  1. Karel Language Reference
  2. Tu nájdete knižnicu robota Karla, vrátane návodu na inštaláciu knižnice.
  3. Rudolf Pecinovský: Základy algoritmizace - kapitola 10
  4. Pavel Herout: Učebnice jazyka C (1. díl) - kapitola 5.1, 5.4, 5.5
  5. Hlavičkový súbor robota Karla karel.h
  6. Hlavičkový súbor super robota Karla superkarel.h
  7. Súbor pre preklad Karlovho programu Makefile
  8. Súbor pre preklad super Karlovho programu Makefile-superkarel
  9. GNU Make Tutorial
  10. Náš VIM tutoriál
  11. ViM Quick Reference Card (.pdf)
  12. Tomášov konfigurák pre ViM
  13. Danielov konfigurák pre ViM

Video