Motivácia
Pri programovaní hier, ale aj iných softvérových systémov, je veľmi dôležité porozumieť tomu, ako bude používateľ aplikáciu používať, ako s ňou bude interagovať. V prípade hier je určite potrebné identifikovať fázy herného cyklu, akcie, ktoré môže vyvolať používateľ, a efekty, ktoré môžu mať tieto akcie na hru. Na tieto kľúčové úlohy sa zameriate pri implementácii konzolového používateľského rozhrania.
Pre implementáciu konzolového používateľského rozhrania hry je v prípade dlaždicových hier potrebné implementovať nasledujúce tri metódy:
play(Field field)
- herná slučka, ktorá kombinuje vypisovanie textovej podoby herného poľa na výstup a dialóg s používateľomshow()
- slúži na výpis textovej podoby herného poľa, volá sa vždy po jednom "ťahu" hryhandleInput()
- spracuje používateľský vstup a vykoná príslušnú akciu s hrou
Ciele
- Implementovať hernú slučku, v ktorej bude hra prebiehať.
- Implementovať výpis textovej podoby herného poľa.
- Implementovať spracovanie používateľského vstupu a komunikáciu hry s používateľom.
Postup
Krok 1
Úloha 1.1
Implementujte metódu s funkcionalitou hernej slučky, napr. play(Field field)
, v triede predstavujúcej konzolové používateľské rozhranie, napr. ConsoleUI
.
Metóda by mala vykonávať nasledujúce akcie:
- inicializácia privátnej premennej pre herné pole
field
, ktorá sa využije ako vnútorný model hry, - v cykle:
- výpis textovej reprezentácie herného poľa do konzoly pomocou metódy
show()
, - načítanie a spracovanie používateľského vstupu pomocou metódy
handleInput()
, - reakcia na zmenu stavu hry (
FAILED
,SOLVED
a i.).
- výpis textovej reprezentácie herného poľa do konzoly pomocou metódy
Poznámka
Pri implementácii podľa potreby rozdeľte zdrojový kód aj na prípadné pomocné privátne metódy.
Príklad implementácie metódy play
pre hru Minesweeper :
public void play(Field field) {
this.field = field;
do {
show();
handleInput();
} while(field.getState() == GameState.PLAYING);
show();
if(field.getState() == GameState.SOLVED) {
System.out.println("Solved!");
} else if(field.getState() == GameState.FAILED){
System.out.println("Failed!");
}
}
Krok 2
Na zobrazovanie herného poľa na štandardný výstup sú v prípade hry Minesweeper kladené nasledujúce požiadavky:
- Riadky sú označované veľkými písmenami zoradenými podľa abecedy (A, B, ..., I).
- Stĺpce sú označované číslicami (0, 1, ... , 8).
- Pre vykreslenie odkrytej dlaždice (
OPEN
) typu mína (Mine
) sa používa znakX
. - Pre vykreslenie dlaždice v stave (
OPEN
) typu pomoc pri hľadaní (Clue
) sa používa číslo reprezentujúce hodnotu dlaždice. - Pre vykreslenie označenej dlaždice (
MARKED
) sa používa znakM
. - Pre vykreslenie neoznačenej dlaždice (
CLOSED
) sa používa znak-
.
V prípade dlaždicových hier odporúčame postupovať podobným spôsobom, teda definovať si, akým spôsobom bude vykresľované herné pole (dvojrozmerné pole v matici, jednorozmerné pole horizontálne alebo vertikálne, kartové hry rozložené podľa pozície hráčov resp. kariet). Následne definovať kódovanie jednotlivých políčok resp. kariet písmenami alebo špeciálnymi znakmi podobne ako u hry Minesweeper: M
, -
, a čísla pre nápovedu.
Údaje pre zobrazenie jednotlivých dlaždíc získate z hernej logiky (u nás objekt triedy Field
).
Úloha 2.1
Implementujte vykreslenie herného poľa v metóde void show()
v triede ConsoleUI
.
Poznámka
Pre zobrazenie formátovaného výstupu (napríklad pri zobrazení označenia riadkov) môžete použiť napr. metódu System.out.printf(...)
, ktorá napr. dokáže formátovať výstup na preddefinovaný počet znakov, napr.: System.out.printf("%3d", 4)
vypíše číslo 4 na 3 znaky. Pre viac informácií si túto metódu vyhľadajte v dokumentácii Javadoc.
Poznámka
Aby ste mohli na štandardný výstup jednoduchým spôsobom vypísať textovú podobu herného poľa, zadefinujte textovú reprezentáciu jednotlivých tried dlaždíc (napr. triedy Mine
a Clue
) prekrytím štandardnej metódy toString()
. Napríklad:
public class Mine {
@Override
public String toString() {
return "*";
}
}
Krok 3
Úloha 3.1
Implementujte metódu handleInput()
v triede ConsoleUI
, ktorá má slúžiť na spracovanie používateľského vstupu.
V hre Minesweeper metóda handleInput()
vykonáva nasledujúce akcie:
- Vypíše požiadavku na zadanie vstupu so vzorom očakávaného vstupu od používateľa:
X
– ukončenie hry, jednotlivé ťahy - napr.MA1
– označenie dlaždice v riadku A a stĺpci 1,OB4
– odkrytie dlaždice v riadku B a stĺpci 4. - Načíta vstupnú požiadavku od používateľa (
nextLine()
). - Overí správnosť vstupného reťazca. Na overenie správnosti vstupu využíva regulárne výrazy.
- V prípade požiadavky od používateľa, ktorá nie je v požadovanom tvare si vyžiada od používateľa opätovné zadanie vstupu.
- Na základe identifikácie akcie od používateľa vykoná požadovanú operáciu (označenie dlaždice, odkrytie dlaždice, ukončenie programu).
Poznámka
Pre definíciu vzoru vstupu pomocou regulárneho výrazu vytvorte objekt triedy Pattern
(napr. statická metóda Pattern.compile("O([A-I])([0-8])")
pre vstup v tvare OA9 pre otvorenie dlaždice). To, či zadaný vstup zodpovedá vzoru, overte pomocou objektu triedy Matcher
. Objekt triedy Matcher
je možné získať pomocou metódy Matcher matcher(CharSequence input)
vytvoreného objektu typu Pattern
. Na overenie vstupov použite metódy boolean matches()
a String group(int group)
definované v triede Matcher
.
Krok 4
Úloha 4.1
Nahrajte vašu implementáciu do vášho repozitára na GitLab-e. Projekt môžete ďalej priebežne aktualizovať. Pred ďalším cvičením sa uistite, že máte v repozitári vaše aktuálne súbory. Zároveň si pripravte otázky, ktoré by ste na cvičení chceli vyriešiť.
Doplňujúce úlohy
Úloha A.1
Pre zlepšenie použiteľnosti akceptujte používateľský vstup veľkými aj malými písmenami (napr. v hre Minesweeper oa9
aj OA9
).
Úloha A.2
Implementujte podporu začatia novej hry po výhre alebo prehre:
Gratulujeme, vyhrali ste!
Prajete si začatie novej hry (A/N)? _
Zdroje
- Java Tutoriál venovaný regulárnym výrazom