Search
V rámci semestrální práce je možné vytvořit hru podle vlastního návrhu. Hra bude realizována v textovém režimu, zde je možné využit terminály POSIX.
Je nutné, aby hra smysluplně využívala minimálně tři definovaná vlákna (viz ukázka) – vstupní, výstupní (vykreslovací) a výpočetní (časovací). Vlákna musí spolu komunikovat – překreslení hry se děje jenom pokud je to nutné, hru lze kdykoliv korektně ukončit apod.
Vzorové řešení hry Piškvorky splňuje pouze minimální požadavky na semestrální práci a může být hodnoceno až 20 body. Na řešení lze ocenit možnost nastavení hry přes parametry programu a přípravu testů (viz níže). Vyšší bodové hodnocení lze dosáhnout také použitím složitějších algoritmů pro výpočet (například automatickou kontrolou řešení, vyhodnocení odpovědí hráče apod.) nebo lepší grafickou podobou aplikace (například využití více barev, větší hrací pole, další možnosti nastavení hry).
Upozornění: Pro správnou funkčnost vytvářené konzolové aplikace využíváme přepnutí do raw módu a ANSI escape sequences. I když tyto možnosti nabízí i terminály systému Windows, práce zde je mnohem komplikovanější a často nepředvídatelná.
Pokud se rozhodnete vytvářet tento typ semestrální práce, doporučujeme vývoj pod některým z UN*X systémů. Pod Windows lze efektivně využít i Windows Subsystem for Linux.
Tento typ semestrální práce využívá vlákna pro tvorbu konzolové aplikace. Semestrální práce je automaticky vícevláknová a demonstruje základní principy návrhu a tvorby uživatelského rozhraní. Ukážeme, jak lze implementovat jednoduchou hru piškvorky.
Začneme s programem tic_tac_toe_1.zip. Program využívá tři vlákna:
Q
counter
PERIOD_COUNTER
Při zadávání vstupů je obvykle vyžadováno jejich potvrzení klávesou ENTER. Pro zjednodušené načítání vstupů přepínáme terminál do tzv. raw módu, který potvrzování klávesou ENTER nevyžaduje. K tomu slouží funkce set_raw – set_raw(true) nastaví raw mód, set_raw(false) ho naopak zruší.
ENTER
set_raw
set_raw(true)
set_raw(false)
Předpokládáme, že program tic_tac_toe_1.zip připočítá jedničku do proměnné counter s periodou PERIOD_COUNTER. Změnu vypisuje na terminál. Po zmáčknutí Q se program ukončí. Program vyzkoušejte a upravte podle zadání. Na následující otázky byste měli odpovědět kladně:
tic_tac_toe_1.zip
Řešení
inputThread
computeThread
outputThread
std::condition_variable
Tři definovaná vlákna využijeme ke konstrukci hry. Začneme návrhem vzhledu výpisů. Hrací pole pro Piškvorky bude vypadat následovně:
------------- | | | | ------------- | | | | ------------- | | | | ------------- Kolecko:
------------- | X | O | | ------------- | O | X | | ------------- | O | | | ------------- Krizek:
------------- | | | | ------------- | | | | ------------- | | | | ------------- Kolecko: 1 3
----------------------------- | O | | | X | O | | | ----------------------------- | X | O | O | X | | | | ----------------------------- | | O | X | | | | | ----------------------------- | | X | | | | | | ----------------------------- | | | | | | | | ----------------------------- Kolecko:
Rozměry hracího pole a požadovaný počet značek v řadě pro výhru jsou parametry třídy tic_tac_toe. Parametry lze zadat prostřednictvím příkazové řádky. Parsování příkazové řádky se provádí ve třídě ArgParser, která na základě argumentů programu nastaví parametry pro třídu tic_tac_toe:
tic_tac_toe
ArgParser
-w
-width
-h
-height
-c
-count
Pokud nejsou parametry programu zadány, jsou využity předdefinované hodnoty – hrací pole velikosti 3×3 políčka.
Příklad spuštění programu:
Piskvorky -w 7 -c 4 -h 5 Piskvorky -width 7 -c 4 -height 5 Piskvorky -w 7 -h 5
Definujeme typ jednoho políčka hrací plochy p_field – typ nothing, wheel, cross. Informace o jednotlivých políčkách hracího pole jsou uloženy v std::vector typu p_field velikosti hracího pole (šířka x výška).
p_field
nothing
wheel
cross
std::vector
Pod vykresleným hracím polem bude vypsáno, kdo je na řadě a případně souřadnice aktuálně zadaného bodu ve formátu řádek sloupec. Výpis pod hrací plochou využijeme i k dalším informacím pro hráče a definujeme ho jako speciální řetězec výpisu (proměnná text).
K překreslování hracího pole (probuzení vlákna outputThread) bude docházet vždy, když dojde ke změnám parametrů hry, tj. když bude do hracího pole vložen nový křížek nebo kolečko. K tomu dochází po zadání souřadnic hráčem hry.
Definujeme třídu Window, která podle daného návrhu vykreslí hrací pole. Předpokládáme využití ANSI escape sequences. Potřebné konstanty definujeme pomocí maker:
Window
#define ANSI_CLEAR "\x1B[2J\x1B[H" #define ANSI_COLOR_RESET "\x1B[m" #define COLOR_RED "\x1B[91m" #define COLOR_GREEN "\x1B[92m" #define COLOR_WIN "\x1B[48;5;52m\x1B[38;5;208m" #define COLOR_DRAW "\x1B[48;5;17m\x1B[38;5;75m"
Konstanta ANSI_CLEAR vymaže terminál a nastaví počátek vykreslování na levý horní roh terminálu. Konstanta ANSI_COLOR_RESET zruší nastavení barev – další vykreslování probíhá podle nastavení terminálu (obvykle bílá barva na černém pozadí).
ANSI_CLEAR
ANSI_COLOR_RESET
Další barvy lze definovat pomocí následující tabulky nebo lze využít další možnosti ANSI escape podle dokumentace. Například “\x1B[4m” způsobí výpis podtrženým písmem, “\x1B[9m” způsobí výpis přeškrtnutým písmem, “\x1B[91m” výpis červeně.
“\x1B[4m”
“\x1B[9m”
“\x1B[91m”
Barvy lze definovat i specificky pro pozadí a popředí výpisu (n je číslo v rozmezí 0 až 256 a udává barvu podle tabulky):
n
“\x1B[38:5:⟨n⟩m”
“\x1B[48:5:⟨n⟩m”
Proces ovládání hry je řízen vláknem inputThread. První zadaná číslice určuje řádek, druhá sloupec vložení značky. Novou značku vkládáme na dané místo pouze v případě, že na tomto místě jiná značka není. Při vložení značky je nutné zkontrolovat stav hry – výhru některého z hráčů nebo remízu. V případě ukončení hry je nutné vypsat odpovídající informace.
Doporučujeme k ovládání hry vybrat klávesy reprezentující písmena anglické abecedy nebo číslice. Speciální znaky (šipky, funkční klávesy apod.) jsou na zpracování náročnější.
V případě složitějšího ovládání hry doporučujeme pro ovládání definovat speciální třídu.
Některé hry mohou vyžadovat pravidelnou změnu hracího pole, například pravidelný pohyb hráče bez ohledu na vstup z klávesnice (housenka se pohybuje po ploše), pohyb pozadí (hra Mario) nebo pravidelný výpis skóre.
Pro demonstraci využití časování ve hře vypisujeme „časové“ skóre hráčů – jak dlouho jednotliví hráči své tahy promýšleli. Dojde-li k remíze, lze výhru započítat hráči s menším skóre, s kratším časem stráveným nad jednotlivými tahy.
Semestrální práce by měla být dobře otestována a ověřena. Můžete využít automatické testy (tzv. Continuous Integration), jak jste se s nimi setkávali v průběhu semestru. Nebo můžete dodat testy ve formě různých posloupností znaků pro ovládání hry. Příklad testů pro hru Piškvorky (rozměry 3×3):
q
1q
12q
112233q
1121223133
122113112231
1221223233111331
112112223123
311122213113
11121321222331
111222333121321323
1121311233222332
13s2223z1133
1121122213
3122211133132232
1122213113123223
Příklad testů pro hru Piškvorky (rozměry 7×5, 4 značky v řadě):
112212132333344521445553463526154325
112212231314243515173351162644534352544527
Příklad testů pro hru Piškvorky (rozměry 7×5, 5 značek v řadě):
11221223212431252613415133353246574217522753544337474445151634
1122122321243125261341513335324657421752275354433747441516453455
1122122313142435151733511626445343525445273442
Připravili jsme pro vás i ukázku semestrálky - hra Piškvorky. Najdete ji na fakultní instanci GitLabu, zde.
Odpovídající email by pak vypadal zhruba takto:
Dobrý den, odevzdávám semestrálku "Odhad Pí za pomoci Monte Carlo simulace". Kód je na https://gitlab.fel.cvut.cz/nagyoing/mujprojekt, hash acbf81b733323cd87250269f38415c0c7f0f5c99. ...
Pokud forknete ukázkový repozitář a nechcete, aby byl váš kód viditelný světu, nastavte Visibility1) na Internal.
Před odevzdáním semestrální práce na téma tvorba hry si zde můžete zkontrolovat, zda jste na něco nezapomněli.
* Kód * Obsahuje váš kód CMakeLists.txt přes který se vaše semestrálka dá postavit? * Používá váš kód alespoň tři vlákna, která správně komunikují? * Nepoužívá váš kód rozšíření jazyka? (Například OpenMP, VLA) * Nepoužívá váš kód nepřenosné knihovny (Například POSIX, Win32) * Testování * Obsahuje vaše řešení popis způsobů a postupů testování? Obsahuje příklady testů, které jste prováděli? * Zkontrolovali jste svoje řešení s využitím vhodného analytického nástroje (valgrind, dr. Memory apod.)? * Zpráva * Obsahuje vaše zpráva hash commitu (nebo tag), vůči kterému byla napsaná? * Obsahuje vaše zpráva popis zadání? * Obsahuje vaše zpráva popis ovládání hry? * Obsahuje vaše zpráva popis možností a způsobů nastavení hry? * Máte proměnné a funkce programu řádně zdokumentovány? Jsou všude doplněny komentáře?
Věříme, že vymyslet vlastní návrh aplikace, kterou lze ovládat pomocí vstupů z klávesnice, by neměl být problém. Přesto uvádíme seznam her, které lze pro zadání využít. Lze vymyslet různé varianty uvedených her.