Univerzita Karlova v Praze Matematicko-fyzikální fakulta
BAKALÁŘSKÁ PRÁCE
Václav Kozmík Renonc - licitovaný mariáš Katedra teoretické informatiky a matematické logiky
Vedoucí bakalářské práce: RNDr. David Kronus, Ph.D. Studijní program: Informatika, programování
2008
Děkuji všem, kteří mě podporovali při tvorbě této práce. Hlavní poděkování patří Kristiánu Malinovi, který pro tuto aplikaci nakreslil obrázky všech karet. Dále také děkuji Honzovi Steinerovi za neustálou podporu a rady při testování programu. V neposlední řadě děkuji vedoucímu této práce, panu Davidu Kronusovi, za to, že mi umožnil realizovat toto téma a vždy mě vedl správným směrem při návrhu a realizaci aplikace.
Prohlašuji, že jsem svou bakalářskou práci napsal samostatně a výhradně s použitím citovaných pramenů. Souhlasím se zapůjčováním práce a jejím zveřejňováním. V Praze dne 29.5.2008
Václav Kozmík
2
Obsah 1 Úvod
7
2 Analýza problému 2.1 Požadavky uživatelů . . . . . . 2.2 Požadavky z hlediska uplatnění 2.3 Cílová platforma a jazyk . . . . 2.4 Více druhů mariáše . . . . . . . 2.5 Části aplikace . . . . . . . . . . 2.6 Umělá inteligence . . . . . . . . 2.7 Hra po síti . . . . . . . . . . . . 2.8 Ukládání her . . . . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
3 Programátorská dokumentace 3.1 Cíle projektu . . . . . . . . . . . . . . . . . . 3.2 Používané pojmy a zkratky . . . . . . . . . . 3.3 Jazyk a vývojové prostředí . . . . . . . . . . . 3.4 Struktura programu . . . . . . . . . . . . . . . 3.5 Hlavní třídy a rozhraní programu . . . . . . . 3.5.1 Třída Karta . . . . . . . . . . . . . . . 3.5.2 Třída Balicek . . . . . . . . . . . . . 3.5.3 Třída HraM . . . . . . . . . . . . . . . 3.5.4 Třída LicitHra . . . . . . . . . . . . . 3.5.5 Třídy AI, LicitHrac . . . . . . . . . 3.5.6 Třída HerniServer . . . . . . . . . . . . 3.5.7 Třídy událostí a odpovědí . . . . . . . 3.5.8 Třída GUIHrac . . . . . . . . . . . . . 3.6 Hlavní myšlenky implementace . . . . . . . . 3.6.1 Umělá inteligence . . . . . . . . . . . . 3.6.2 Licitace . . . . . . . . . . . . . . . . . 3.6.3 Volba hry a flekování . . . . . . . . . . 3.6.4 Volba karty k zahrání . . . . . . . . . . 3.6.5 Příklad pravidla pro umělou inteligenci 3.6.6 Minimax . . . . . . . . . . . . . . . . . 3
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
. . . . . . . . . . . . . . . . . . . .
. . . . . . . .
9 9 10 10 11 11 12 13 13
. . . . . . . . . . . . . . . . . . . .
14 14 14 15 15 16 16 16 16 17 17 17 17 18 18 18 18 19 19 19 20
3.7
3.8 3.9
3.6.7 Ukládání a načítání her . . . . . . . . . . . . . . 3.6.8 Komunikační rozhraní . . . . . . . . . . . . . . 3.6.9 Ložené hry a nápověda pro člověka . . . . . . . 3.6.10 Řetězce a grafika . . . . . . . . . . . . . . . . . 3.6.11 Rozměry prvků grafického rozhraní . . . . . . . Hra po síti . . . . . . . . . . . . . . . . . . . . . . . . . 3.7.1 Protokol komunikace . . . . . . . . . . . . . . . 3.7.2 Zasílání a extrakce dat . . . . . . . . . . . . . . 3.7.3 Distribuce zpráv . . . . . . . . . . . . . . . . . 3.7.4 Implementace herního serveru . . . . . . . . . . Protokol a případná rozšíření . . . . . . . . . . . . . . Některé problémy a postupy . . . . . . . . . . . . . . . 3.9.1 Nastavení programu a pravidel . . . . . . . . . . 3.9.2 Implementace grafického rozhraní . . . . . . . . 3.9.3 Jak implementovat vlastní GUI . . . . . . . . . 3.9.4 Implementace síťové hry do grafického rozhraní 3.9.5 Jak implementovat klienta pro síť . . . . . . . .
4 Porovnání s existujícími programy 4.1 Pivoňka software - RE! . . . . . . 4.2 Falasoft - Becherovka mariáš . . . 4.3 Jakub Vrána - Čtyřka . . . . . . . 4.4 talon.cz . . . . . . . . . . . . . . 4.5 Shrnutí . . . . . . . . . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . .
. . . . .
. . . . . . . . . . . . . . . . .
21 21 22 23 24 25 25 26 27 28 28 29 29 29 30 31 31
. . . . .
32 32 32 33 33 34
5 Závěr
35
Literatura
37
A Obsah přiloženého DVD
39
B Nejdůležitější vlastnosti programu
40
C Uživatelská dokumentace C.1 Popis programu . . . . . . . . . . C.2 Požadavky na HW, SW . . . . . . C.3 Instalace . . . . . . . . . . . . . . C.4 Jak rychle začít po instalaci . . . C.5 Hlavní okno programu . . . . . . C.5.1 Oblast hlavních tlačítek . C.5.2 Prostřední oblast . . . . . C.5.3 Oblast s kartami uživatele C.5.4 Informační rámečky . . . . C.6 Historie . . . . . . . . . . . . . . 4
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
41 41 41 41 42 42 42 43 43 43 44
C.7 Hra po síti . . . . . . . . . . C.7.1 Výběr a spuštění hry C.8 Nastavení . . . . . . . . . . C.9 Server pro konzoli . . . . . . C.10 Pravidla mariáše . . . . . . C.11 Karty . . . . . . . . . . . .
. . . . . .
. . . . . .
5
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
44 44 45 47 47 47
Název práce: Renonc - licitovaný mariáš Autor: Václav Kozmík Katedra (ústav): Katedra teoretické informatiky a matematické logiky Vedoucí bakalářské práce: RNDr. David Kronus, Ph.D. e-mail vedoucího:
[email protected] Abstrakt: Předložená práce se zabývá vývojem aplikace pro hru licitovaného mariáše na počítači. Výsledná aplikace pro operační systém Windows umožňuje hru proti počítačovým protivníkům nebo hru po síti s lidskými protihráči. Umělá inteligence dosahuje úrovně pokročilejšího hráče mariáše, dodržuje zažité herní zvyklosti a pro řešení herních situací na konci hry používá algoritmus minimaxu. Síťová komunikace probíhá přes vlastní protokol založený na XML, což umožňuje alternativní implementaci klientské části v libovolném programovacím jazyce. Přínosem oproti stávajícím aplikacím je moderní grafické rozhraní, široké možnosti nastavení pravidel hry a také možnost ukládání lokálních i síťových her v jakémkoliv stavu hry. Práce popisuje možnosti aplikace z uživatelské a programátorské stránky a zahrnuje i porovnání s existujícími programy. Klíčová slova: mariáš, hra po síti, umělá inteligence
Title: Renonc - whist Author: Václav Kozmík Department: Department of Theoretical Computer Science and Mathematical Logic Supervisor: RNDr. David Kronus, Ph.D. Supervisor’s e-mail address:
[email protected] Abstract: The presented work concentrates on a development of a card playing game application for PC. The resulting application allows us to play against computer opponents or to play over the network against human opponents. Artificial intelligence achieves slightly advanced gameplay level, complies with common game practice and uses minimax algorithm for solving situations at the end of game. Network communication runs over a protocol based on XML, which allows easy development of alternative client interfaces in any programming language. Benefits, compared to present applications, include modern graphical interface, large number of rules settings and also the possibility to save the game state at any time when playing local or internet game. This work describes the application from user’s and programmer’s point of view and it also includes a comparison with other similar applications. Keywords: whist, network play, artificial intelligence
6
Kapitola 1 Úvod Mariáš je typicky česká karetní hra. Vzhledem k tomu, že se ve světě skoro vůbec nehraje, není dostupné velké množství aplikací pro hru na počítači. Všechny aplikace, které se dají sehnat, pocházejí vesměs od českých autorů a jejich počet by pravděpodobně nepřekročil deset. Navíc většina z nich se již delší dobu nevyvíjí, nesplňují dnešní standard v ovládání a vzhledu aplikací nebo mají dokonce problémy s během pod operačním systémem Windows Vista. Vzhledem k povaze mariáše jako hry hrané po hospodách a dle místních zvyklostí existuje velké množství různých variant pravidel. Pokud si ale chceme zahrát v některém z dostupných programů, velmi brzy budeme zklamáni z možností nastavení a budeme si muset zvykat na pravidla, která zavedl autor programu. Jako pokročilého hráče mě tento stav mrzí, a proto jsem se rozhodl pro tvorbu programu, který alespoň v některých ohledech současnou situaci vylepší. Tato práce se zabývá implementací aplikace, která umožňuje hru licitovaného mariáše proti počítačovým protivníkům nebo hru po síti s lidskými protihráči. U počítačových hráčů je dosaženo úrovně podobné pokročilejšímu hráči mariáše. To znamená, že umí například i nejběžnější signály, kterým rozumí, a sám je provádí. Je možné nastavit velké množství modifikací herních pravidel, které vycházejí z místních úprav a zvyklostí hráčů mariáše. Síťová verze hry podporuje díky modularizaci i připojení počítačových hráčů místo některého z lidských oponentů, komunikace probíhá přes otevřený XML protokol. Ovládání aplikace je víceméně intuitivní, zkušený hráč mariáše by měl být schopný ovládat a rozumět chování aplikace bez čtení návodů nebo experimentování. Pro začínající hráče je naopak výhodou, že grafické rozhraní zpřístupňuje vždy jen platné tahy nebo činnosti tak, aby se nedostávali zbytečně do komplikací plynoucích z neznalosti pravidel. Aplikaci lze provozovat pod operačními systémy Windows s omezením na ty verze, kde je možné nainstalovat .NET Framework verze 3 nebo vyšší. V kapitole 2 popíšeme problém více do hloubky a pokusíme se zdůvodnit rozhodnutí učiněná při návrhu řešení. V navazující kapitole číslo 3 rozebereme některé podstatné detaily naší implementace programu a postup sestavení. Srovnání s existujícími programy podobného zaměření lze najít v kapitole 4. Závěrečná kapitola 5 7
zhodnocuje práci jako celek a poukazuje na další možná vylepšení. Vysvětlení některých používaných pojmů lze najít v kapitole 3.2. Příloha B poskytuje seznam hlavních možností aplikace a příloha C obsahuje návod pro práci s programem a obsluhu jeho funkcí.
8
Kapitola 2 Analýza problému Jak již bylo poukázáno v úvodní kapitole, dostupné aplikace trpí zejména nedostatečnými možnostmi úpravy pravidel a také zastaralým grafickým rozhraním, případně problémy se spouštěním pod novým operačním systémem Windows Vista. Základním cílem je tedy přinést vlastní aplikaci, která bude v těchto ohledech výrazně lepší.
2.1
Požadavky uživatelů
Většina pokročilých hráčů mariáše udává, že jsou zvyklí na určité standardní postupy hry a zavedené signály. Příkladem může být například toto: hraje se durch a můj spoluhráč shodí eso (zahraje eso, zbaví se nevhodné karty). Tím jednoznačně říká, že barvu (esa, které shodil) drží a já ji mohu shazovat. Uživatelé tedy očekávají podobné chování a postupy i od případných počítačových spoluhráčů. Nejlepší je, pokud mohou hráči používat stejná pravidla, na která jsou zvyklí, nejraději by si i volili mezi druhy mariáše jako je licitovaný nebo čtyřka. Hráčů mariáše není v České republice nijak málo, většina z nich hraje mariáš po hospodách a nemusí mít s počítačovým hraním velké zkušenosti. Jejich úroveň počítačových znalostí může být ve většině případů pouze uživatelská. Z uvedených hledisek je jasné, že by mělo jít aplikaci nainstalovat a spustit co nejjednodušeji a měla by odpovídat zvyklostem uživatelů nabytých z používání základních aplikací v jejich operačním systému. Lepší než hrát proti počítačovým oponentům je ale pro každého určitě hrát se svými kamarády. I když jsou od sebe vzdáleni, rádi by hráli mariáš přes internet a očekávají, že jim v tom bude případná aplikace nápomocna. Protože nemají možnost jednoduché konzultace jako když hrají spolu na jednom místě, program by měl zajistit počítání skóre, zobrazovat dosažené výsledky a nabídnout historii hry k prozkoumání. Rozehranou partii her by chtěl uživatel někde uschovat, aby ji mohl příště obnovit a zachovat si své skóre. Pro uživatele je v dnešní době nejpřirozenějším ovládacím zařízením myš. Pro-
9
gram by tedy měl poskytnout grafické rozhraní, které odpovídá provedením dnešnímu standardu, a umožnit intuitivní jednoduché ovládání bez nutnosti studovat klávesové zkratky či jiné pokyny. Začínající uživatel chce být veden správným směrem a je nerad, pokud je obtěžován různými okny, které ho upozorňují na kroky proti pravidlům nebo jiné akce, které ho spíše matou.
2.2
Požadavky z hlediska uplatnění
Vyvíjená aplikace by měla být dostupná pro co největší počet potenciálních uživatelů a navíc by bylo nejlepší, kdyby nyní vytvořený program byl schopný běhu alespoň na další generaci operačních systémů.
2.3
Cílová platforma a jazyk
Vzhledem k silně převažujícímu počtu uživatelů operačních systémů Windows jsem se rozhodl primárně zaměřit na tuto platformu. V současné situaci lze odhadovat, že budoucí směr vývoje pro tuto platformu je jednoznačně vývoj v rámci řízeného kódu pro .NET. Vzhledem k rostoucí popularitě je dnes možné kompilovat projekty pro .NET i pod Linuxem, a tak by bylo dobré udržet alespoň některé části programu kompatibilní se starší verzí frameworku .NET 2.0, která je kompilovatelná překladačem projektu Mono [8]. Výhodou platformy .NET je nejen velká pravděpodobnost kompatibility do budoucna, ale i množství připravených knihoven a objektů, které jsou užitečné při implementaci aplikace. Zvolená platforma samozřejmě přináší i nevýhody jako je menší rychlost a delší čas načítání samotného programu a knihoven. Nabízí se i otázka, proč nezvolit například Javu, která je zaměřením a jazykem velmi podobná a je mnohem lépe přenositelná. Největší problém, který ale s Javou nastává, je výrazně horší podpora pro tvorbu grafického rozhraní než nabízí .NET Framework (Windows Presentation Foundation), navíc z hlediska rychlosti výsledného programu je Java subjektivně ještě pomalejší než .NET. Z programovacích jazyků dostupných pro zvolenou platformu se jako nejlepší jeví jednoznačně jazyk C#, protože je založen na známé syntaxi jazyků C/C++. Mariáš je aplikací, která nevyžaduje programování velkého množství formulářových oken nebo napojení na datové zdroje. Kromě obrázků karet také nejsou vyžadovány žádné speciální obrazové předlohy. Z toho důvodu jsem se rozhodl dělat aplikaci plně vektorovou, což do budoucna umožní jednoduché přidávání efektů a tvorbu hezčího uživatelského prostředí. Právě kvůli jednoduché implementaci vektorového prostředí jsem zvolil jako knihovnu pro tvorbu grafického rozhraní WPF. Jediným problémem se ukázalo sehnat vektorové předlohy pro mariášové karty, protože i když je tiskárny, které se zabývají tiskem mariášových karet, mají, nechtějí je dát k dispozici. Výsledkem této situace je to, že program
10
používá vlastní sadu mariášových karet a symbolů, které pro mě nakreslil Kristián Malina, za což mu ještě jednou tímto děkuji.
2.4
Více druhů mariáše
Mariáš je hrou s pevně definovaným pořadím úkonů, podstatným pozorováním je například to, že hráč nemůže mimo stanovený okamžik nijak zasahovat do hry. Existuje více variant mariáše, nejznámější jsou licitovaný mariáš, volený mariáš nebo čtyřka. Liší se počtem hráčů (tři nebo čtyři), způsobem určení trumfů a hrané hry (licitace, volba trumfů z části karet) nebo speciálním systémem určení spoluhráče u čtyřky. Jak již bylo zmíněno dříve, hráči by nejraději měli implementované všechny tyto varianty, odlišnosti jsou ale natolik zásadní, že to časově není možné. Základní principy a pravidla zůstavají ale u všech variant stejné. Při implementaci se tedy budeme snažit o to, aby tyto shodné věci byly znovupoužitelné při implementaci jiné z variant než je mariáš licitovaný. Volba licitovaného mariáše jako implementované varianty není nijak překvapující, jde o nejsložitější variantu, která obsahuje některé hry navíc (dvě sedmy) a je oblíbená mezi pokročilými hráči. Většina implementovaných postupů je i z hlediska umělé inteligence použitelná ihned pro variantu voleného mariáše, naopak čtyřka obsahuje určitý element nejistoty (s kým vlastně hrajeme) a změna počtu hráčů zásadně mění strategii. Proto musíme počítat s tímto omezením pro případ umělé inteligence a soustředit se na variantu hry ve třech.
2.5
Části aplikace
Z prezentovaných skutečností je jasné, že chceme hru rozdělit minimálně na tři části. Jádro, které bude řídit průběh vlastní hry podle nastavených pravidel a oslovovat právě toho hráče, který je na řadě, umělá inteligence, která bude na tyto oslovení reagovat, a jako třetí část grafické rozhraní, které umožní na tyto oslovení reagovat člověku. Pokud tedy zvolíme jádro hry jako základní stavební prvek, zajistíme tím konzistentní kontrolu průběhu hry již na jeho straně a můžeme předávat pouze jasné pokyny, které minimalizují rizika nekorektního chování hráčů a případné ošetřování chybových stavů. Je tedy nutné specifikovat nějaký protokol komunikace mezi jádrem a hráči, v tomto případě rozhraní v jazyce C#. Toto rozhraní bude jedinou a jednotnou vrstvou mezi jádrem a hráčem, a to jak lidským, tak počítačovým. Jádro bude disponovat referencí na hráče a v případě potřeby vyvolá příslušnou metodu z tohoto rozhraní. Její typ návratové hodnoty navíc jasně stanoví, zda je potřeba nějaká reakce nebo jde o informativní zprávu. Nejtěžším prvkem návrhu je tedy promyslet průběh hry mariáše a vytvořit podle toho příslušné metody, které budou součástí tohoto rozhraní.
11
2.6
Umělá inteligence
Přístupů k tvorbě umělé inteligence existuje celá řada. Pokusím se vysvětlit, proč si myslím, že pro hru typu mariáše je stále lepší přístup na základě statických pravidel (jak se chovat v dané situaci) než metody hrubé síly. Důležitou věcí je fakt, že mariáš není otevřená hra. Hráči musí dodržovat určitá pravidla, z čehož se dá odvodit hodně informací, ale na začátku hry nemáme prakticky žádnou informaci o kartách protihráčů. Již tedy počet všech možných rozložení lze odhadnout na začátku jako počet kombinací 10 prvků z 20. V každém z 10 kol může mít hráč odhadem možnost zahrát 4 karty. To nám s celkem třemi hráči dává obrovské množství průběhů hry, které rozhodně není možné projít v reálném čase. Velký počet kombinací znemožňuje použití metod typu minimaxu již od začátku hry, ale je možné jej nasadit ke konci hry, kdy je počet kombinací již relativně malý. Dalším problémem může být nejasná interpretace výsledků minimaxu. Počítačový hráč může hrát ve dvojici s lidským hráčem a je otázkou, zda lze předpokládat, že spoluhráč bude volit vždy nejlepší variantu z hlediska našeho ohodnocení. Toto všechno navíc komplikuje fakt zavedených postupů a triků v mariáši. Velmi těžko lze přímo do minimaxu implementovat rozhodnutí, která budou učiněna podle chování našeho spoluhráče v budoucnosti. Jiná alternativní metoda je možnost učit se od protihráčů. To znamená, že bychom si pamatovali, že v dané situaci určité rozhodnutí vedlo k výhře nebo lepšímu výsledku. Opět máme ale spoustu možných problémů, v mariáši máme často opakující se situace, které se ale liší rozložením karet protivníků. Tah, který je správný při jednom rozložení, může být naprosto katastrofický při rozložení jiném. Reálné rozložení karet protivníků ale v daném okamžiku většinou neznáme přesně, umíme jen odhadnout jaké karty mohou mít. Abychom se tedy něco rozumného z hlediska pravděpodobnosti naučili, museli bychom odehrát pravděpodobně tisíce her, což není moc reálné na provedení. Zvolil jsem tedy postup implementace umělé inteligence prakticky jako seznam pravidel, například pokud máš v betlu 7 karet stejné barvy a vynášíš, navíc máš eso, vynes nízkou kartu této barvy, abys ji pojistil. Ke konci hry, kdy již máme většinou dobrou informaci o kartách protihráčů, je aplikován minimax přes všechny možné kombinace karet ostatních hráčů. Při implementaci alfa-beta prořezávání je reálné nasadit tuto metodu na čtyři až pět kol před koncem, její výhody se ale nejvíce projeví právě v posledních třech kolech, kdy lze vhodným trikem zvrátit průběh hry na naší stranu (často se jedná o uhrání posledního štychu nebo o uhrání hlášené sedmy). Podobné argumenty o velké výpočetní náročnosti lze aplikovat i na licitaci, volbu hry a odhození talonu, kde disponujeme ještě menší informací o stavu hry, a proto zde postupujeme tradičními metodami. Detaily implementace umělé inteligence jsou popsány v programátorské dokumentaci.
12
2.7
Hra po síti
Požadavky na hru po síti je možné reálně splnit i s jednoduchým návrhem a implementací. Naše jádro předpokládá komunikaci se třídou, která splňuje dané komunikační rozhraní, což může být například síťový klient. Zbývá určit, jak budou klienti a server mezi sebou komunikovat. Jako nejjednoduší varianta se určitě nabízí .NET Remoting, který umožňuje implementaci vzdáleného volání procedur bez psaní dalšího kódu. Tato varianta by ale neposkytla možnost vývoje alternativních klientů pod jinou platformou nebo v jiném jazyce. Z tohoto důvodu byl zvolen textový protokol ve formě XML. Kdokoliv bude chtít napsat například jen vlastní grafické rozhraní nebo vlastní server, může tento protokol použít a napsat program pro svoji oblíbenou platformu ve svém oblíbeném programovacím jazyce. Protokol v podstatě kopíruje strukturu komunikačního rozhraní mezi hráčem a serverem a přidává navíc funkce na registrace hráčů nebo chat. Protože mariáš je založen na neznalosti karet spoluhráče, umožníme z principu jen komunikaci veřejnou, abychom nenabádali k podvádění.
2.8
Ukládání her
Ukládání her můžeme řešit trikem založeným na existenci jednotného komunikačního rozhraní. Samotné jádro hry ukládá historii událostí, které byly vyvolány na daném hráči. Hru můžeme pak načítat například tak, že celý její průběh zopakujeme, tedy jádro zašle stejné informace postupně za sebou správným hráčům. Jediný rozdíl je v tom, že neposkytne možnost volby, ale o naší volbě nás prakticky informuje. Tento postup má zjevné nevýhody v datové a časové náročnosti, má však ale jednu podstatnou výhodu. Obnoví veškerou informaci o hře a zprůhlední načítání hry i pro případné alternativní klienty. Do budoucna může umožnit třeba počítačovým hráčům naučit se informaci o stylu hraní protihráčů nebo již nyní chceme, aby umožnil grafickému rozhraní zobrazit historii v plném rozsahu.
13
Kapitola 3 Programátorská dokumentace 3.1
Cíle projektu
Cílem projektu je aplikace s moderním a intuitivním uživatelským rozhraním, která bude hrát mariáš na úrovni pokročilejšího hráče a umožňovat hru po síti. Komunikace po síti by měla probíhat přes vlastní protokol na bázi XML, nezávislý na platformě. Výsledkem činnosti má být několik samostatných modulů, které budou vykonávat svoji specifickou činnost.
3.2
Používané pojmy a zkratky
• Microsoft .NET Framework - vývojářská platforma s podporou interpretovaných jazyků, více informací na http://msdn2.microsoft.com/en-us/netframework/default.aspx • Windows Presentation Foundation (WPF) - prostředí pro tvorbu grafického rozhraní, více informací na http://msdn2.microsoft.com/en-us/netframework/aa663326.aspx • Extensible Application Markup Language (XAML) - deklarativní jazyk pro popis grafického rozhraní, viz http://msdn2.microsoft.com/en-us/library/ms752059.aspx • Microsoft Visual Studio - vývojové prostředí určené pro Windows, více informací na http://www.microsoft.com/cze/msdn/produkty/vstudio/default.mspx • C# - programovací jazyk pro platformu .NET, viz http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx • Base Class Libraries (BCL) - základní třídy pro vývoj aplikací pro platformu .NET 14
3.3
Jazyk a vývojové prostředí
Program je psán v jazyce C# verze 2.0, jádro programu a serverová část využívá možnosti .NET Framework 2.0. Pro tvorbu grafického rozhraní byla zvolena technologie WPF a grafická část programu tedy vyžaduje minimálně .NET 3.0. Jako vývojové prostředí bylo původně zvoleno MS Visual Studio 2005, ale po čase jsem zjistil, že tato verze není pro vývoj ve WPF příliš vhodná, doplňky pro vývoj jsou nestabilní a chybí také možnost nastavit v editoru zdrojů viditelnost jako veřejnou. Finální verze programu je tedy kompilována v novějším Visual Studiu 2008 a dodané soubory jsou také v tomto formátu. Pro kompilaci v této verzi nejsou potřeba žádné další doplňky. Jádro programu i serverová část by měly být kompilovatelné i pod Linuxem prostřednictvím překladače projektu Mono, což ovšem nebylo testováno vzhledem k absenci možnosti přenést i grafické rozhraní. Výsledný spustitelný soubor samostatného serveru spolu s knihovnami (kompilováno ve Visual Studiu) běží v rámci projektu Mono korektně. Při publikování finální kompilované verze programu jsem narazil na chybu ve Visual Studiu, kdy se publikování nezdaří s hlášením o chybějících souborech typu MojeOkno.g.i.cs. Jako dočasné řešení než Microsoft vydá záplatu lze vymazat obsah adresáře obj ve složce projektu a poté znovu projekt publikovat. Zdrojové kódy obsahují tři samostatné projekty. Prvním je jádro (RenoncMarias.Core), které se kompiluje do samostatné knihovny DLL. Stejně pak postupujeme i u serverové části (RenoncMarias.Server ), kterou kompilujeme také do vlastní dynamicky linkované knihovny, která ovšem vyžaduje i knihovnu jádra. Grafická část, která je kompilována do výsledného spustitelného souboru, pak vyžaduje obě knihovny. Navíc je k dispozici i projekt ConsoleServer, který umožňuje spustit samostatně jenom serverovou část aplikace, kompilací tohoto projektu vznikne konzolová aplikace.
3.4
Struktura programu
Program je rozdělen na tři hlavní části, a to jádro, grafické rozhraní a server. Komunikace těchto částí probíhá přes vlastní rozhraní, označené jako IHrac, případně přes vlastní síťový XML protokol, o kterém pojednává kapitola 3.7.1. Rozhraní IHrac je klíčové pro celou hru. Je to vlastně způsob komunikace jádra s jednotlivými hráči, nezávisle na tom, zda jde o hráče počítačového nebo člověka. Na tomto místě je vhodné zdůraznit, že grafická část programu je vlastně hráč mariáše, který je do jádra připojen přes toto rozhraní. Dostává tedy úplně stejné informace jako počítačoví hráči a je s ním stejně zacházeno. Tato abstrakce by měla umožnit jednoduché rozšiřování funkcionality programu, navíc umožňuje elegantní začlenění síťové hry. Popis jednotlivých metod tohoto rozhraní je uveden přímo u jejich deklarací a lze jej také najít v přiložené generované dokumentaci. Program je uzavřen ve
15
jmenném prostoru RenoncMarias, který ještě obsahuje podprostor LicitM pro licitovaný mariáš, GUI pro grafické rozhraní a Server pro síťovou část. Snahou bylo, aby společné části, které mohou být použity i pro jiné varianty hry, byly dostupné v hlavním jmenném prostoru, a naopak věci specifické pro licitovaný mariáš byly v části LicitM. To se například týká i již zmiňovaného rozhraní, protože každá varianta hry má jiný průběh.
3.5 3.5.1
Hlavní třídy a rozhraní programu Třída Karta
Třída Karta reprezentuje jednu herní kartu. Skládá se z vlastností Barva a Hodnota. Na této třídě je podstatné, že umožňuje porovnávat karty na shodu a obsahuje funkce na porovnávání hodnot karet. Jsou zde dvě verze, a to porovnávání s desítkami pod spodkem a normální porovnávání. Aby nedocházelo k omylům, neimplementuje tato třída implicitně žádné z těchto porovnávání a je proto nutné při třízení používat přetížených metod se specifikací způsobu porovnávání.
3.5.2
Třída Balicek
Základní třídou pro množinu karet je Balicek. Je odvozena od třídy List se specifikací prvků typu Karta. Oproti rodičovské třídě přidává navíc funkce specifické pro mariáš, jako je míchání balíčku, naplnění balíčku všemi kartami, snímání balíčku, atp. Obsahuje také pomocné funkce pro umělou inteligenci jako je hledání největších a nejmenších karet, odstraňování dané barvy z balíčku, počet karet dané barvy nebo hodnoty v balíčku. Přetěžuje navíc metodu Sort tak, aby přijímala i porovnávač hodnot karet a ne jen porovnávač celých karet.
3.5.3
Třída HraM
Třída HraM reprezentuje jednu hlášenou hru licitovaného mariáše. Její význam spočívá v tom, že obsahuje metody, které usnadňují programování pravidel a inteligence, které se liší podle typu hry. Například instance této hry umí vracet správný typ porovnávání karet dle nastavení pravidel nebo obsahuje metody, které vrací, zda tato hra má trumfy nebo pomocné. Každá instance také umí rozdělit danou hru na její části, tj. například stosedm na stovku a sedmu. Zároveň je zde implementována konverze na typ licitované hry a porovnávání her z hlediska licitace. Podle výsledků hry umí také tato třída spočítat cenu hry a vyhodnocuje, kdo zabíjí štych, který právě leží na stole.
16
3.5.4
Třída LicitHra
Řídící třídou programu je třída LicitHra. Vytvořením její instance a spuštěním metody NekonecnaSmyckaHer() dojde k zahájení vlastní hry. Tato třída zajišťuje v několika různých metodách celý průběh hry, volání správných metod jednotlivých hráčů, kontrolu pravidel, počítání výsledků hry, skládání karet nebo simulaci zbylého průběhu hry při ložené hře. Konstruktor této třídy dostává jako parametry nastavení hry a reference na tři hráče, se kterými bude třída komunikovat. Třída také umožňuje načítat a ukládat stav rozehrané hry, a to v libovolné chvíli. O principu implementace ukládání her je pojednáno ve zvláštním odstavci.
3.5.5
Třídy AI, LicitHrac
Třídy AI a LicitHrac slouží k implementaci umělé inteligence pro licitovaný mariáš. Jsou rozděleny do tří souborů. Metody, které by mohly být částečně užitečné i mimo licitovaný mariáš, jsou ve třídě AI, která se ještě dělí na část pro licitování, resp. volbu hry, a na samotnou herní část. Používané herní rozhraní dává hráčům mnoho informací, které v současné době implementace počítačové inteligence nepoužívá, ale mohly by být v budoucnu využity k jejímu vylepšování.
3.5.6
Třída HerniServer
Zajišťuje implementaci všech důležitých funkcí serveru pro síťové hry jako je správa hráčů, zakládání a spouštění her, chat a ukládání stavu hry. Významné jsou zde také statické metody SendUdalost, resp. ExtractUdalost, které přes předané síťové připojení zašlou, resp. přijmou objekt typu síťové události nebo odpovědi. Všechny implementace by měly využívat tyto metody, kde je zajištěna serializace a komprese objektů. Více o principech síťové komunikace pojednává kapitola 3.7. Poskytované funkce serveru shrnuje rozhraní IServer, pro jednodušší implementaci klientů je ale navíc k dispozici třída ServerImplementator, která umožňuje přímo zavolat danou metodu a implementuje ji tak, že zasílá síťovou zprávu a případně čeká na odpověď po síti. Pro implementaci klientů lze také využít třídu NetDispatcher, která je určena pro spuštění v samostatném vlákně a zajišťuje příjem a zpracování zpráv. Zprávy typu odpověď uschovává a můžeme si je vyžádat, po přijetí nové události naopak vyvolá přiřazené metody pro její obsluhu.
3.5.7
Třídy událostí a odpovědí
Zahrnuje celkem čtyři abstraktní třídy, a to Udalost, NetUdalost, Odpoved a NetOdpoved a množství jejich implementací pro každou možnou událost z rozhraní IHrac a IServer. Princip rozdělení je takový, že zprávy zasílané jádrem hry, které se netýkají síťové komunikace, jsou typu Udalost, resp. jejich návratové hodnoty typu Odpoved a zprávy týkající se síťové hry jsou zbylých typů. 17
Objekty typu Udalost jsou navíc používány i jádrem hry pro ukládání rozehrané hry.
3.5.8
Třída GUIHrac
Třída GUIHrac poskytuje implementaci pro hru člověka. Stará se hlavně o zpracovávání příchozích informací od jádra hry a jejich transformaci k jasným pokynům pro člověka. Zajišťuje udržování karet v ruce, sběr informací o skóre všech hráčů, historii her a také poskytuje důležité vlastnosti pro samotné zobrazovací okno. Vzhledem k velké provázanosti dění ve hře s hlavním oknem aplikace bylo ale nutné, aby byly od hlavního okna hry této třídě poskytnuty nějaké pomocné funkce. Tyto jsou shrnuty v rozhraní GUIIface a reference na okno je předávána třídě v konstruktoru. Tato abstrakce navíc umožňuje tvorbu například více druhů uživatelských rozhraní nad jednotným základem. Je nutné ale upozornit, že tato třída používá kolekce technologie WPF pro zajištění notifikací o změnách, a tak vyžaduje verzi .NET Frameworku 3.
3.6 3.6.1
Hlavní myšlenky implementace Umělá inteligence
Princip implementace hry počítačů je prakticky v seznamu neměnných pravidel jak postupovat. Tato pravidla jsou odvozena z praktických zkušeností ze hry mariáše a také upravována podle testování hry počítače. Při pozorování častých chyb protihráčů je možné měnit pravidla jak přesouváním v kódu, tj. měnit jejich prioritu, tak změnou různých odhadnutých konstant, které byly pro danou situaci zvoleny. Do budoucna je počítáno i s určitým prvkem náhody ve hře, to by znamenalo, že pokud počítač neví, jakou kartu zahrát, vrací balíček stejně dobrých výnosů. Mezi nimi se pak vybere náhodně. Navíc je implementován minimax pro řešení stavů ke konci hry, například na poslední 3 nebo 4 kola. Zde je již počet kombinací velmi malý nebo máme jistotu o kartách protihráčů a můžeme efektivně projít všechny možnosti.
3.6.2
Licitace
Pro licitaci je vytvořena sada metod, které testují, zda se nám vyplatí licitovat na danou hru. Počítačový hráč pak voláním těchto metod zjistí nejvyšší licitovatelnou hru a na tu licituje. Rozhraní umožňuje i reakci na průběh licitace ostatních hráčů, v umělé inteligenci to zatím ale není bráno v potaz. Samotné metody jsou tvořeny pro každou hru zvlášť a jsou programovány ve smyslu počítání trumfů a vysokých karet, odhadování výsledku hry nebo počítání možných chytáků pro betla a durcha.
18
3.6.3
Volba hry a flekování
Pokud si hráč vylicituje vlastní hru, dochází k otázce výběru talonu a hlášené hry. Talon může zásadně měnit povahu hlášené hry, navíc naším cílem by mělo být maximalizovat zisk, resp. minimalizovat ztrátu. Pro tento účel jsem vytvořil funkce, které pro danou hru, karty v ruce a shozený talon počítají možné výsledky hry. Ke každému výsledku hry je pak připojena odhadovaná pravděpodobnost toho, že nastane. U některých her máme možnosti jen výhry a prohry (např. betl, sedma) a pravděpodobnost je zde počítána dle počtu chytáků nebo z počtu trumfů a vysokých karet. U výsledků hry se postupuje způsobem, kde stanovíme nějaké rozumné možné dolní a horní meze výsledku a mezi ně rozdělíme pravděpodobnosti s ohledem na nejpravděpodobnější výsledek někde mezi nimi. Pro volbu nejlepší hry pak zkusíme odhodit všechny možné kombinace karet a zahlásit všechny možné hry, pro každou kombinaci spočteme výsledek a vybereme maximum. V případě flekování hry, kterou sami hlásíme, postupujeme podle spočtené pravděpodobnosti. Sečteme pravděpodobnosti naší výhry a pokud máme součet větší než je mez daná aktuálním počtem fleků, přidáváme další flek. V případě flekování hry protihráče postupujeme podobně jako u licitace dle seznamu pravidel, která určují, kolik máme dát fleků z aktuálních karet v ruce.
3.6.4
Volba karty k zahrání
Původně bylo mým záměrem pro vlastní hru udělat větší množství společných metod, které by se pak použily na různých místech dle dané hry. Ve výsledku se ale ukázalo, že hra obsahuje velké odlišnosti, a tak došlo prakticky k tomu, že každá metoda pro danou hru se větví podle toho, zda hru hlásíme my nebo ne, a tyto části se ještě dělí podle toho, zda vynášíme, hrajeme druzí nebo třetí. Při dané pozici se zde pak uplatňuje seznam pravidel pro hru. Pokud se pravidlo aplikuje, nepokračujeme dál, jinak zkusíme další pravidlo. Příklad může být třeba toto: nejdříve se podíváme, zda není jisté, že na některé barvě připravíme protivníky o trumfy, pak až zkoušíme nést barvu, od které máme nejvíce karet. Snahou je nalézt optimální pořadí a sadu pravidel tak, aby hráči hráli v průměru co nejlépe. Druhou snahou v těchto pravidlech je použití standardních postupů odmazávání a chytání například v betlu a durchu. Do budoucna by asi tato část kódu potřebovala nejvíce pročistit a zprůhlednit, případně rozdělit na větší množství menších a samostatných metod.
3.6.5
Příklad pravidla pro umělou inteligenci
Uvedeme si příklad seznamu pravidel, a tím je jak řešíme hru durch v následující metodě. ///AIHra.cs public Balicek HrajDurch(Vynos[] vyneseno, 19
Balicek bal, InfoOHre info) Situace se dělí podle toho, zda durch hrajeme my nebo jej chytáme. Pokud durcha hrajeme, provedeme následující kroky: • zvolíme barvu, od které jsme měli na začátku nejvíce karet, • najdeme si maximální hodnotu karty od této barvy, to samé pro možné karty protihráčů, • pokud máme nejvyšší hodnotu, neseme tuto kartu, • pokud ne, pokračujeme s další barvou, od které jsme měli nejvíce karet, • pokud už žádná taková barva není, neseme poslední nalezenou, ale je jasné, že prohráváme. Cílem této metody je nikdy nevynést tak, aby nám zabili naši kartu, a zároveň ale nést tu barvu, od které jsme měli nejvíce karet, abychom nedali moc informací protihráčům. Pokud durcha chytáme, postupujeme naopak takto: • pokud mám barvu, která je vynesena, zahraji nejnižší kartu od této barvy, • pokud ji nemám, najdu barvy, které si držím, a pokud můžu, ukážu například esem, že ji hlídám • pokud jsem neurčil kartu ke shození, podívám se, zda spoluhráč neshazoval vysokou kartu od dané barvy, pokud ano, asi ji drží a já se této barvy shazuji, • v dalším kroku vyberu kartu tak, že shazuji od barvy, kterou držím, ale mám zbytečně moc karet na to, abych ji stále držel, • jinak odhodím nejmenší kartu od barvy, které mám nejmíň. V předchozím textu držet danou barvu znamená to, že mezi mojí nejvyšší kartou dané barvy a esem je méně karet než mám celkem od dané barvy a protivník může mít některou nižší kartu, kterou poté zabiju.
3.6.6
Minimax
Pokud je již počet nutných iterací malý, snažíme se nasadit metodu minimaxu. Počítačový hráč si drží informaci o možných kartách protihráčů a při zavolání metody minimaxu vygeneruje všechny možné kombinace, při kterých hledá nejlepší tah. Z hlediska pravděpodobnosti je pak zvolen tah, který se objevil nejčastěji. Vzhledem k tomu, že v průběhu hry mariáše neexistuje prakticky žádný rozumný odhad ohodnocení stavu, je nutné vždy hru propočítat až do konce, kdy jsme 20
schopni spočítat její cenu a určit tak výhodnost našich tahů. Tento přístup přináší také některé nevýhody, které jsou pro člověka patrné, například pokud může počítačový hráč namazat desítku spoluhráči, měl by to vždy udělat. Jedna desítka ale nemusí pro výslednou cenu znamenat žádný rozdíl, a tak počítačový hráč volí i jinou alternativu a běžný uživatel by si mohl myslet, že je umělá inteligence špatná. Tomuto problému se snažíme čelit tak, že do ohodnocení zahrneme i počet uhraných desítek, ale s tak malou vahou, abychom případně nepoškodili důležitější finanční část výsledku. I přes veškerou snahu se ale nevyhneme tahům, které sice nejsou špatné, ale pro člověka působí divně, protože by sám nikdy takto nehrál. Do budoucna by bylo nejlepší vylepšit tyto metody tak, aby zahrnovaly i informace naučené ze hry, to znamená, že každá kombinace karet by měla jinou pravděpodobnost podle předchozího průběhu hry. Jednou z možností by také bylo zkusit nasadit metody hrubé síly na celou sehrávku s tím, že by se počítalo jen na některých vhodně nebo náhodně vybraných kombinacích karet. Při současné implementaci (obsahuje alfa-beta prořezávání) je reálné nasadit minimax většinou po polovině sehrávky. Při testech počítačů se statickou implementací inteligence proti počítačům, kteří ke konci využívají minimax, se ukazuje mírná výhoda ve prospěch minimaxu. Vzhledem k implementaci minimaxu až ke konci vývoje programu bohužel nemám k dispozici rozumná subjektivní vyjádření lidských hráčů.
3.6.7
Ukládání a načítání her
Pro ukládání jsem se rozhodl využít schopností automatické serializace do XML, soubor s uloženou hrou je prakticky seznam událostí, které se ve hře staly. Mezi hráče hry a jádro je vložena třída pojmenovaná HistoryManager. Tato třída zaznamenává pokyny odeslané hráčům a při uložení je jednoduše serializuje do souboru. Při načítání naopak tato třída zajišťuje to, že provádí za hráče rozhodnutí, která jsou zaznamenána v souboru, a hráčům posílá jen informace o tom, jak se rozhodli. Lepší představu o komunikaci jednotlivých součástí programu poskytne následující odstavec. Soubory s uloženými hrami jsou komprimovány metodou GZip.
3.6.8
Komunikační rozhraní
IHrac je hlavní rozhraní programu. Jako takové prodělalo během vývoje nejvíce změn. Například implementace ukládání a načítání her přinesla několik nových metod, které daného hráče informují o jeho provedených krocích, ale nedávají mu možnost vlastní volby. Uvedeme jednu ukázku takto upravené metody: /// LicitovanyMarias.cs HraM TalonAZahlas(ref Balicek talon, HraLicit minhra, out bool slozit, out int trumfyvtal, out int pomocnevtal);
21
Při normálním průběhu hry jádro hry zavolá tuto metodu na hráči, který si vylicitoval nejvyšší hru. Předá mu talon ve stejnojmenném parametru a očekává, že ho hráč upraví a vrátí hlášenou hru a další parametry. Pokud ale načítáme hru ze souboru, nemůžeme poskytnout hráči takovou volnost, protože by mohl vybrat jiný talon nebo hru a došlo by k nekonzistenci. Proto jsem musel přidat pro tento účel následující metodu, která jen hráče informuje o tom, jakou hru a talon zvolil. /// LicitovanyMarias.cs void ZvolenyTalon(Balicek novytalon, Balicek starytalon, HraM hra); Pokud by se v budoucnu měla rozšiřovat funkčnost aplikace, docházelo by k tomu prostřednictvím změny tohoto rozhraní. Jedním z rozumných vylepšení může být například počítání tzv. bonusových bodů za uhrání odvážné hry. Komunikace hlavních částí programu je shrnuta na obrázku 3.1.
Obrázek 3.1: Schéma komunikace
3.6.9
Ložené hry a nápověda pro člověka
Při implementaci grafického rozhraní bylo cílem udělat jej plně nezávislé na jádře a umělé inteligenci počítačů, komunikace by měla probíhat pouze přes rozhraní licitovaného mariáše. Bohužel tento cíl se podařilo splnit jen částečně, protože se objevila nutnost nějakým způsobem kontrolovat, zda již má hráč hru loženou, a poskytovat nápovědu, jakou kartu zahrát. Řešením tohoto problému je připojení „stínového hráčeÿ, kterého informujeme o všech krocích člověka. Tento hráč je 22
instancí umělé inteligence jako ostatní počítačoví hráči a může tak poskytovat nápovědu jakou kartu hrát, zda je hra již ložená a další věci. Do budoucna tak lze velmi jednoduše implementovat nápovědu i ve smyslu licitace a volby hry s odhazováním talonu. Pro případ síťové hry je do budoucna možné zvážit vypnutí této nápovědy tak, aby hráči spoléhali jen na sebe. Je nutné ale upozornit, že jádro se situací špatně nahlášené ložené hry nepočítá. Nutnou úpravou by tedy bylo přidání poplatku za renonc - špatně nahlášenou loženou hru a implementace informace pro hráče v jádře a komunikačním rozhraní. V obšírnějším pojetí lze také uvažovat o možnosti vypnout jakoukoliv nápovědu, což znamená, že by se nezobrazovalo jakou kartu můžeme hrát, jakou hru můžeme volit, žádná historie hry. Tyto funkce by mohly být vyžadovány profesionálními hráči pokud by spolu měli hrát přes internet.
3.6.10
Řetězce a grafika
Všechny řetězce, které se zobrazují uživateli na obrazovce, jsou zadefinovány ve třídě Resources, která se upravuje editorem Visual Studia. Je nutné, aby byla tato třída kompilována jako veřejná, jinak nepůjde napojit tyto řetězce na prvky grafického rozhraní přímo v XAMLu. Používané obrázky karet a další grafika jsou rozděleny do souborů Karty.xaml a Grafika.xaml. V těchto souborech jsou uloženy ve stylu WPF jako zdroje a dají se použít podle jejich klíče. Nejdůležitějším postupem je jak zobrazit samotné obrázky karet, proto ho popíši do větších detailů na ukázce kódu. V následujícím kódu vytvoříme seznam karet a nastavíme, že k vykreslení karty se má použít šablona vrácená třídou KartaSelector.
Vytvoření instance třídy na výběr šablony karty.
A implementace této třídy. Při tvorbě je využito nastavení různých parametrů karty podle aktuální situace a nastavení hry, to jsou vlastnosti zda má být karta animována a průhledná nebo ne. /// GUI.cs public class KartaSelector : DataTemplateSelector 23
{ public override DataTemplate SelectTemplate (object item, DependencyObject container) { //sestav string s datatemplate Karta k = ((GUIKarta)item).VratKartu(); string karta = GUIHra.GetImage(k); string name = GUIHra.GetName(k); string str = String.Format( ...vyvtoření stringu DataTemplate v XAML ... ) //načti xaml StringReader stringReader = new StringReader(str); XmlReader xmlReader = XmlReader.Create(stringReader); DataTemplate dtmpl = (DataTemplate)( XamlReader.Load(xmlReader)); return dtmpl; } }
3.6.11
Rozměry prvků grafického rozhraní
Při návrhu každé aplikace řešíme otázku, jak reagovat při změně velikosti okna. Díky použitým technologiím je možné vykreslovat okno v plné kvalitě při změně velikosti nebo poměru stran, a tak jsem se rozhodl dát uživateli plnou volbu velikosti hlavního okna aplikace. Pro zajištění konzistence velikosti karet a textu se velikosti všech ostatních oken mění podle velikosti hlavního okna. Za tímto účelem je vytvořena třída ReSizer, která je napojena na hlavní okno a poskytuje informace o změně jeho šířky a výšky. Tato třída prohledá všechna okna aplikace a podle jména rozpozná okno hlavní. Uchová si referenci a dále poskytuje jeho šířku a výšku. Použití třídy v kódu XAML pak vypadá takto:
<Window x:Class="RenoncMarias.GUI.HistoryWindow" ... Width="{Binding Source={StaticResource ReSizer}, Path=MWndWidth}" Height="{Binding Source={StaticResource ReSizer}, Path=MWndHeight}" > 24
3.7
Hra po síti
V této části dokumentace se zaměřím na implementaci hry po síti, možné problémy a nedostatky a hlavně také na použitý komunikační protokol. Již od začátku tvorby aplikace bylo počítáno s tím, že rozhraní IHrac bude sloužit jako jediný komunikační kanál mezi jádrem a grafickým rozhraním, a tak není žádný problém mezi ně vložit vrstvu, která zajistí přenesení dat po síti. Nyní používané řešení je na tomto principu založené, ovšem vyžaduje od grafického rozhraní ještě implementace metod rozhraní IKlient. To obsahuje nové metody, které původní nesíťová hra neobsahovala a ani by logicky obsahovat neměla. Princip komunikace lze shrnout takto: např. server chce zavolat metodu na klientovi, použije třídu ServerHrac, která implementuje rozhraní klienta a zjednodušuje zasílání zpráv. Tato třída pak serializuje parametry metody do objektu typu NetUdalost a pošle celý objekt jako XML. Na druhé straně je objekt deserializován a zavolána příslušná obslužná rutina této události.
3.7.1
Protokol komunikace
Komunikace probíhá čistě ve formátu XML, každá zaslaná zpráva je jeden serializovaný objekt typu Udalost, NetUdalost, Odpoved nebo NetOdpoved. XML je vytvořeno standardními metodami serializace v .NETu, není však problém je zpracovat na jiné platformě nebo v jiném jazyce. Schéma používaných XML souborů lze najít na přiloženém disku. Pro začátek uvedeme příklad zaslaného XML:
1 Stovka false Cervena Forhont 0 0 <MoznostiProti /> Na předchozím příkladu vidíme, že nastala událost zahlášení hry hráčem. Pole Hrac je zde nyní redundatní a je určeno jen pro zjednodušení načítání hry. Přijaté 25
XML dále obsahuje pole Hra, kde jsou informace o druhu hry, trumfech a pomocných. Povšimněme si, jakým způsobem jsou zpracovány položky, které nebyly nastaveny, resp. nemají smysl, v tomto případě neexistuje barva pomocných pro hru stovka. Dále vidíme další informační elementy a prázdný seznam her, které můžeme hlásit proti.
3.7.2
Zasílání a extrakce dat
Události jsou posílány přes standardní TCP/IP spojení. Pro snížení objemu datových přenosů, hlavně s ohledem na jistou roztažnost XML stringů, je před zasláním provedena komprese metodou GZip (použitím standardní třídy BCL GZipStream). Pro jednodušší zpracování dat postupujeme následujícím způsobem: nejprve připravíme pole bajtů, které chceme zaslat, určíme jeho délku a pak jako první zašleme tuto délku a pak daný počet bajtů. Délka je posílána jako 32-bitové celé číslo (čtyři bajty) ve formátu little endian. Na druhé straně spojení díky tomu jednoduše poznáme, kde končí zasílaná zpráva, a můžeme ji zpracovat. Ukázka implementace v .NETu jak poslat událost: /// Server.cs public static void SendUdalost(TcpClient client, object o) { try { //serializujeme do stringu XmlSerializer serial = new XmlSerializer(o.GetType()); //memory stream pro získání pole bajtů MemoryStream memstr = new MemoryStream(); GZipStream compstr = new GZipStream(memstr, CompressionMode.Compress, true); serial.Serialize(compstr, o); compstr.Close(); //zapíšeme délku dat a data samotná BinaryWriter binwrit = new BinaryWriter(client.GetStream()); byte[] tosend = memstr.GetBuffer(); int len = (int)memstr.Length; binwrit.Write(len); binwrit.Write(tosend, 0, len); binwrit.Flush(); } ... } 26
A ještě jak načíst příchozí událost: /// Server.cs public static object ExtractUdalost(TcpClient client) { try { //načti stream BinaryReader inread = new BinaryReader(client.GetStream()); //délka dat a načtení int len = inread.ReadInt32(); byte[] data = inread.ReadBytes(len); //dáme do streamu MemoryStream memstr = new MemoryStream(data); GZipStream compstr = new GZipStream(memstr, CompressionMode.Decompress); memstr.Seek(0, SeekOrigin.Begin); //načteme typ elementu XmlTextReader xml = new XmlTextReader(compstr); xml.Read(); xml.MoveToContent(); //deserializace ... } ... }
3.7.3
Distribuce zpráv
Pro zjednodušení implementace zpracování zpráv ze sítě je k dispozici třída NetDispatcher. Tato třída neustále extrahuje příchozí zprávy z internetového spojení a podle jejich typu provede zvolenou akci. Pokud je příchozí zpráva typu události jádra nebo události síťové hry, zavolá třída připojené obslužné funkce na jejich zpracování. Pokud je naopak příchozí zpráva typu odpověď, je uschována do té doby, než si o ní požádáme. Pokud si navíc vyžádáme odpověď, když ještě není k dispozici, zajistí třída pozastavení vlákna a probuzení v okamžiku, kdy odpověď dorazí.
27
3.7.4
Implementace herního serveru
Herní server implementovaný ve třídě HerniServer implementuje v podstatě rozhraní IServer. Současná implementace je myšlena spíše jako server pro hru několika kamarádů přes internet než jako implementace jednoho velkého serveru. V první řadě ukazuje serverová část možnosti aplikace a protokolu s ohledem na nastavování pravidel hry a ukládání her, stejně jako potvrzuje reálnou využitelnost protokolu. Pro reálné použití jako centrálního serveru pro hry všech hráčů, což by mohl být cíl pro některou z budoucích verzí, by bylo nutné použít nějakou SQL databázi. Současná verze udržuje informace o všech hráčích a hrách v paměti a při každém přístupu je kompletně zamyká, což není pro větší počet uživatelů použitelné. Navíc ukládání dat probíhá pouze metodou serializace do souboru při korektním ukončení serveru, čímž hrozí v případě chyb v serveru ztráta dat. Až na tento zmíněný nedostatek může ale serverová část velmi dobře sloužit svému účelu. Princip implementace je velmi jednoduchý, zprávy hry přesměrujeme do jádra spuštěného v separátním vlákně, a to tak, že mu v konstruktoru předáme instance třídy HracImplementator, která zajišťuje zaslání událostí a případné načtení odpovědí ze síťového spojení. Komunikace po síti je shrnuta na obrázku 3.2.
Obrázek 3.2: Schéma komunikace
3.8
Protokol a případná rozšíření
Současná verze protokolu je označena jako verze 1.0. Všechny schopnosti a možnosti vycházejí ze současného stavu aplikace. To samo o sobě neznamená, že je to protokol univerzální nebo všeobecně použitelný, ale lze hodnotit, že zejména v herní části jsou zahrnuty skoro všechny možnosti mariášové hry. Vhodnou konfigurací pravidel, která se při síťové hře dají nastavit, lze také tyto možnosti omezit a využívat pouze menší část protokolu (např. vypnout takzvané hry proti, které jsou implementačně složité). Takto ušetříme implementaci některých objektů protokolu, které pak nemohou vůbec nastat, u některých jiných objektů zůstanou 28
informace, které nebudeme muset zpracovávat. Do budoucna je samozřejmé uvažovat i o rozšíření možností protokolu. Z možností při samotné hře by to mohla být implementace renonců a jejich cen nebo implementace bonusových bodů. V části sestavování síťové hry je možných rozšíření mnohem více, například možnost hrát nějakou formu mariášové ligy, zpracování statistik, více informací při registraci hráče, možnost změnit údaje registrovaného hráče nebo zablokování účtu. Uvažovat lze také o možnosti komunikace mezi libovolnými hráči přihlášenými na server nebo nějakém systému automatického nalezení vhodných oponentů.
3.9 3.9.1
Některé problémy a postupy Nastavení programu a pravidel
Původně bylo nastavení pravidel a nastavení programu ukládáno společně ve statické instanci třídy Settings.Default, kterou poskytuje k tvorbě nastavení přímo Visual Studio. Bohužel až později se ukázalo, že toto řešení je z několika ohledů nedostatečné. Hlavní problém nastává při ukládání her. Je nutné uložit nastavení dané série her, aby mohlo být později obnoveno v původním rozsahu, protože uživatel mohl program mezitím přenastavit. Dalším problémem je běh jádra programu. Je nutné, aby jádro nebylo závislé na statickém nastavení a každá jeho instance měla nastavení vlastní, což umožňuje implementaci herního serveru s nastavením pravidel pro každou relaci her zvlášť. Z těchto důvodů jsem tedy vytvořil novou třídu LicitNastaveni, kde se udržuje nastavení dané hry. Všechny další komponenty programu byly předělány tak, aby nepoužívaly statické nastavení, ale nastavení předané v konstruktoru nebo parametrem statické metody. Uživatelská nastavení byla ponechána v původní třídě a jsou editovatelná v editoru Visual Studia. Uživatelem přenastavená pravidla pro nové hry se pak ukládají na disk do souboru pravidla.xml.
3.9.2
Implementace grafického rozhraní
Při tvorbě grafického rozhraní lze narazit na několik komplikací, které nemusí být zpočátku při návrhu aplikace zřejmé. Zvolený způsob implementace jádra jako řídícího elementu celé hry vede k faktu, že jádro musí běžet v samostatném vlákně. Ve chvíli, kdy je volána metoda hráče, která vrací nějakou odpověď, je nutné pozastavit běh jádra a počkat na odpověď člověka. Zvládnutí této překážky ovšem naopak usnadňuje implementaci síťové hry. Další věcí je použití kolekcí. Základní kolekce, která je v jádru používána, je List. Ta se ovšem nehodí pro použití ve WPF, kde je nutné, aby kolekce upozorňovala na případné změny svého obsahu. Vrstva mezi hlavním oknem a jádrem programu tedy převádí předaná data a interně ukládá v nové kolekci, která se jmenuje ObservableCollection. Raději upozorňuji na fakt, že grafické prvky okna ve Windows mohou být měněny jen z vlákna, které okno vytvořilo. To znamená, že pokud chceme udělat jakoukoliv 29
změnu, která přímo ovlivňuje prvky na obrazovce, je nutné jí vyvolat na tzv. Dispatcheru jako delegáta. Ten zajistí korektní naplánování a provedení ve vlákně okna.
3.9.3
Jak implementovat vlastní GUI
Pokud by z nějakého důvodu nastala nutnost implementace jiného grafického rozhraní, které používá jádro této aplikace, je dobré se držet následujících postupů. Pokud nemáte zájem o síťovou hru, budete potřebovat jenom knihovnu RenoncMarias.Core.dll. V případě potřeby síťové hry může být vhodné do aplikace navíc připojit i knihovnu RenoncMarias.Server.dll. Pro běh grafického rozhraní vytvoříme vlastní třídu, která bude splňovat rozhraní IHrac. Je nutné implementovat minimálně všechny metody, které mají návratovou hodnotu, ostatní jsou pouze informační, ale většinou jsou předávaná data pro hráče nebo další průběh hry podstatná. Upozorňuji pouze na to, že metody vracející nějakou hodnotu by neměly nijak měnit stav Vaší třídy, protože o zvolených akcích budete zpětně informováni přes jiné části rozhraní. Toto je nutné dodržet hlavně kvůli načítání her ze souboru. Pokud nechcete implementovat některé složitější prvky hry, například hry proti, lze je zakázat v nastavení a uživateli pak nedáme možnost tato nastavení měnit. Takto se lze jednoduše vyhnout některým problémům jako je nutnost implicitně všude psát, kdo danou hru hlásil. Pokud již máme vše připraveno a nastavíme pravidla hry pomocí instance třídy LicitNastaveni, můžeme spustit jádro takto: MojeTrida hrac = new MojeTrida(); LicitNastaveni nast = new LicitNastaveni(); //výchozí nastavení ... //modifikace nastavení LicitHra hra = new LicitHra(hrac, new LicitHrac(), new LicitHrac(), nast); //možné načtení hry Stream s = ... //otevřeme soubor hra.NactiHru(s); //spustíme samotnou hru Thread t = new Thread(new ThreadStart(hra.NekonecnaSmyckaHer)); t.IsBackground = true; t.Start(); Jako další dva hráče předáváme v konstruktoru hry instance umělé inteligence, která je implementována v knihovně jádra.
30
3.9.4
Implementace síťové hry do grafického rozhraní
Oproti hře na lokálním počítači nám přibyla nutnost zpracovat síťové události, z nichž největší komplikace přináší chat. To si ukážeme na jednoduchém příkladu. Dostaneme zprávu o tom, že má uživatel zvolit talon, a předáme ji ke standardnímu vyřízení proceduře, která na to byla určena pro lokální hru. Protože je nutné počkat, než něco uživatel „naklikáÿ, je vyřízení metody pozastaveno voláním Monitor.Wait(...). To pro síťovou hru ale znamená, že nenačítáme nově příchozí zprávy typu např. zpráva z chatu. Ve výsledku by uživatelé neviděli zprávy dříve, než by zvolili daný talon. Proto musíme při zpracování zpráv ze sítě postupovat opatrněji a používat vlákna, abychom zabránili podobným problémům.
3.9.5
Jak implementovat klienta pro síť
Pro implementaci vlastního klienta, který se může připojit na zde popisovaný herní server, je nutné dodržet několik zásad. Odesílání a načítání dat probíhá podle pevného scénáře, kdy zašleme nebo přečteme počet bajtů budoucí zprávy a pak teprve zprávu samotnou. Náš klient by měl umět zpracovávat zprávy, které odpovídají rozhraním IHrac a IKlient. Příslušné třídy a rozhraní jsou spolu s popisem součástí zdrojových kódů, lze je přímo převzít nebo naimplementovat podobně. Náš klient pak musí na každou zprávu, která má v rozhraní definovanou návratovou hodnotu, zaslat příslušnou odpověď (třídy i s popisem jsou opět k dispozici). Hesla uživatelů jsou zasílána jako MD5 hash zadaného stringu.
31
Kapitola 4 Porovnání s existujícími programy 4.1
Pivoňka software - RE!
RE! je v Čechách prakticky legendární software vytvořený ještě pro operační systém MS DOS. Na svou dobu přinesl velmi dobré schopnosti počítačů a dodnes nepřekonané ovládání, i když jen klávesnicí. Oficiální stránky programu neexistují, kompilovaná verze se však sehnat dá. V dnešní době přináší problémy se spouštěním pod operačními systémy jako je Windows Vista a také uživatele neoslovuje svým grafickým zpracováním. Přesto byl tento program pro mě největším vzorem při vývoji a také je mnohými hráči stále považován za nepřekonaný. Dle mých subjektivních porovnání a také porovnání dalších lidí, kteří testovali můj program, se podařilo dosáhnout lepší inteligence počítačových hráčů než jaká je v tomto programu. Program RE! neměl prakticky žádné možnosti nastavení, a to jak pravidel hry, tak uživatelského rozhraní. Dovolím si tvrdit, že ve všech ohledech kromě jednoho se povedlo RE! překonat. Co zbývá udělat a z čeho si beru do budoucna příklad, je možnost a rychlost ovládání hry jen pomocí klávesnice. I když tento styl ovládání není intuitivní pro nové hráče, je velmi dobrý pro zkušené uživatele programu, kteří chtějí odehrát hodně her, a to buď proti počítačům nebo přes internet.
4.2
Falasoft - Becherovka mariáš
Becherovka mariáš [11] umožňuje pouze hru voleného mariáše, a tak se trochu liší od mého programu, který umožňuje naopak hru licitovaného mariáše. Přesto se pokusím o porovnání v ostatních ohledech. Tento program je již programován pro Windows, i když je na něm nyní vidět jistá dávka zastaralosti. Ovládání lze hodnotit vcelku kladně, co bych ale programu vytknul je velká nepřehlednost karet, které mám v ruce. Další nevýhodou pro nové hráče je, že program je málo 32
vede k tomu, co dělat, a nechává předvolené výchozí volby - například řeknu, že barva je špatná, a pokud nic nezměním, znamená to, že budu hrát betl. Rovněž možnosti nastavení programu a pravidel jsou velice omezené. Inteligence protihráčů není na špatné úrovni, ovšem je také třeba brát v úvahu, že volený mariáš je celkově jednodušší než mariáš licitovaný. Celkově shrnuto je program překonán ve všech ohledech.
4.3
Jakub Vrána - Čtyřka
Mariáš Čtyřka [10] se od mého programu také liší zvolenou variantou hry, ale i tak je zajímavý. Vzniknul jako ročníkový projekt autora na MFF UK, poté jej autor o něco rozšířil a pokusil se na tom něco vydělat, takže je program poskytován jako shareware, i když se již dávno nevyvíjí. Pravděpodobně vzhledem k zápisům do registru nebo na nevhodná místa na disku má program problémy s během pod Vistou, ale po přeuložení nastavení se rozeběhne. Z hlediska inteligence si program nestojí špatně, ale opět se zde jedná o zcela jiný přístup kvůli hře čtyřech hráčů. Možnosti nastavení jsou rozsáhlé, je podporována i hra přes internet. Ovládání až na některé detaily hodnotím kladně, zajímavé jsou i namluvené proslovy hráčů. Z tohoto programu si do budoucna jako námět beru hlavně dodělání zvuků do aplikace.
4.4
talon.cz
V současné době jediný rozvíjející se projekt je talon.cz [9], jehož hlavním cílem je online hra na zmiňovaných stránkách. Umožňuje hru licitovaného, voleného mariáše i čtyřky, k dispozici je i verze programu pro stažení a hru s počítači (jen licitovaný a volený). Ovládání programu je i pro zkušeného hráče mariáše málo intuitivní, ale dá se na něj po čase zvyknout. Nepřehlednost se projevuje hlavně při výběru hlášené hry a odhození talonu nebo při licitaci, kdy jsme o krocích protivníků informováni textově ve společném rámečku pro všechny události nebo jen těžko zahlédnutelnými bublinami. Verze zdarma nemá prakticky žádné možnosti nastavení, placená verze umožňuje nastavit něco málo navíc. Na inteligenci automatů jsem neshledal žádné vážnější nedostatky. Přehlednost webu hodnotím jako velmi špatnou, stejně tak náhledy do historie her. Možnosti hry po internetu, jako je mariášová liga, poháry, počítání bonusových bodů nebo statistiky hráčů jsou naopak velmi rozsáhlé. Z tohoto projektu bych si chtěl vzít příklad hlavně pro zlepšování možností hry přes internet, protože je vidět, že i přes to, že většina služeb je placených, tak se uchytil a netrpí nedostatkem hráčů.
33
4.5
Shrnutí
Oproti aplikacím dostupným na trhu se dle mého názoru povedlo naprogramovat aplikaci, která je uživatelsky přívětivá a vhodná i pro začátečníky. Rovněž z hlediska možností nastavení pravidel jde aplikace zdaleka nejdál, pokud porovnáváme aplikace umožňující hru licitovaného mariáše. Do budoucna by se měla aplikace zlepšovat hlavně v možnostech síťové hry, například statistiky hráčů, mariášová liga, centralizace herního serveru nebo zlepšování grafického rozhraní při síťové hře. Dále bych se rád zaměřil také na pokročilé hráče, což znamená přidat funkce jako ovládání z klávesnice, více informací o snímání a pořadí karet, bonusové body nebo omezení nápovědy počítačem při síťové hře.
34
Kapitola 5 Závěr V prezentované aplikaci se povedlo implementovat požadovanou funkcionalitu. Hráč si může pro hru na vlastním počítači nebo přes internet libovolně nakonfigurovat pravidla, možnosti nastavení jsou relativně rozsáhlé. V libovolném stavu hry lze danou relaci her uložit a poté ji do stejného stavu obnovit. Komunikace po internetu probíhá přes vlastní otevřený protokol na bázi XML, navíc je aplikace rozdělena do samostatných modulů jádra, grafického rozhraní a serveru. Herní server automaticky ukládá hry a také umožňuje jejich obnovení, což je ideální předpoklad pro nasazení jednoho centrálního serveru. Přínosem je také moderní a intuitivní grafické rozhraní spolu s jednoduchou instalací a automatickou aktualizací na nové verze programu. Z hlediska umělé inteligence se povedlo implementovat hru na rozumné úrovni, počítačoví hráči většinou nedělají žádné zjevné chyby, bohužel ale úrovně profesionálních hráčů ještě nedosahují. Jako poslední věc bych rád zhodnotil možnosti zobrazení historie celé relace her, kde jsou k dispozici snad všechny myslitelné údaje, a lze tak přehledně studovat, kdo měl jaké karty nebo kdy udělal chybu. Je mnoho vylepšení, která by se mohla do aplikace dodělat. Následuje seznam těch nejzajímavějších: • Rozšíření o další varianty hry - přidání voleného mariáše nebo čtyřky, implementačně náročnější hlavně pro variantu čtyřka, protože by bylo nutné přeuspořádat grafické rozhraní a přepsat část jádra a metod umělé inteligence. • Zlepšovat umělou inteligenci - stále je co vylepšovat, a to ve všech oblastech. Největší zlepšení lze očekávat od lepšího zpracování informací o hře jako je tato: pokud hráč končil licitaci na sedmě lepší, je pravděpodobné, že bude mít alespoň tři nebo čtyři karty od červené barvy. Tyto informace by měly upravovat pravděpodobnostní rozdělení karet a měnit tak výsledky postupů statické i minimaxové části umělé inteligence. • Ovládání hry z klávesnice - možnost kompletně ovládat hru nebo alespoň část, kde vybíráme naše akce, z klávesnice, hlavně pro zrychlení. 35
• Počítání prémiových bodů z hlediska profesionálního mariáše a informace o tom, kolik karet bylo sejmuto. • Více možností on-line hry, možnost hrát ligu nebo statistiky hráčů. • Další sada karet - druhá sada obrázků karet, které jsou běžně hráčům známé, jako je Piatnik nebo Kolínské tiskárny. • Průvodce začátečníka - vysvětlí názorně pravidla hry, ukáže vzorovou hru a v průběhu prvních her bude napovídat. • Přepsání částí serveru pro použití SQL databáze, zprovoznění jednoho centrálního serveru.
36
Literatura [1] Adam Nathan: Windows Presentation Foundation Unleashed, Sams Publishing, 2007, ISBN 0-672-32891-7 [2] Miroslav Virius: Od C++ k C#, KOPP, 2002, ISBN 80-7232-176-5 [3] Oficiální pravidla licitovaného mariáše a mariáše obecně: http://www.marias.cstv.cz/licitovany_marias/2008/Pravidla_2008. doc http://www.marias.cstv.cz/2008/Obecna_pravidla_hry_ marias-finalni_navrh.doc [4] Třída pro zobrazování bublin: http://pavanpodila.spaces.live.com/blog/cns!9C9E888164859398! 289.entry http://blogs.msdn.com/llobo/archive/2007/07/11/ wpf-balloon-comments.aspx [5] Návod na tlačítka s obrázky: http://blogs.msdn.com/mikehillberg/archive/2007/02/01/ ParameterizedTemplates.aspx [6] Nástroj pro převod vektorové grafiky do XAML: http://www.mikeswanson.com/XAMLExport/ [7] Blog týkající se WPF: http://www.beacosta.com/blog/ [8] Projekt Mono (.NET pro Linux): http://www.mono-project.com/ [9] Online herní server mariáše: http://www.talon.cz/ [10] Mariáš na počítači pro čtyři hráče: http://ctyrka.vrana.cz/
37
[11] Becherovka mariáš na počítač: http://www.falasoft.com/cz/karty [12] Třída pro generování kombinací http://www.codeproject.com/KB/recipes/combinatorial_in_csharp. aspx
38
Příloha A Obsah přiloženého DVD Na přiloženém disku lze najít následující obsah: • Instalátor aplikace - instalaci lze spustit kliknutím na soubor setup.exe. Pokud nemáte na svém počítači rozhraní .NET Framework 3.0 nebo vyšší, bude toto rozhraní v průběhu instalace doinstalováno. • Zdrojové kódy - v adresáři Source je kompletní projekt pro Visual Studio 2008 spolu se soubory s grafikou a nápovědou. • Dokumentace - tento text bakalářské práce ve formátu PDF a generovanou programátorskou dokumentaci lze najít v adresáři Documentation. Ve stejném adresáři lze také najít schéma XML souborů komunikačního protokolu pro hru po síti (RenoncProtocol.xsd), které je příliš dlouhé pro vložení do tohoto textu.
39
Příloha B Nejdůležitější vlastnosti programu • hra licitovaného mariáše proti počítačovým protivníkům • implementuje ložené hry, není nutné dohrávat zcela jasnou hru • umožňuje tzv. hry proti • rozsáhlé možnosti konfigurace pravidel mariáše • historie odehraných her v relaci s velkým množstvím informací • počítačoví protivníci jsou na rozumné úrovni a dodržují zavedené způsoby hry • možnost ukládání a načítání hry v libovolném okamžiku • hra přes internet s automatickým ukládáním rozehrané relace • moderní a intuitivní grafické rozhraní • nápověda, jak hrát, od počítače • automatická instalace nových verzí aplikace
40
Příloha C Uživatelská dokumentace C.1
Popis programu
Program je určen pro hru licitovaného mariáše proti počítači. Umožňuje hru 1 lidského hráče proti 2 počítačům a hru po síti s libovolnou kombinací počítačových a lidských protivníků. Program je kompletně v češtině, umožňuje ukládání a načítání stavu hry (i při hře po síti) a nastavení různých modifikací mariášových pravidel.
C.2
Požadavky na HW, SW
Je vyžadován operační systém Windows XP Service Pack 2 a vyšší nebo Windows Vista. Při vypnutí animací v nastavení programu běží program rozumně na jakémkoliv počítači schopném provozovat zmíněné operační systémy. Při instalaci na Windows XP dojde v případě potřeby k instalaci prostředí .NET Framework 3.0.
C.3
Instalace
Instalace probíhá přímo z webových stránek projektu, které jsou dostupné na adrese http://marias.aspweb.cz. V sekci Stáhnout lze najít instalační soubor setup.exe. Po spuštění instalátoru budete upozorněni, zda opravdu chcete instalovat aplikaci neznámého vydavatele, potvrďte kliknutím na Nainstalovat. Na systému Windows XP může dojít před samotnou instalací programu ještě k instalaci běhového prostředí .NET Framework 3.0. Bez přítomnosti tohoto prostředí nebude program fungovat! Při prvním spuštění program vyžaduje potvrzení licenčního ujednání.
41
C.4
Jak rychle začít po instalaci
Pokud nechcete studovat celý tento návod a znáte pravidla mariáše (pokud ne, je nejlepší je nejprve prostudovat, viz sekce C.10), můžete rychle začít tak, že si spustíte okno Nastavení, kde nastavíte Vaše jméno a jména protihráčů. Následně kliknutím na Pravidla pro nové hry otevřete okno, kde nastavíte pravidla podle Vašich zvyklostí. Výchozí nastavení pravidel a cen her odpovídá oficiálním pravidlům podle Českého svazu mariáše. Vše potvrdíte stiskem OK a po kliknutí na tlačítko Nová hra můžete začít ihned hrát.
C.5
Hlavní okno programu
Hlavní okno programu obsahuje následující podstatné části (viz obrázek C.1): • oblast hlavních tlačítek (nahoře přímo pod lištou programu), • prostřední oblast s dotazy na uživatele a aktuálním štychem, • oblast s kartami uživatele (dole v okně, přímo nad dolním okrajem), • informační rámečky o nahlášených hrách a flecích, • informační rámečky se stavem jednotlivých hráčů.
C.5.1
Oblast hlavních tlačítek
Oblast hlavních tlačítek obsahuje následující prvky. • Nová hra - začne novou hru, všichni hráči začínají na skóre 0, prázdná historie. • Načíst hru - načte uloženou hru ze souboru, výběr probíhá přes standardní dialog Windows. • Uložit hru - uloží právě rozehranou hru do souboru s příponou .rms. • Ukončit hru - ukončí právě probíhající hru bez uložení. • Historie - zobrazí historii právě probíhající hry. • Hrát on-line - umožní připojení k serveru a start hry přes internet. • Nastavení - umožňuje nastavit pravidla hry, jména hráčů a další. • Nápověda - zobrazí nápovědu na webu. • O programu - zobrazí informace o verzi programu a autorovi. • Ukončit - ukončí běh aplikace. 42
Obrázek C.1: Hlavní okno programu
C.5.2
Prostřední oblast
Zde se objevuje aktuální štych (karty, které zrovna leží na stole) nebo dotazy pro uživatele. Význam jednotlivých dotazů se odvíjí od pravidel mariáše, viz příslušná sekce dokumentace. Zobrazení aktuálního štychu respektuje pořadí karet, tj. podle toho, jak jsou karty překryty, lze poznat, kdo nesl jako první, druhý, resp. poslední. Rovněž poloha karty analogicky určuje hráče, který danou kartu vynesl.
C.5.3
Oblast s kartami uživatele
Zde jsou vyobrazeny všechny karty, které máte aktuálně „v ruceÿ. Pokud herní situace vyžaduje volbu karty, kartu vybereme jednoduše kliknutím na její obrázek. Význam jednotlivých obrázků na kartách lze najít v příslušné části této dokumentace. Karty mohou být dle stavu hry po najetí animovány, což znamená, že daná karta je povolena k zahrání nebo jiné akci, nebo mohou být naopak „zašedléÿ, což znamená, že danou kartu nelze zahrát nebo vybrat. Animace nebo průhlednost neplatných karet lze nastavit v nastavení programu. Způsob řazení karet podle hodnoty závisí rovněž na nastavení, viz příslušná část dokumentace.
C.5.4
Informační rámečky
Na obrazovce jsou vidět tři informační rámečky s ikonkou člověka, každá obsahuje informaci o jednom z hráčů. Jména všech hráčů lze nastavit v nastavení hry (to 43
neplatí pro síťovou hru, kde jsou automaticky načtena ze serveru). Dále se zde zobrazuje skóre (průběžně počítáno podle odehraných her), výchozí skóre všech hráčů je 0. V každém rámečku se také ukazuje aktuální pozice hráče vzhledem k mariášové hře (forhont x zadák x rozdávající) a aktuálně zahlášené hlášky, které jsou vyjádřené ikonkou barvy vyneseného svrška. Rámečky se zahlášenými hrami a fleky na dané hry informují o tom, jaká hra nebo jaké hry se právě hrají a kdo dával kolik fleků.
C.6
Historie
Po kliknutí na tlačítko Historie zobrazíme historii aktuální série her. V levé části okna lze kliknutím vybrat hru, o které chceme zobrazit informace. Zvolená hra je zvýrazněna červenou barvou textu, po novém vyvolání je vybrána aktuálně hraná hra. Ve zbývající části okna jsou zobrazeny odehrané štychy a další informace o hře, jako jsou hlášené hry, kdo na co licitoval, fleky, atd. Po skončení dané hry je také možné zobrazit karty všech hráčů ze začátku hry, co bylo v talonu a pokud to má smysl, tak i nový talon a karty hráče, který si vylicitoval hru, před obdržením talonu. K jednotlivým zahlášeným hrám se zobrazí i jejich výsledek.
C.7
Hra po síti
Po stisknutí tlačítka Hrát on-line se zobrazí okno, které nám umožní se připojit a přihlásit k hernímu serveru pro hru přes internet. Pokud chceme založit server na našem počítači, můžeme použít tlačítko Spustit server lokálně. Ostatním hráčům pak sdělíme naší IP adresu, kterou lze jednoduše zjistit například na stránce http://www.whatismyip.com. Vámi spuštěný server lze zastavit tlačítkem Zastavit lokální server. Pole port necháváme většinou na výchozí hodnotě, pokud nám správce serveru neřekl jinak. Na vlastní server se připojíme zadáním adresy „localhostÿ, na ostatní servery se připojujeme zadáním adresy IP. Pokud se na daný server připojujeme poprvé, je nutné se zaregistrovat. Po kliknutí na tlačítko Zaregistrovat a zadání uživatelského jména, hesla, přezdívky (nebo celého jména) a e-mailu stistkutím OK dokončíme registraci. Dále se již jen přihlašujeme zadáním našeho uživatelského jména a hesla a kliknutím na tlačítko Připojit.
C.7.1
Výběr a spuštění hry
Po přihlášení se na server máme na výběr ze dvou seznamů her. Jeden ukazuje nově založené hry, ve kterých je ještě volné místo, a druhý hry, které jsme rozehráli v minulosti. U každé hry jsou zobrazeni hráči, kteří ji hráli, a navíc čas první a poslední odehrané hry. U počítačových protivníků je jako jméno zobrazeno AI. Pokud chceme znovu načíst seznamy aktuálních her, klikneme na tlačítko Načti znovu. Tlačítkem Připojit se do hry zaujmeme volné místo v nově zakládané hře. 44
Sami můžeme novou hru založit kliknutím na tlačítko Založit hru. Pokud chceme pokračovat v dříve rozehrané hře, zvolíme ji a klikneme na Obnovit hru. Do této hry se můžou připojit jen její původní hráči. Po startu hry dojde k obnovení původního nastavení pravidel a všech odehraných her. Po připojení do hry se zobrazí okno, které zobrazuje aktuálně připojené uživatele a umožňuje komunikaci s nimi. Ke komunikaci slouží rámeček Chat, textové pole, do kterého píšeme naši zprávu, a tlačítko Odeslat, které ji pošle všem ostatním hráčům v dané hře. Vpravo nahoře vidíme stav jednotlivých míst ve hře, pro každé místo je zde vidět buď jméno hráče, který je zde připojen (v případě obnovované hry to může být i jméno se stavem nepřipojen, což znamená, že toto místo musí obsadit daný hráč) nebo AI pro počítačového protivníka. Volné místo je označeno textem Nepřipojen. První hráč u stolu, tzn. ten, kdo je na prvním místě ve výše zmíněném rámečku, může nastavovat pravidla hry, obsazení míst počítačovými protivníky a také spustit hru, jakmile jsou všichni připraveni. Ostatní hráči tato nastavení mohou zobrazit, ale nemohou je měnit. Tlačítkem Odpojit můžeme danou hru opustit. Po spuštění síťové hry máme k dispozici nové tlačítko Chat, které slouží ke komunikaci s lidskými protihráči. Po odeslání se zpráva všem zobrazí v bublině u jejího odesílatele.
C.8
Nastavení
Po stisknutí tlačítka Nastavení se objeví okno, kde můžeme nastavit základní vlastnosti hry. Nová nastavení potvrdíme stiskem OK, kdy dojde k jejich uložení. Následuje popis jednotlivých prvků. • Moje jméno - nastavuje jméno, které se bude zobrazovat u Vámi provedených činností. • Jméno protihráče vlevo - nastavuje jméno prvního počítačového protihráče ve směru hodinových ručiček. • Jméno protihráče vpravo - nastavuje jméno druhého protivníka. • Doba zobrazení bubliny (ms) - lze vložit celé číslo větší nebo rovné nule, udává dobu, po kterou bude zobrazena bublina u hráče (hra bude na tuto dobu pozastavena). • Průhlednost neplatných karet - lze vložit celé číslo od nuly do sta, 0 znamená neviditelnou kartu, 100 plnou viditelnost, tímto údajem nastavíme, jak dobře budou vidět karty, které nelze v dané situaci zvolit nebo zahrát. • Řadit implicitně desítku pod spodka - pokud je zatrženo, tak ve stavu, kdy ještě není nahlášena hra, bude program řadit desítky mezi devítku a spodka namísto standardního řazení mezi krále a eso. 45
• Přeřadit karty podle typu aktuálně hrané hry - pokud je zatrženo, tak program změní řazení karet podle aktuálně hrané hry, tj. například pro betla řadí desítku pod spodka a pro stovku mezi eso a krále. • Animovat karty při najetí - pokud je zatrženo, tak při najetí kurzorem myši nad platnou kartu dojde k animaci na větší velikost. • Pravidla aktuální hry - zobrazí pravidla aktuálně hrané hry, pokud se nějaká hraje. • Pravidla pro nové hry - umožní nastavit pravidla pro nové hry. Pravidla hry se skládají ze dvou částí, a to jsou ceny jednotlivých her a nastavení pravidel. Pravidla hry ani ceny nelze při spuštěné hře již měnit, navíc zůstávají v platnosti i pro uložené hry. Před začátkem nové série her je dobré si zkontrolovat, zda Vám současné nastavení vyhovuje. Pravidla pro nové hry zůstávají stejně jako další nastavení uložena i po skončení programu. Jako ceny vkládáme požadovanou cenu bez fleků v haléřích, celá čísla větší nebo rovná nule. Dále následuje vysvětlení zbylých nastavení. • Ve dvou sedmách je hodnota desítky pod spodkem - pokud je zaškrtnuto, je při hře dvě sedmy počítána desítka hodnotou mezi spodka a devítku. • Ve dvou sedmách lze shazovat desítky do talonu - pokud je zaškrtnuto, lze při hře dvě sedmy shazovat desítky a esa do talonu. • Cena stovky se s každou desítkou násobí dvěma - při zaškrtnutí počítá výsledek nad uhrané sto násobením dvěma za každou desítku, jinak připočítá za každou desítku navíc jen základní cenu; příklad: uhráno 120, základní cena 40 hal, při zaškrtnutí je cena 40 * 2 * 2 = 160 haléřů, jinak je 40 + 40 + 40 = 120 haléřů. • Lze hlásit sedmu aniž ji mám v ruce - povolí zahlásit hru sedma, i když sedmu dané barvy nemám v ruce. • Po vylicitování obyčejné sedmy lze složit hru - pokud si vylicituji hru sedma (ne sedma lepší), povolí po shlédnutí talonu karty složit bez hry. • Je povoleno hlásit sedmu proti - povolí všem protivníkům hlásit hru sedma proti. • Je povoleno hlásit stovku proti - povolí všem protivníkům hlásit hru stovka proti. • Stovka lepší je vyšší hra než stosedm obyčejných - mění pořadí her při licitaci, při zaškrtnutí máme pořadí stovka, stosedm, stovka lepší, stosedm lepších, jinak máme pořadí stovka, stovka lepší, stosedm, stosedm lepších. 46
• Do uhrání stovky se počítá první vynesená hláška - zaškrtnutí způsobí, že k uhrání stovky se počítá první hláška, ne nejvyšší hláška. • Povinný flek na hru při sedmě, pokud mám trháka - udává hráčům povinnost flekovat na hru při hře sedma, pokud mají svrška nebo krále trumfové barvy. • Míchat karty po každé hře - namísto složení balíčků na sebe a sejmutí provede po každé hře míchání balíčku. • Započítat forhontovi výdělek, pokud všichni řeknou pass - pokud si nikdo nic nevylicituje, započítá forhontovi nastavenou cenu za pass. • Sedma bez fleku na hru nebo na sedmu se nehraje - pokud nikdo neflekuje na hru nebo na sedmu (při hře sedma), hra se skládá s výhrou hlásícího hráče. • Sedma s jedním flekem na hru a bez fleku na sedmu se nehraje - pokud padne při hře sedma jen jeden flek na hru a žádný na sedmu, hra se skládá (typicky s nulovým výsledkem). • Maximální počet fleků na jednu hru - stanoví maximální počet fleků na jednu část hry, které můžou padnout; vkládáme celé číslo větší nebo rovné nule, nula udává neomezený počet fleků.
C.9
Server pro konzoli
Součástí instalace je i spouštěcí program pro samostatný běh serveru. Ten se nachází v souboru RenoncMarias.ConsoleServer.exe. Po jeho spuštění zadáme číslo portu, na kterém bude server očekávat příchozí spojení (celé číslo, pokud nevíte jaké, zadejte 9540) a potvrdíme stiskem klávesy Enter. Po dalším stisknutí klávesy Enter bude server ukončen. Tento soubor lze (s příslušnými knihovnami RenoncMarias.Core.dll a RenoncMarias.Server.dll) spustit i v rámci projektu Mono například pod Linuxem.
C.10
Pravidla mariáše
Pravidla lze najít například na adrese http://www.marias.cstv.cz/2008/Obecna_ pravidla_hry_marias-finalni_navrh.doc. Pravidla soutěžního mariáše naleznete zde: http://www.marias.cstv.cz/licitovany_marias/2008/Pravidla_2008.doc.
C.11
Karty
Náhled na použité obrázky karet spolu s popisky naleznete na obrázku C.2. 47
Obrázek C.2: Použité obrázky karet
48