O čom je lab
V rámci tohto cvičenia budete pokračovať v programovaní zjednodušenej verzie hry IQ Marathon.
Ciele
- Osvojiť si prácu so súbormi.
- Rutinne pracovať s parametrami funkcií.
- Rutinne pracovať s reťazcami.
- Rutinne pracovať s viacrozmernými poliami.
- Rutinne pracovať s ternárnym operátorom.
Postup
Krok 1: Part II.
Vašou úlohou je načítať hracie pole zo súboru a umiestniť do neho šípky <, v, > a ^ tak, aby sa krava mohla dostať do cieľovej pozície. Pritom spočítate, koľko krát zmení krava smer, kým sa dostane do cieľovej pozície.
Úloha 1.1
V programe iq_marathon.c
vytvorte funkciu int solve_maze(const int height, const int width, char world[][width+1])
, ktorá vyrieši hru a vráti počet zmien smeru. Samotné správanie funkcie naprogramujeme v nasledujúcich úlohách.
Logika našej verzie hry bude nasledovná: Krava pôjde vždy rovno, až kým nenarazí na stenu (znak X). Potom zmení smer. V prípade, že je aktuálny smer kravy horizontálny (W alebo E), nový smer bude vertikálny (S alebo N) podľa toho, kde sa nachádza cieľová pozícia. Naopak, ak je aktuálny smer kravy vertikálny (S alebo N), nový smer bude horizontálny (W alebo E) podľa toho, kde sa nachádza cieľová pozícia.
Úloha 1.2
Do funkcie solve_maze()
pridajte volanie funkcií find_cow()
a find_finish()
tak, aby ste si mohli uchovať smer kravy, súradnice kravy a súradnice cieľovej pozície.
- Pozície uchovajte v samostatných premenných, napr.
int x, y
pre počiatočnú pozíciu aint finish_x, finish_y
pre koncovú pozíciu. - S počiatočnou pozíciou je dôležité uložiť aj smer kravy, napr. do premennej
char direction
.
Úloha 1.3
Do funkcie solve_maze()
pridajte cyklus, pomocou ktorého uskutočníte postupný prechod kravy hracím poľom do cieľovej pozície. Funkcia do hracieho poľa vyznačí, kedy došlo k zmene smeru a nakoniec vráti počet zmien smeru.
- Krava pôjde vždy rovno v danom smere, kým nenarazí na stenu (znak X). Potom zmení smer o 90 stupňov podľa toho, kde sa nachádza cieľová pozícia, a uloží do poľa znak <, v, > resp. ^.
- Hra nemá riešenie, ak po zmene smeru krava opäť (ihneď) narazí na stenu.
Úloha 1.4
Príklad hry pre súbor maze2:
$ ./iq_marathon Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X X X X X X X X X XX X X X X XXXXXXXXXXXXX X N X XX X X X X X XXXXXX XX X X X X X X X X XX X X X X X XXXX X X X X X X X XXXXXXXXXX X X X X XX X XX X X X X X X X X F X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX After: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X X X X X X X X X XX X X X > vX XXXXXXXXXXXXX X N X XX X X X X X XXXXXX XX X X X X X X X X XX X X X X X XXXX X X X X X X X XXXXXXXXXX X X X X XX > vX XX X X X X X X X X F < X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Number of direction changes: 5
Príklad hry pre súbor maze1:
$ ./iq_marathon Before: XXXXXXXXXX X F X X XXXXX X X E X XXXXXXXXXX No solution here.
Krok 2: Command Line Arguments
Vašou úlohou je upraviť riešenie tak, aby bolo možné zadať názov súboru s hrou už pri spustení programu (ako argument príkazového riadku).
Úloha 2.1
Do deklarácie hlavnej funkcie main()
pridajte parametre, pomocou ktorých bude možné pracovať s argumentami príkazového riadku.
Úloha 2.2
Upravte hlavnú funkciu main()
tak, aby program pracoval so súborom, ktorého názov bol zadaný ako argument príkazového riadku.
Úloha 2.3
Upravte program tak, aby sa ukončil, ak používateľ nezadá názov súboru.
Príklad použitia programu môže byť nasledovný:
$ ./iq_marathon Error: Too few arguments $ ./iq_marathon maze1 Before: XXXXXXXXXX X F X X XXXXX X X E X XXXXXXXXXX No solution here! $ ./iq_marathon maze2 Before: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X X X X X X X X X XX X X X X XXXXXXXXXXXXX X N X XX X X X X X XXXXXX XX X X X X X X X X XX X X X X X XXXX X X X X X X X XXXXXXXXXX X X X X XX X XX X X X X X X X X F X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX After: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X XX X X X X X X X X X X X XX X X X > vX XXXXXXXXXXXXX X N X XX X X X X X XXXXXX XX X X X X X X X X XX X X X X X XXXX X X X X X X X XXXXXXXXXX X X X X XX > vX XX X X X X X X X X F < X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Number of direction changes: 5
Doplňujúce úlohy
Úloha A.1
Nami implementovaný algoritmus nedokáže vždy vyriešiť hru napriek tomu, že hra riešenie má. Dôvodom je fakt, že k zmene smeru dochádza iba pri náraze na stenu. Upravte (vylepšite) algoritmus tak, aby dokázal vyriešiť aj iné situácie. Použiť môžete napr. algoritmus vyhľadávania do šírky: Depth first search. Riešenie overte na súbore maze4.
Úloha A.2
Vytvorte modifikáciu tejto hry pre robota Karla. Úlohou Karla bude nájsť vo svete poklad. Karel ide vždy rovno. Ak je na pozícii počet značiek 1, Karel sa otočí na sever a opäť ide rovno. Ak je na pozícii počet značiek 2, Karel sa otočí na západ a opäť ide rovno. Ak je na pozícii počet značiek 3, Karel sa otočí na juh a opäť ide rovno. Ak je na pozícii počet značiek 4, Karel sa otočí na východ a opäť ide rovno. Ak je na pozícii počet značiek 5, znamená to, že Karel našiel poklad a hra končí.
Na začiatku programu svet obsahuje steny a pozíciu, na ktorej sa nachádza poklad (počet značiek 5). Do tohto sveta je najskôr potrebné vložiť značky tak, aby Karel postupne menil smer, a tak sa dostal k pokladu. Tento svet Karel načíta a podľa toho sa dostane do cieľovej pozície. Karel vie ísť iba rovno a keď nájde značky, otočí sa v danom smere. Značky pritom pozbiera (pozícia ostane prázdna).
Vaše riešenie overte na mapách treasuremap1.kw a treasuremap2.kw.
Doplňujúce zdroje
- Ternárny operátor
- Funkcia
fopen()
: c-reference, cplusplus.com - Opens a file and returns a file stream associated with that file. - Funkcia
fclose()
: c-reference, cplusplus.com - Closes the given file stream. - Funkcia
fscanf()
: c-reference, cplusplus.com - Reads data fromstdin
, interprets it according to format and stores the results into given locations. - Funkcia
fprintf()
: c-reference, cplusplus.com - Loads the data from the given locations, converts them to character string equivalents and writes the results tostdout
. - Funkcia
perror()
: c-reference, cplusplus.com - Displays a character string corresponding of the current error tostderr
. - Funkcia
fgetc()
: c-reference, cplusplus.com - Reads the next character from the given input stream. - Funkcia
fputc()
: c-reference, cplusplus.com - Writes a character ch to the given output stream stream. - Funkcia
fgets()
: c-reference, cplusplus.com - Gets a character string from a file stream. - Funkcia
fputs()
: c-reference, cplusplus.com - Writes a character string to a file stream. - Funkcia
putchar()
: c-reference, cplusplus.com - Writes a character tostdout
.