Implementace deskové hry ======================== [listopad 2010, revize listopad 2015, revize září 2017] Požadavky --------- - oddělení implementace výkonné části (logika) od implementace UI části - možnost použít stejnou logiku s různým UI (výměna textové konzole za GUI) - minimální rozhraní logiky pro UI - ideálně jen pro řízení hry, ale kvůli efektivitě i pro zobrazení hrací desky, historie tahů aj. - žádné rozhraní UI pro logiku - úplná nezávislost logiky na UI! - platformově nezávislá implementace logiky, např. formou sdílené knihovny - UI může být platformově závisle implementované, ale lze i nezávisle (konzole, multiplatformní GUI knihovny, OpenGL, Java Swing/FX apod.) Postup --------------------------------------------------------------------- Hrací deska = stavy políček (prázdné, typ a barva figurky) = (dvojrozměrné) pole čísel, pojmenované dat. typy, např. prázdné 0, bílé < 0, černé > 0 - inicializace desky - nějaké rozestavění figurek UI = textová konzole - zobrazení hrací desky Tah = posloupnost indexů do pole desky a dvou stavů políček (aktuálního a nového) = posloupnost (dvojic) čísel, délka: poslední prvek zarážka nebo první prvek počet UI - textové zadání tahu lidským hráčem (dokud nezadán správně), po zobrazení desky - [debug] zobrazení zadaného tahu Hrací deska - provedení tahu = změna desky, kontrola jen tah na desce UI - (nekonečný) cyklus zobrazení desky, zadání tahu, volání provedení tahu = "řízení" hry Pravidla - inicializace desky (přesun z Hrací desky) - výchozí rozestavění figurek - inicializace hráče na tahu = číslo barvy hráče, např. bílý -1, černý 1 - změna hráče na tahu - kontrola platnosti tahu = je táhnuto figurkou hráče na tahu? UI - zobrazení hráče na tahu, po zobrazení desky - volá kontrolu platnosti tahu, před provedením tahu - zobrazení hlášky o neplatnosti tahu + zpět na zadání tahu pokud kontrola neuspěje - volá změnu hráče na tahu, po provedení tahu Řízení hry - volané z UI po zadání tahu, se zadaným tahem - volá kontrolu platnosti tahu (místo UI), speciální návrat do UI, pokud kontrola neuspěje - volá provedení tahu (místo UI) - volá změnu hráče na tahu (místo UI) - návrat do UI = "pasivní" řízení hry aktivované z UI UI - zobrazení hlášky o neplatnosti tahu při speciálním návratu z Řízení hry Pravidla - výpočet všech možných tahů (včetně všech mezistavů políček - braní figurky při skoku, vícenásobné skoky, povýšení figurky apod.) platných podle pravidel pro danou figurku = seznam tahů UI - volitelně zobrazení všech tahů zvolené figurky - "nápověda", po zadání první pozice tahu (figurky) Pravidla - kontrola platnosti (neúplného) tahu += je v seznamu všech (úplných) tahů pro danou figurku? - rozšíření úspěšné kontroly o doplnění (neúplného) tahu o mezistavy políček -> nahrazení (úplným) tahem ze seznamu - výpočet všech možných tahů platných podle pravidel pro všechny figurky daného hráče = sjednocení seznamů pro každou figurku (+ příp. odstranění neskoků aj.) - opravení kontroly platnosti tahu - je v seznamu všech tahů hráče na tahu? UI - [debug] zobrazení všech tahů hráče na tahu Pravidla - test konce hry (výhra, prohra, remíza) - podle desky a seznamu všech tahů hráče na tahu, odložit testy, pro které je potřeba historie tahů Řízení hry - volání testu konce hry před nebo po změně hráče na tahu, speciální návrat do UI, pokud test uspěje UI - zobrazení výsledku hry při speciálním návratu z Řízení hry, po zobrazení desky Mozek - výběr nejlepšího tahu ze seznamu všech tahů daného hráče - náhodný výběr UI - inicializace nastavení hráčů: lidský vs. počítačový = číslo pro barvu hráče, "inteligence" hráče = číslo, např. lidská < 0, počítačová > 0 - volba pro nastavení hráčů, vedle zadání tahu lidským hráčem - výběr nejlepšího tahu místo zadání tahu lidským hráčem, pokud je na tahu počítačový hráč Řízení hry - nevolání kontroly platnosti tahu, pokud je na tahu počítačový hráč Hrací deska - provedení tahu zpět = Tah "pozpátku" Mozek - ohodnocení desky: hodnoty figurek, pozice figurek -> tahy ze seznamu všech tahů daného hráče (braní figurky při skoku, vícenásobné skoky, povýšení figurky apod.), konec hry, moje figurky +, soupeřovy -, souhrnné číslo - výběr nejlepšího tahu - algoritmus MiniMax, AlfaBeta apod., provádění tahu a tahu zpět na (jediné) kopii desky! - [debug] zobrazení (průběhu výběru) vybraného tahu UI - volba pro nápovědu tahu, pokud je na tahu lidský hráč, vedle zadání tahu - nápověda tahu = spuštění výběru nejlepšího tahu pro lidského hráče - možnosti zrušení zadávání tahu od lidského hráče a použití napovězeného tahu --------------------------------------------------------------------- Mozek - výběr nejlepšího tahu do samostatného vlákna - uložení vybraného tahu do sdílené proměnné - chráněný přístup! - signalizace UI o (průběhu) výběru - např. vyvolání události Řízení hry - nastavení hráčů zruší výběr nejlepšího tahu = ukončení vlákna UI - "čekání" na signalizaci od Mozku po spuštění výběru nejlepšího tahu - pasivní!, např. obslužná funkce události, aktivní čekání na zadání voleb - volba pozastavení, znovurozběhnutí a zrušení výběru nejlepšího tahu = vlákna - volitelně zobrazení průběhu výběru tahu, po signalizaci od Mozku - volání Řízení hry po finální signalizaci od Mozku (zadání tahu), s tahem načteným ze sdílené proměnné - nápověda tahu = pasivní čekání na finální signalizaci od Mozku, aktivní čekání na zadání voleb a tahu lidského hráče, zobrazit vybraný tah po finální signalizaci od Mozku, pokud nebyl zadán tah lidským hráčem - zrušit generování nápovědy tahu při zadání tahu od lidského hráče Hrací deska, Řízení hry - uložení a načtení desky, nastavení hráčů a hráče na tahu UI - volby pro uložení do a načtení ze souboru - textového (TXT, XML) Hrací deska - historie tahů = 1. seznam tahů a aktuální pozice v něm nebo 2. dva zásobníky, pro undo a redo tahy - inicializace historie tahů = vyprázdnění 1. seznamu a nastavení aktuální pozice v něm na konec (= začátek) nebo 2. obou zásobníků - po provedení tahu z Řízení hry 1. smazání seznamu od aktuální pozice dál, tah na aktuální pozici (= konec seznamu) a její nastavení za tah (= konec seznamu) nebo 2. tah do undo zásobníku a vyprázdnění redo zásobníku - undo/redo: 1. změna aktuální pozice v seznamu o tah zpět/, provedení inverzního/ tahu na aktuální pozici a změna aktuální pozice v seznamu o tah /vpřed nebo 2. výběr tahu z undo/redo zásobníku a vložení do redo/undo zásobníku, provedení inverzního/ tahu ze zásobníku - uložení historie tahů = 1. seznamu a aktuální pozice v něm nebo 2. obou zásobníků Pravidla - doplnění testu konce hry (výhra, prohra, remíza) - o testy, pro které je potřeba historie tahů UI - zobrazení historie tahů: 1. seznamu od konce po zacatek a aktualni pozice v nem nebo 2. redo zasobniku od dna po vrchol a undo zasobniku od vrcholu po dno, po zobrazení desky - volby pro undo/redo - undo/redo: speciální volání Řízení hry Řízení hry - volání provedení undo/redo místo načtení a volání kontroly a provedení tahu při speciálním volání z UI - undo/redo zruší výběr nejlepšího tahu UI - volba pro replay, po zobrazení výsledku hry - replay: celkové undo, krokované redo - volby při replay: pauza, zpět = undo, vpřed = redo, na začátek = celkové undo, na konec/stop = celkové redo - volby pro novou hru, ukončení hry aj. - zruší výběr nejlepšího tahu - nahrazení textové konzole GUI - grafické zobrazení desky, hráče na tahu, historie apod., zadávání tahu lidského hráče myší, menu místo voleb, smyčka zpracování událostí místo (nekonečného) cyklu, ... žádné změny logiky!