11. týždeň

IQ Marathon, Part II.

Polia, reťazce, súbory, parametre funkcií

O čom je lab

V rámci tohto cvičenia budete pokračovať v programovaní zjednodušenej verzie hry IQ Marathon.

Ciele

  1. Osvojiť si prácu so súbormi.
  2. Rutinne pracovať s parametrami funkcií.
  3. Rutinne pracovať s reťazcami.
  4. Rutinne pracovať s viacrozmernými poliami.
  5. 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 a int 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

Do hlavnej funkcie programu pridajte vykreslenie hracieho poľa na začiatku hry a na konci hry s počtom zmien smeru. Hru môžete overiť na súboroch maze1, maze2 a maze3.

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

  1. Ternárny operátor
  2. Funkcia fopen(): c-reference, cplusplus.com - Opens a file and returns a file stream associated with that file.
  3. Funkcia fclose(): c-reference, cplusplus.com - Closes the given file stream.
  4. Funkcia fscanf(): c-reference, cplusplus.com - Reads data from stdin, interprets it according to format and stores the results into given locations.
  5. Funkcia fprintf(): c-reference, cplusplus.com - Loads the data from the given locations, converts them to character string equivalents and writes the results to stdout.
  6. Funkcia perror(): c-reference, cplusplus.com - Displays a character string corresponding of the current error to stderr.
  7. Funkcia fgetc(): c-reference, cplusplus.com - Reads the next character from the given input stream.
  8. Funkcia fputc(): c-reference, cplusplus.com - Writes a character ch to the given output stream stream.
  9. Funkcia fgets(): c-reference, cplusplus.com - Gets a character string from a file stream.
  10. Funkcia fputs(): c-reference, cplusplus.com - Writes a character string to a file stream.
  11. Funkcia putchar(): c-reference, cplusplus.com - Writes a character to stdout.

Video