Meeting Old Friend, Karel the Robot
Ciele
- Zopakovať si riadenie robota Karla prostredníctvom jednoduchých programov.
- Naučiť sa vytvárať nové funkcie v programovacom jazyku C.
- Naučiť sa vetviť tok programu na základe podmienok v programovacom jazyku C.
- 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:

- 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 -lcursesprič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.
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
-
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:
-
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.
-
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.
Ďalšie zdroje
- Robot Karel - stránka na wikipédii venovaná robotovi Karlovi
- Knižnica Karel the Robot (Hlavičkový súbor, Windows, Linux 32b, Linux 64b)
- PDCurses - verzia knižnice curses pre operačný systém Windows (pdcurses.lib, pdcurses.dll)
- Konfiguračný súbor pre editor Vim - .vimrc
- Rudolf Pecinovský: Základy algoritmizace - kapitola 6.1 a 11 (celá kapitola)
- Pavel Herout: Učebnice jazyka C (1. díl) - kapitoly 9.2 (úvod), 9.2.1, 9.2.2, 9.2.4, 9.2.5, kapitoly 5.1 a 5.4
$Id$