Sokoban Intermezzo: the Curses

Ciele

  1. Osvojiť si základy práce s knižnicou curses.

Úvod

Na tomto cvičení začínate pracovať na svojom druhom zadaní - jednoduchej konzolovej hre Sokoban. Pri práci môžete vychádzať z vašej implementácie knižnice robota Karla a pri čítaní nasledujúcich modulov budú jednotlivé úlohy nadväzovať na vašu predchádzajúcu implementáciu.

Hlavným cieľom tohto cvičenia je však zoznámiť sa s knižnicou curses, ktorá vám poskytne viac možností pri práci s obrazovkou, ako poskytujú funkcie printf() alebo putchar(). Okrem toho umožňuje odchytiť stlačenie klávesy, čo budete vedieť využiť pri ovládaní svojej postavy v hre.

Postup

Krok č. 1

Ak chceme pracovať s knižnicou curses, je potrebné ju na začiatku programu inicializovať a po skončení behu programu zasa obnoviť pôvodné nastavenia. V opačnom prípade totiž nebude možné používať jednotlivé funkcie knižnice. Preto v tomto kroku upravíte funkciu turnOn() tak, aby inicializovala režim knižnice curses a vytvoríte funkciu turnOff(), ktorá zasa tento režim vypne.

Úloha 1.1:

Pripojte do svojho programu knižnicu curses.h a vyriešte všetky vzniknuté problémy.

Jeden z možných problémov sa bude týkať vlastného typu boolean, ktorý ste vytvárali. Typ boolean sa totiž v knižnici curses nachádza.

Ďalší problém môže vzniknúť, ak ste nepoužili pripravený projekt z cvičenia č. 5, ale vytvorili ste si vlastný projekt. Potrebujete ho nastaviť tak, aby pracoval s knižnicou curses.

Poznámka:
Pokiaľ pracujete na OS Windows, môže sa vám pri preklade zobraziť varovanie v podobe "MOUSE_MOVED" redefined. Aby ste sa mu vyhli, vložte knižnicu curses.h pred knižnicu windows.h.

Úloha 1.2:

Vo funkcii turnOn() inicializujte režim knižnice curses pomocou funkcie initscr().

Úloha 1.3:

Vytvorte funkciu turnOff(), ktorá ukončí režim práce knižnice curses a obnoví pôvodné nastavenia.

Úloha 1.4:

Overte správnosť svojej implementácie.
Poznámka:
Ak ste pracovali v OS Linux a postupovali ste správne, tak sa na obrazovke nič nezobrazí. Je to spôsobené tým, že knižnica curses pracuje vo vlastnom režime a pre výpis na obrazovku nepoužíva funkciu printf(), ktorú zatiaľ vo svojom programe používate.

Krok č. 2

Keďže sa aktuálne na obrazovku nevykreslí scéna, ktorú už máte pripravenú, v tomto kroku aktualizujete funkciu draw() tak, aby bola kompatibilná s knižnicou curses.

Úloha 2.1:

Aktualizujte funkciu draw() tak, aby vedela vykresliť mapu na obrazovku s použitím funkcií knižnice curses.
Pre zvládnutie tejto úlohy budete potrebovať poznať nasledujúce funkcie:
  • printw() - print formatted output in curses windows
  • move() - move curses window cursor
  • refresh() - refresh curses windows and lines
  • clear() - clears the screen
Poznámka:
Pri používaní funkcie move() nezabudnite, že pozícia (0,0) sa nachádza v ľavom hornom rohu.

Úloha 2.2:

Overte správnosť svojej implementácie.

Krok č. 3

Zatiaľ viete hráča ovládať len pomocou volania funkcií, ktoré reprezentujú primitívy robota Karla. V tomto kroku využijete funkcie nachádzajúce sa v knižnici curses na to, aby ste mohli hráča ovládať aj pomocou klávesnice.

Úloha 3.1:

Vo funkcii main() vytvorte nekonečnú slučku a načítavajte v nej kódy stlačených kláves pomocou volania funkcie getch().
Poznámka:
Pokiaľ overíte funkčnosť svojho riešenia teraz, každý stlačený kláves sa rovno zobrazí na obrazovke. Pri hraní hier to však nie je vhodné. Ak sa chcete tomuto efektu vyhnúť, použite funkciu noecho(). Zobrazovanie znakov opäť zapnete zavolaním funkcie echo().

Úloha 3.2:

Vo vytvorenej slučke zabezpečte, aby sa po stlačení klávesy q vykonávanie programu (slučky) ukončilo.

Úloha 3.3:

Namapujte stlačenie klávesy KEY_UP na volanie funkcie movek().
Poznámka:
Aby ste mohli pracovať aj s kurzorovými klávesmi, je potrebné zapnúť keypad na termináli používateľa. To je možné vykonať zavolaním funkcie keypad(), ktorej parametrom okna (win) bude konštanta stdscr reprezentujúca štandardný výstup.

Úloha 3.4:

Namapujte stlačenie klávesy KEY_LEFT na volanie funkcie turnLeft().

Úloha 3.5:

Overte správnosť svojej implementácie.

Doplňujúce úlohy

  1. Oboznámte sa s podporou a prácou s farbami v knižnici curses a vhodným spôsobom ich použite vo svojom riešení. Pre prácu s farbami môžete použiť nasledujúce funkcie:
    • has_colors() - vracia TRUE alebo FALSE podľa toho, či terminál podporuje prácu s farbami
    • start_color() - funkcia musí byť zavolaná, ak chcete v programe používať farby (ideálne rovno po funkcii initscr(), ale je dobré najprv overiť, či terminál prácu s farbami podporuje)
    • init_pair() - mení definíciu dvojice farieb, pričom dvojica farieb je chápaná ako farba pozadia a farba popredia. Funkcia má tri argumenty: číslo páru, čislo farby popredia a číslo farby pozadia.
    • attrset() - nastaví atribúty okna na atribúty zadané ako argument funkcie, pričom parametrom môže byť aj dvojica farieb definovaná funkciou init_pair().
  2. Upravte funkciu draw() tak, aby sa pri každom volaní nemusela vykreslovať celá scéna znova, ale prekreslili sa len vzniknuté zmeny. Za zmenu sa v tomto prípade dá považovať stará a nová pozícia robota Karla, ako aj aktualizácia stavového riadku.
  3. V prípade, že sa s robotom Karlom nechcete rozlúčiť tak skoro, tak namapujte vhodné klávesové skratky aj na funkcie putBeeper() a pickBeeper().
$Id$