Gymn´azium Praha 6, Arabsk´a 16
ˇ Sachy ˇn´ıkove ´ho Projektu Dokumentace Roc Autor
Tˇr´ıda
Ondˇrej N´ yvlt
1. E
Vyuˇ cuj´ıc´ı
Tom´ aˇs Obdrˇz´alek
Pˇredmˇ et
Programov´an´ı
18. kvˇetna 2014
Obsah ´ 1 Uvod 1.1 Anotace . . . . . . . . . . . . . 1.2 Prohl´ aˇsen´ı . . . . . . . . . . . . 1.3 Pozn´ amky . . . . . . . . . . . . 1.4 Zad´ an´ı . . . . . . . . . . . . . . 1.4.1 Z´ akladn´ı funkcionalita . 1.4.2 Bonusov´ a funkcionalita
. . . . . .
1 1 1 1 1 1 2
2 Hra 2.1 Historie hry . . . . . . . . . . . . . . . 2.2 Princip hry . . . . . . . . . . . . . . .
2 2 2
3 Aplikace 3.1 Pouˇzit´e technologie . . . 3.2 Ovl´ ad´ an´ı . . . . . . . . . 3.3 N´ avrh . . . . . . . . . . 3.4 Struktura projektu . . . 3.4.1 View . . . . . . . 3.4.2 Model . . . . . . 3.4.3 ViewModel . . . 3.5 Aplikaˇcn´ı logika . . . . . 3.5.1 Kliknut´ı na pole 3.5.2 Z´ısk´ an´ı tah˚ u . . 3.5.3 Proveden´ı tahu .
3 3 3 4 5 5 6 6 7 7 8 9
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
phical user interface. App is designed for PCs and is capable of handling two-player game – player vs. computer game mode is not available.
1.2
Prohlaˇsuji, ˇze jsem jedin´ ym autorem tohoto projektu, vˇsechny citace jsou ˇr´adnˇe oznaˇcen´e a vˇsechna pouˇzit´a literatura a dalˇs´ı zdroje jsou v pr´aci uveden´e. T´ımto dle z´akona 121/2000 Sb. (tzv. Autorsk´ y z´akon) ve znˇen´ı pozdˇejˇs´ıch pˇredpis˚ u udˇeluji bez´ uplatnˇe ˇskole Gymn´azium, Praha 6, Arabsk´ a 14 opr´avnˇen´ı k v´ ykonu pr´ava na rozmnoˇzov´an´ı d´ıla (§ 13) a pr´ava na sdˇelov´an´ı d´ıla veˇrejnosti (§ 18)
Datum
1.3
4 Z´ avˇ er 9 4.1 V´ yvoj n´ avrhu, probl´emy . . . . . . . . 9 4.2 Splnˇen´ı zad´ an´ı . . . . . . . . . . . . . 10
1 1.1
Prohl´ aˇ sen´ı
M´ısto
Autor
Pozn´ amky
V tomto dokumentu doch´az´ı ke vzniku mnohoznaˇcn´ ych pojm˚ u. Aby nevznikala nedorozumnˇen´ı, uv´ad´ım n´asleduj´ıc´ı pokyny: Pojem pole v tomto dokumentu oznaˇcuje oblast pr˚ uniku ˇr´adku a sloupce na mˇr´ıˇzi ˇsachovnice nebo objekt typu Square ˇci jeho grafickou interpretaci v uˇzivatelsk´em rozhran´ı. Ve v´ yznamu datov´e struktury array nen´ı pouˇzit.
´ Uvod Anotace
Pojmy aktivn´ı pole, vybran´e pole, povolen´y tah, zak´ azan´y tah atd. existuj´ı pouze v r´amci aplikace a nevyskytuj´ı se ve hˇre ˇsachy.
C´ılem projektu bylo vytvoˇrit implementaci klasick´e strategick´e deskov´e hry ˇsachy, kde dva hr´aˇci proti sobˇe soupeˇr´ı posouv´ an´ım figurek po ˇsachovnici. Aplikace je postavena na .NET frameworku s vyuˇzit´ım programovac´ıho jazyka C# a technologie WPF pro grafick´e uˇzivatelsk´e rozhran´ı. Aplikace je navrˇzena pro PC a umoˇzn ˇuje hru dvou hr´ aˇc˚ u – nedisponuje moˇznost´ı hry hr´ aˇc proti poˇc´ıtaˇci.
1.4 1.4.1
Zad´ an´ı Z´ akladn´ı funkcionalita
• Aplikace s grafick´ ym uˇzivatelsk´ ym rozhran´ım (GUI)
Abstract The objective of the project was to create full-featured implementation of classic strategy board game chess where two player fight with each other by moving pieces around the chessboard. Application is built on .NET framework using C# programming language and WPF technology for gra-
• Implementace hry ˇsachy“ ” • Umoˇzn ˇuje hru dvou hr´aˇc˚ u • Zprostˇredkuje pohyb figurek po ˇsachovnici 1
• Rozpozn´ a libovolnou moˇznost konce hry (ˇsach, mat, pat) 1.4.2
Bonusov´ a funkcionalita
• Zapoˇc´ıt´ av´ a body a zaznamen´ av´ a pr˚ ubˇeh hry • Zobraz´ı statistiky na konci hry • Umoˇzn´ı uloˇzen´ı v´ ysledk˚ u hry do textov´eho souboru • Speci´ aln´ı tahy (roˇs´ ada, tah mimochodem)
2
Hra Obr´ azek 1: V´ychoz´ı rozloˇzen´ı figurek na ˇsachovnici.
ˇ Sachy jsou klasick´ a deskov´ a hra pro dva hr´aˇce. V soutˇeˇzn´ı podobˇe je povaˇzov´ ana za odvˇetv´ı sportu. Hr´ aˇci spolu soupeˇr´ı prostˇrednictv´ım figurek posouvan´ ych po ˇsachovnici. C´ılem je dostat protihr´aˇcovu figurku kr´ ale do situace, kdy je ohroˇzen a nelze toto ohroˇzen´ı kter´ ymkoliv zp˚ usobem odvr´ atit.
2.1
Figurky Kaˇzd´ y hr´aˇc m´a na zaˇc´atku hry k dispozici sadu 16 figurek ˇsesti r˚ uzn´ ych typ˚ u, rozm´ıstˇen´ ych ve v´ ychoz´ım postaven´ı. Figurky rozd´ıln´ ych hr´ aˇc˚ u se liˇs´ı barvou; svˇetl´e figurky n´aleˇz´ı b´ıl´emu hr´ aˇci (zkr´acenˇe b´ıl´y ) a tmav´e ˇcern´emu hr´aˇci (ˇcern´y ). Kaˇzd´ y typ figurky m´a zvl´aˇstn´ı moˇznosti pohybu po ˇsachovnici (poˇcet figurek na jednoho hr´ aˇce v z´avorce).
Historie hry
P˚ uvod Jako m´ısto vzniku se kv˚ uli jazykov´ ym souvislostem nejˇcastˇeji oznaˇcuje Indie. Prvn´ı zm´ınka o pˇredch˚ udci hry se objevila v Persii kolem roku ˇ 600 n. l., kde je nyz´ yv´ ana jako Satrandˇ z. V 9. stolet´ı ˇ se dostala do C´ıny a pot´e se zaˇcala postupnˇe ˇs´ıˇrit i v Evropˇe. Kolem roku 1000 jsou v Evropˇe ˇsachy vˇseobecnˇe zn´ amou hrou.
• Pˇ eˇ sec (8): Pohyb o jedno pole vpˇred, je-li voln´e; v prvn´ım tahu konkr´etn´ıho pˇeˇsce je moˇzn´e ho posunout o dvˇe pole vpˇred. Br´at m˚ uˇze pohybem o jedno pole vpˇred a jedno stranou. • Vˇ eˇ z (2): Pˇr´ım´ y pohyb po ˇrad´ach a sloupc´ıch o libovoln´ y poˇcet pol´ı. • Jezdec – t´eˇz K˚ uˇ n (2): Pohyb o dvˇe pole rovnˇe a jedno stranou (ve tvaru p´ısmene L“). ” • Stˇ relec (2): Pohyb po diagon´al´ach o libovoln´ y poˇcet pol´ı. Stˇrelec se pohybuje vˇzdy na pol´ıch stejn´e barvy.
Modern´ı hra Ve 13. stolet´ı se zaˇcala pravidla rozˇsiˇrovat a ust´ alila se kolem 15. stolet´ı. Oproti ˇ relativnˇe omezen´emu Satrandˇ zi se liˇs´ı mimo jin´e rozˇs´ıˇren´ ymi tahy – zejm´ena u kr´ alovny, kter´a mˇela p˚ uvodnˇe velmi omezen´e moˇznosti pohybu. Fin´aln´ı podobu hra z´ıskala v 19. stolet´ı.
2.2
• D´ ama – t´eˇz Kr´ alovna (1): Kombinuje moˇznosti pohybu stˇrelce a vˇeˇze.
Princip hry
• Kr´ al (1): Pohyb o jedno pole libovoln´ ym smˇerem.
ˇ Sachovnice Hra prob´ıh´ a na ˇsachovnici. ˇ Sachovnice je ˇctvercov´ a deska s mˇr´ıˇz´ı o velikosti 8 sloupc˚ u (znaˇceny p´ısmeny a aˇz h) a 8 ˇrad (znaˇcen´ ych ˇc´ısly 1 aˇz 8). Buˇ nka v mˇr´ıˇzi se naz´ yv´ a pole. Pole maj´ı stˇr´ıdavˇe tmavou (ˇcern´ a pole) a svˇetlou barvu (b´ıl´ a pole). Na kaˇzd´em poli m˚ uˇze st´ at maxim´ alnˇe jedna figurka.
Tahy Figurky jsou na ˇsachovnici pˇresouv´ any prostˇrednictv´ım tah˚ u. Hr´aˇci se v taz´ıch pravidelnˇe stˇr´ıdaj´ı; b´ıl´ y zahajuje hru prvn´ım tahem. Tah se sest´av´a z pˇresunut´ı figurky t´ahnouc´ıho hr´ aˇce podle pravidel pohybu pˇremist’ovan´e figurky. Po2
3
kud pˇremist’ovan´e figurce stoj´ı v cestˇe“ jin´a fi” gurka, nelze ji pˇreskoˇcit (v´ yjimku tvoˇr´ı jezdec). Figurku nelze pˇrem´ıstit na pole, kde se nach´ az´ı jin´a figurka stejn´e barvy. Pokud se na c´ılov´em poli nach´az´ı figurka rozd´ıln´e barvy, je odebr´ ana ze ˇsachovnice a d´ ale se hry nez´ uˇcastˇ nuje; takov´ y tah se naz´ yv´a bran´ı. Existuj´ı tahy, pro kter´e plat´ı speci´ aln´ı pravidla:
3.1
Aplikace Pouˇ zit´ e technologie
.NET Framework mou Microsoft.
C#
• Tah mimochodem (en passant): Pˇeˇscem je moˇzn´e sebrat pˇeˇsce protihr´ aˇce, kter´ y se posunul o dvˇe pole, jako by se posunul pouze o jedno. Lze vykonat pouze v tahu bezprostˇrednˇe n´ asleduj´ıc´ım po dvojit´em tahu sebran´eho pˇeˇsce.
Bˇehov´e rozhran´ı vyv´ıjen´e fir-
Programovac´ı jazyk
Windows Presentation Foundation (WPF) Technologie pro tvorbu GUI, kter´a vyuˇz´ıv´ a znaˇckovac´ı jazyk XAML (Extensible application markup language).
• Roˇ s´ ada Posunut´ı kr´ ale o dvˇe pole smˇerem k vˇeˇzi a pˇresunut´ı vˇeˇze na pole pˇreskoˇcen´e kr´ alem. Roˇs´ ada je jedin´ y tah, kdy se pohybuj´ı dvˇe figurky souˇcasnˇe, ale je povaˇzov´ ana jako tah kr´ ale. Aby bylo moˇzn´e roˇs´ adu vykonat, mus´ı b´ yt splnˇeny podm´ınky: Mezi kr´ alem a vˇeˇz´ı se nenach´ az´ı ˇz´ adn´ a figurka; kr´ alem ani vˇeˇz´ı nebylo taˇzeno; kr´ al nesm´ı b´ yt v ˇsachu a nesm´ı pˇrej´ıt pˇres pole, kter´e je ohroˇzen´e soupeˇrovou figurkou.
Microsoft Visual Studio 2013 Express for Desktop V´ yvojov´e prostˇred´ı, kter´e umoˇzn ˇuje vyv´ıjet aplikace pro Windows na klasickou plochu (tj. nikoliv modern´ı aplikace Windows 8 a vyˇsˇs´ı).
3.2
Ovl´ ad´ an´ı
Instalace Hr´aˇc z´ısk´a sloˇzku, ve kter´e se nach´ az´ı spustiteln´ y soubor setup.exe. Kdyˇz jej uˇzivatel spust´ı, aplikace se nainstaluje a pot´e ji m˚ uˇze naj´ıt v nab´ıdce start. Aplikace lze nainstalovat pouze na operaˇcn´ı syst´em Windows.
ˇ Sach Situace, kdy je kr´ al ohroˇzen figurkou (figurkami) soupeˇre, se naz´ yv´ a ˇsach. Kdyby nebyl ˇsach odvr´ acen hr´ aˇcem, jehoˇz kr´ al je ohroˇzen, soupeˇr by mohl kr´ ale v n´ asleduj´ıc´ım tahu sebrat – takov´ a situace nesm´ı nastat. Hr´ aˇc proto mus´ı ˇsach odvr´ atit:
Ovl´ ad´ an´ı Po spuˇstˇen´ı aplikace se otevˇre hlavn´ı okno, kter´e obsahuje tˇri z´akladn´ı prvky: menu, ˇsachovnici a panel hr´aˇc˚ u.
• Ustoup´ı s kr´ alem na neohroˇzen´e pole.
ˇ Sachovnice umoˇzn ˇuje samotnou hru. Panel hr´ aˇc˚ u, kter´ y se nach´az´ı na prav´e stranˇe od ˇsachovnice, poskytuje z´akladn´ı informace a statistiky o jednotliv´ ych hr´aˇc´ıch (jm´eno, barva, poˇcet figurek). Nad panelem hr´aˇc˚ u je zobrazen poˇcet vykonan´ ych tah˚ u a doba uplynul´a od zaˇc´atku hry. Nad ˇsachovnic´ı se nach´az´ı menu.
• Postav´ı pˇred kr´ ale figurku a ochr´ an´ı“ ho. ” • Sebere figurku ohroˇzuj´ıc´ı kr´ ale. Situace, kdy nelze ˇsach odvr´ atit ˇz´ adn´ ym tahem, se naz´ yv´ a mat (resp. ˇsachmat). V takov´em pˇr´ıpadˇe hra konˇc´ı a hr´ aˇc, kter´ y soupeˇri zp˚ usobil mat, se st´av´a v´ıtˇezem.
ˇ ˇ Sachovnice Sachovnice se ovl´ad´a kliknut´ım na zvolen´e pole. Pokud se na nˇem nach´az´ı figurka aktu´aln´ıho hr´aˇce, vybran´e pole se st´av´a aktivn´ım a je ˇcervenˇe zv´ yraznˇeno. Pole, na kter´e je moˇzn´e vykonat tah, jsou zv´ yraznˇena barevn´ ym ohraniˇcen´ım. Speci´aln´ı tahy jsou zv´ yraznˇeny podobnˇe, liˇs´ı se
Kromˇe matu m˚ uˇze nastat pat. V takov´e situaci hr´aˇc, kter´ y je na tahu, nen´ı v ˇsachu, ale nem˚ uˇze vykonat ˇz´ adn´ y tah. Hra konˇc´ıc´ı patem nem´ a v´ıtˇeze; nast´av´a rem´ıza. 3
(a) Historie tah˚ u
(b) Statistika
Obr´ azek 4: Speci´ aln´ı okna dostupn´ a pˇres menu.
zobrazuje odliˇsn´ ym zp˚ usobem. Tahy jsou vykresleny jako graf z´avislosti poˇctu figurek na poˇctu vykonan´ ych tah˚ u. Graficky tak zobrazuje bilanci poˇctu figurek obou hr´aˇc˚ u v pr˚ ubˇehu hry.
Obr´ azek 2: Hlavn´ı okno. Na aktivn´ım poli (ˇcervenˇe) stoj´ı b´ıl´ a d´ ama a ˇsedomodˇre ohraniˇcen´e pole znaˇc´ı moˇzn´e tahy.
• About Otevˇre okno About. Toto okno zobrazuje informace o aplikaci. Obr´ azek 3: Zv´yraznˇen´ı speci´ aln´ıho tahu – roˇs´ ady (fialovˇe ohraniˇcen´e pole) pˇred a po pˇrejet´ı myˇs´ı.
Konec hry Po skonˇcen´ı hry se objev´ı okno Results (V´ ysledky). Okno ozn´am´ı v´ıtˇeze a prostˇrednictv´ım tlaˇc´ıtek odk´aˇze uˇzivatele do historie tah˚ u ˇci statistik. Zb´ yvaj´ıc´ı tlaˇc´ıtka nab´ız´ı uloˇzen´ı pr˚ ubˇehu hry do textov´eho souboru nebo spuˇstˇen´ı nov´e hry.
pouze barvou ohraniˇcen´ı. Po pˇrejet´ı myˇsi na takov´ ym polem se zobraz´ı popisek s typem tahu. Kliknut´ım je vykon´ an pˇr´ısluˇsn´ y tah; figurka je pˇresunuta na c´ılov´e pole a veˇsker´ a zv´ yraznˇen´ı zmiz´ı. Klikneli uˇzivatel pˇr´ımo na aktivn´ı pole, zv´ yraznˇen´ı zmiz´ı a ˇz´ adn´ y tah nen´ı vykon´ an.
3.3
N´ avrh
Aplikace byla navrˇzena podle vzoru Model View ViewModel (MVVM). Sch´ema je zaloˇzeno na striktn´ım oddˇelen´ı grafick´eho uˇzivatelsk´eho rozhran´ı (GUI) od logiky aplikace (bussines logic). To umoˇzn ˇuje mˇenit GUI nez´avisle na k´odu aplikace a naopak. MVVM dˇel´ı aplikaci na tˇri vrstvy:
Menu Nad ˇsachovnic´ı, tj. v lev´em horn´ım rohu okna, se nach´ az´ı menu – horizont´ aln´ı p´ as tlaˇc´ıtek, kter´e uˇzivateli umoˇzn ˇuj´ı vykonat pˇr´ıkazy: • New Spust´ı novou hru. • Save Uloˇz´ı pr˚ ubˇeh hry do textov´eho souboru ve form´ atu YAML. Po kliknut´ı na toto tlaˇc´ıtko se otevˇre dialog pro uloˇzen´ı souboru.
View Reprezentuje uˇzivatelsk´e rozhran´ı, kter´e je navrˇzeno ve znaˇckovac´ım jazyce XAML. Urˇcuje vzhled oken, str´anek, ovl´adac´ıch prvk˚ u atd. Pˇrev´ ad´ı data do viz´aln´ı podoby.
• History Otevˇre okno History (historie tah˚ u). Historie tah˚ u zobrazuje veˇsker´e proveden´e tahy od zaˇc´ atku hry a pˇr´ısluˇsn´e informace (t´ahnouc´ı figurka, v´ ychoz´ı a c´ılov´e pole, sebran´ a figurka, ˇcas, stav hr´ aˇce, ...); data pro vykreslen´ı z´ısk´av´a od objekt˚ u HistoryRecord z uspoˇr´ adan´e kolekce History ve tˇr´ıdˇ e Chessboard.
Model Popisuje data, se kter´ ymi pracuje aplikace, obvykle ve formˇe objekt˚ u.
ViewModel Tˇr´ıda, kter´a drˇz´ı stav aplikace. ViewModel poskytuje data pro View, kter´ y je pˇrev´ ad´ı do vizu´aln´ı podoby a zobrazuje je v UI.
• Stats Otevˇre okno Statistics (Statistika). Okno je funkˇcnˇe podobn´e oknu History, ale informace 4
• Converters Pˇrevodn´ıky hodnot mezi View a ViewModelem – tˇr´ıdy implementuj´ıc´ı IValueConverter. • Model Obsahuje vnoˇren´e jmenn´e prostory: – Moves Tahy – tˇr´ıdy implementuj´ıc´ı IMove. Obr´ azek 5: Sch´ema MVVM (zdroj: msdn.microsoft.com)
– Pieces Figurky – tˇr´ıdy rozˇs´ıˇruj´ıc´ı tˇr´ıdu Piece. Sv´ az´ an´ı View a ViewModelu je realizov´ ano pomoc´ı bindingu – View je nav´ az´ an na vlastnosti tˇr´ıdy ViewModel. Data mohou b´ yt mezi Viewem a ViewModelem synchronizov´ ana obˇema smˇery. Zmˇen´ı-li uˇzivatel data v UI pomoc´ı ovl´ adac´ıch prvk˚ u, automaticky se zmˇen´ı i vlastnosti pˇr´ısluˇsn´e ViewModelu. Opaˇcn´ ym smˇerem: jsou-li zmˇenˇeny vlastnosti ViewModelu, aktualizuj´ı se i nav´ azan´e UI prvky. Aby aktualizace UI fungovala, mus´ı ViewModel implementovat INotifyPropertyChanged interface. (V pˇr´ıpadˇe kolekce mus´ı j´ıt o typ ObservableCollection). Dojde-li ke zmˇenˇe hodnoty vlastnosti ViewModel, je vyvol´ana ud´ alost PropertyChanged, kter´ a informuje View a ten pˇrekresl´ı UI na z´ akladˇe nov´ ych dat.
• ViewModel Obsahuje hlavn´ı tˇr´ıdu Chessboard a vlastn´ı typy kolekc´ı • View N´avrh UI. Obsahuje XAML soubory – windows (okna) a resource dictionaries (slovn´ıky zdroj˚ u)
3.4.1
Ve jmenn´em prostoru View se nach´az´ı veˇsker´ y n´avrh uˇzivatelsk´eho rozhran´ı. Protoˇze nˇekter´e u ´seky XAML k´odu jsou pˇr´ıliˇs dlouh´e nebo se opakuj´ı, je v´ yhodn´e je um´ıstit do tzv. resource dictionary (slovn´ık zdroj˚ u), kde se mohou vyskytovat statick´e konstantn´ı hodnoty, ˇretˇezce, barvy, styly, ˇsablony, uˇzivatelsk´e ovl´adac´ı prvky atd. (ekvivalent CSS s rozˇs´ıˇren´ ymi moˇznostmi) K hodnot´am v resource dictionary lze n´aslednˇe pˇristupovat pomoc´ı kl´ıˇc˚ u. Resource dictionary se m˚ uˇze vyskytovat bud’ lok´ alnˇe nebo v samostatn´em souboru, na kter´ y je potˇreba odk´azat.
Pro pˇrevod dat (napˇr. pˇrevod ˇretˇezc˚ u na ˇc´ısla, matematick´ a operace, ...) mezi View a ViewModelem slouˇz´ı konvertory, tj. objekty tˇr´ıd implementuj´ıc´ı interface IValueConverter ViewModel vystavuje pˇr´ıkazy, tj. objekty tˇr´ıd implementuj´ıc´ıch ICommand interface. Pˇredstavuj´ı akce vykonan´e pˇri urˇcit´e ud´ alosti spojen´e s UI prvkem, kter´ y je na nˇej nav´ az´ an (napˇr. stisknut´ı tlaˇc´ıtka). Mimo jin´e podle stavu ViewModelu urˇcuj´ı, zda je moˇzn´e akci vykonat, a podle toho zmˇen´ı stav pˇr´ısluˇsn´eho UI prvku (zneaktivnˇen´ı tlaˇc´ıtka).
3.4
Kaˇzd´ y XAML soubor v projektu pˇredstavuje resource dictionary nebo okno (window). Soubor App.xaml se nach´az´ı na nejvyˇsˇs´ı u ´rovni a obsah resource dictionaries zahrnut´ ych v tomto souboru je dostupn´ y glob´alnˇe.
Struktura projektu
K´od hlavn´ıho okna (MainWindow) je kv˚ uli sv´e d´elce rozdˇelen do d´ılˇc´ıch resource dictionaries: ChessboardDictionary.xaml (ˇsachovnice), PlayerPaneDictionary.xaml & .cs (panel hr´aˇc˚ u). Obsah slovn´ıku BasicDictionary.xaml je obecn´ y, nevztahuj´ıc´ı se pouze k hlavn´ımu oknu.
Soubory projektu jsou roztˇr´ıdˇeny do logick´ ych celk˚ u – jmenn´ ych prostor˚ u (namespaces). Na nejvyˇsˇs´ı u ´rovni je namespace Chess. Jmenn´e prostory Model, View a ViewModel odpov´ıdaj´ı vrstv´ am MVVM sch´ematu. Kaˇzd´ a sloˇzka v projektu pˇredstavuje pr´ avˇe jeden jmenn´ y prostor.
K nˇekter´ ym soubor˚ um obsahuj´ıc´ım XAML k´ od (nejˇcastˇeji okna) je pˇripojen soubor se stejn´ ym n´azvem a pˇr´ıponou .cs, kter´e obsahuj´ı C# k´ od – tzv. code-behind (napˇr. k souboru MainWindow.xaml je pˇripojen code-behind soubor MainWindow.xaml.cs). Zde je moˇzn´e napˇr. odchyt´ avat ud´alosti z View apod.
Chess Namespace na nejvyˇsˇs´ı u ´rovni. • Commands ICommand.
View
Pˇr´ıkazy – tˇr´ıdy implementuj´ıc´ı
5
3.4.2
Move Pˇredstavuje tah. Seskupuje informace o tahu a metody k jeho ovl´ad´an´ı. Jedn´ a se o z´akladn´ı implementaci rozhran´ı IMove.
Model
Model popisuje data, se kter´ ymi aplikace pracuje. Vyjmenov´ any jsou pouze d˚ uleˇzit´e tˇr´ıdy, vlastnosti a metody. Vˇsechny tˇr´ıdy modelu rozˇsiˇruj´ı tˇr´ıdu ModelBase, kter´ a implementuje INotifyPropertyChanged interface. D´ıky tomu se zmˇeny hodnot vlastnost´ı projev´ı v UI.
Square
• Piece Piece: Figurka, pˇremist’ov´ana.
kter´a
• Square StartingSquare, FinalSquare: a c´ılov´e pole pˇresunu figurky.
je
tahem startovn´ı
• Piece Captive: Figurka, kter´a je t´ımto tahem sebr´ana. Obvykle je sebr´ana figurka nach´ azej´ıc´ı se na c´ılov´em poli, v´ yjimku tvoˇr´ı tah mimochodem.
Pˇredstavuje pole na ˇsachovnici.
• int X, Y: Sloupec a ˇr´ adek na ˇsachovnici.
• bool IsRestricted: Pravdiv´e, pokud by takov´ y tah zp˚ usobil ˇsach vlastn´ımu hr´aˇci.
• Piece Piece: Figurka, kter´ a se na poli nach´az´ı.
• bool IsActive: Pravdiv´e, pokud je pole aktivn´ı.
• string Type: Typ tahu. Poskytuje bliˇzˇs´ı informace o tahu, napˇr. dvojit´ y tah pˇeˇsce m´ a v t´eto vlastnosti uloˇzeno "Pawn Double Move". Z´akladn´ım typem je "Common".
Piece Pˇredstavuje figurku. Kaˇzd´ y typ figurky m´a vlastn´ı tˇr´ıdu, kter´ a rozˇsiˇruje tˇr´ıdu Piece.
• void Do(Chessboard chessboard): Vykon´a tah, tj. pˇresune figurku Piece na pole FinalSquare, sebere figurku Captive: a vyvol´a akci Action.
• char Sign: Unicode znak, kter´ y pˇredstavuje ˇsachovou figurku (napˇr. symbol U+2658 N jezdec).
• void TryDo(): Vykon´a tah zkuˇsebnˇe, tj. je moˇzn´e ho anulovat vyvol´an´ım metody Undo().
• Move Move: Tah, kter´ y je moˇzn´e na pole vykonat.
• void Undo(): Anuluje zkuˇsebn´ı tah.
• bool HasMoved: Pravdiv´e, pokud byl s figurkou vykon´ an alespoˇ n jeden tah. V´ ychoz´ı hodnota je false.
Speci´aln´ı tahy (tah mimochodem, roˇs´ada) maj´ı vlastn´ı implementace IMove. Tahy, kter´e se od z´akladn´ıho tahu pˇr´ıliˇs neliˇs´ı (pov´ yˇsen´ı pˇeˇsce), vyuˇz´ıvaj´ı z´akladn´ı Move a ve vlastnosti Action je uloˇzena pˇr´ıdavn´a akce, kter´a je vyvol´ana pˇri vykon´an´ı tahu.
• bool ThreatensKing: Pravdiv´e, pokud ohroˇzuje kr´ ale protihr´ aˇce. • Player Player: Hr´ aˇc, jemuˇz figurka n´ aleˇz´ı. • HashSet
GetMoves(): Z´ısk´ a tahy.
HistoryRecord Pˇredstavuje z´aznam o vykonan´em tahu. V uspoˇr´adan´e kolekci pak objekty t´eto tˇr´ıdy tvoˇr´ı historii tah˚ u.
• HashSet GetEvaluatedMoves(): Z´ısk´a vyhodnocen´e tahy. Tahy, jejichˇz vykon´an´ı by zp˚ usobilo ohroˇzen´ı vlastn´ıho kr´ ale, maj´ı vlastnost IsRestricted pravdivou, ostatn´ı nepravdivou (v´ ychoz´ı hodnota).
• int Order: Poˇrad´ı z´aznamu. • IMove Move: Vykonan´ y tah. • TimeSpan Time: Doba uplynul´a od zaˇc´atku hry do okamˇziku vykon´an´ı tahu.
Player
Pˇredstavuje hr´ aˇce.
• PlayerState State: Stav hr´aˇce, kter´ y tento tah zp˚ usobil protivn´ıkovi.
• string Name: Jm´eno hr´ aˇce • PlayerColor Color: Barva hr´ aˇce (v´ yˇcet obsahuje hodnoty Black a White.
3.4.3
• PlayerState State: Stav hr´ aˇce (ˇsach, ˇsachmat, pat, ...)
Chessboard Pˇredstavuje ˇsachovnici, kter´ a je ViewModelem aplikace. V cel´e aplikaci se nach´ az´ı 6
ViewModel
jedin´ a instance t´eto tˇr´ıdy, ze kter´e View ˇcerp´a data.
vystavena pˇres pˇr´ıkaz SaveFileCommand.
• SquareSet Squares: Kolekce pol´ı na ˇsachovnici. Typ kolekce SquareSet rozˇsiˇruje tˇr´ıdu HashSet< Square> o metodu Square Get(int x, int y) pro z´ısk´ an´ı pole z kolekce.
3.5 3.5.1
• HashSet Pieces: Kolekce vˇsech figurek (vˇc. sebran´ ych). Aplikace s touto kolekc´ı t´emˇeˇr nemanipuluje; kolekce zaruˇcuje, ˇze nikdy nenastane situace, kdy by na urˇcit´ y objekt figurky neexistovala reference a byl by tak vymaz´an.
Aplikaˇ cn´ı logika Kliknut´ı na pole
Chessboard obsahuje kolekce objekt˚ u Square (pole), Piece (figurka), Player (hr´ aˇc). Kaˇzd´ y objekt Square m´a vlastnost Piece, kter´a znaˇc´ı figurku stoj´ıc´ı na dan´em poli. View je nav´az´an kolekci objekt˚ u Squares a vykresluje je do ˇsachovnice. Square implementuje INotifyPropertyChanged, proto se zmˇeny vlast-
• PropertyDictionary Players: Kolekce hr´ aˇc˚ u. Typ PropertyDictionary je vlastn´ı implementace kolekce objekt˚ u, kter´ a jako kl´ıˇc k z´ısk´ an´ı objektu vyuˇz´ıv´a jeho vybranou vlastnost.
nost´ı objektu projev´ı v UI. V oknˇe jsou pole reprezentov´ana do mˇr´ıˇze uspoˇr´adan´ ymi tlaˇc´ıtky, na kter´e je nav´az´an pˇr´ıkaz SetSquaresCommand (nastav pole). Pole je moˇ zn´e vybrat pouze v pˇr´ıpadˇe, ˇze je na nˇej moˇzn´e vykonat tah nebo se na nˇem nach´az´ı figurka t´ahnouc´ıho hr´ aˇce; tato podm´ınka je vloˇzena do metody CanExecute() na objektu SetSquaresCommand a pokud ji pole nesplˇ nuje, tlaˇc´ıtko je neaktivn´ı (nen´ı moˇzn´e na nˇej kliknout).
• ObservableCollection History: Kolekce objekt˚ u HistoryRecord, kter´a tvoˇr´ı z´ aznam o pr˚ ubˇehu hry. • event MovePerformed: Ud´ alost vyvolan´a pˇri vykon´ an´ı tahu • event GameEnded: Ud´ alost vyvolan´ a pˇri skonˇcen´ı hry.
Je-li vˇsak podm´ınka splnˇena, tlaˇc´ıtko je aktivn´ı a klikne-li na nˇej uˇzivatel, spust´ı se pˇr´ıkaz; jako parametr je pˇr´ıkazu pˇred´an nav´azan´ y objekt Square . Pˇr´ıkaz vyvol´a metodu SetSquares(Square square), kter´a vyhodnot´ı ostatn´ı pole na ˇsachovnici podle pole pˇr´ısluˇsej´ıho tlaˇc´ıtku, na kter´e uˇzivatel klikl (tj. vybran´e pole). Mohou nastat n´asleduj´ıc´ı situace:
• event PropertyChanged: Ud´ alost vyvolan´a pˇri zmˇenˇe vlastnosti tˇr´ıd. Jej´ı vyvol´ an´ı aktualizuje UI. • void SetSquares(Square square): Metoda je vyvol´ ana pˇr´ıkazem SetSquaresCommand a jej´ım parametrem je vybran´e pole. Na z´ akladˇe vybran´eho pole nastav´ı stavy ostatn´ıch pol´ı (nastav´ı aktivn´ı pole a tahy, zneaktivn´ı pole, vykon´a tah, atd.)
1. Na vybran´ em poli se nach´ az´ı figurka t´ ahnouc´ıho hr´ aˇ ce. Nejprve je zavol´ana metoda ResetSquares(), kter´a odstran´ı pˇr´ıpadn´e jin´e aktivn´ı pole. Pot´e je vybran´e pole nastaveno jako aktivn´ı (IsActive = true). Na cel´e ˇsachovnici se m˚ uˇze nach´azet pouze jedin´e nebo ˇz´adn´e aktivn´ı pole. Tahy jsou z´ısk´any od figurky, kter´a stoj´ı na aktivn´ım poli, pomoc´ı metody GetEvaluatedMoves() a n´aslednˇe jsou zobrazeny v UI.
• void ResetSquares(): Uvede ˇsachovnici do stavu bez ˇz´ adn´eho aktivn´ıho pole a tah˚ u. • void PerformMove(Square square): Spust´ı metodu square.Move.Do(this), kter´ a vykon´a tah. Pot´e nastav´ı n´ asleduj´ıc´ıho hr´aˇce jako aktu´ aln´ıho a naopak. Zkontroluje ˇsach, mat i pat. Pˇrid´ a nov´ y z´ aznam o tahu do historie tah˚ u. Nakonec vyvol´ a metodu ResetSquares() a ud´ alost MovePerformed.
• void CheckEnd(): Zkontroluje mat a pat.
2. Vybran´ e pole je aktivn´ı, tj. uˇ zivatel na nˇ ej klikl dˇ r´ıve. Je zneaktivnˇeno zavol´ an´ım ResetSquares(). Metoda nastav´ı Square.IsActive = false (zneaktivnˇ en´ı pole) a Square.Move = null (odstranˇ en´ı tah˚ u) u kaˇzd´eho pole v kolekci Squares.
• void SaveFile(): Uloˇz´ı textov´ y soubor se z´ aznamem hry ve form´ atu YAML. Metoda
3. Na vybran´ e pole je moˇ zn´ e vykonat tah. Plat´ı: Square.Move != null. To znamen´ a, ˇze
• bool CheckCheck(): Zkontroluje ˇsach.
7
uˇzivatel dˇr´ıve vybral pole, kter´e se stalo aktivn´ım a nyn´ı chce prov´est tah s figurkou stoj´ıc´ım na aktivn´ım poli na pr´ avˇe vybran´e pole. Tento tah je vykon´ an zavol´ an´ım metody PerformMove(Square square), kde je parametrem vybran´e pole.
3.5.2
Zkuˇsebn´ı tah je vykon´an zavol´an´ım metody TryDo() na objektu tahu. Zkuˇsebn´ı vykon´an´ı se od opravdov´eho vykon´an´ı tahu liˇs´ı tak, ˇze m´a omezenˇejˇs´ı vliv a proto je moˇzn´e ho vr´atit zpˇet pomoc´ı metody Undo (). Pˇrestoˇze iterace cyklu prob´ıhaj´ı tak rychle, ˇze View vˇetˇsinou nest´ıh´a zobrazovat zmˇeny poloh figurek v UI, p˚ uvodnˇe pˇri vykon´av´an´ı zkuˇsebn´ıch tah˚ u figurka poblik´avala na ˇsachovnici. Tento probl´em byl vyˇreˇsen doˇcasn´ ym vypnut´ım vol´an´ı ud´ alosti PropertyChanged na objektech Square, coˇ z br´an´ı aktualizac´ım UI.
Z´ısk´ an´ı tah˚ u
K z´ısk´ an´ı tah˚ u doch´ az´ı v pˇr´ıpadˇe 1 pomoc´ı metody GetEvaluatedMoves() na objekt˚ u figurky, kter´a stoj´ı na aktivn´ım poli. Kaˇzd´ y typ figurky m´ a speci´aln´ı algoritmus pro z´ısk´ an´ı tah˚ u; vˇsechny figurky maj´ı metody GetMoves() a GetEvaluatedMoves(), kter´e vrac´ı mnoˇzinu objekt˚ u IMove.
Figurka vr´at´ı mnoˇzinu tah˚ u, kter´e je moˇzn´e vykonat. Program uloˇz´ı vˇsem objekt˚ um Square do vlastnosti Move takov´ y tah, jehoˇz c´ılov´e pole je pr´avˇe ten objekt Square. Protoˇ ze vlastnost Move je nav´az´ana na View, zobraz´ı se tahy v oknˇe.
Surov´ e tahy Metoda GetMoves() vrac´ı surov´e tahy, u kter´ ych nen´ı zaruˇceno, ˇze vykon´ an´ı ˇz´adn´eho z nich nezp˚ usob´ı ohroˇzen´ı vlastn´ıho kr´ ale. Pokud by byl takov´ y tah vykon´ an, protivn´ık by mohl v n´ asleduj´ıc´ım tahu sebrat kr´ ale, coˇz se nesm´ı st´ at.
HashSet moves = GetMoves(); // Vypne notifikace pro UI chessboard.Squares.IsNotifying = false; foreach (IMove m in moves) { // Zkuˇ sebnˇ e vykon´ a tah m.TryDo();
Vyhodnocen´ e tahy GetEvaluatedMoves() vrac´ı vyhodnocen´e tahy, kter´e maj´ı nastavenou vlastnost IsRestricted na true nebo false. Pakliˇze je IsRestricted = true, je tah zak´ azan´ y a jeho vykon´an´ı by zp˚ usobilo ohroˇzen´ı vlastn´ıho kr´ ale. V opaˇcn´em pˇr´ıpadˇe se jedn´ a o povolen´ y tah, v jehoˇz vykon´an´ı hr´ aˇci nic nebr´ an´ı.
// Zkontroluje, jestli v takov´ em rozloˇ zen´ ı // figurek nen´ ı ohroˇ zen kr´ al Piece king = chessboard.KingOf(this.Player); if (chessboard.Squares.Any(sq => sq.Piece != null && sq.Piece.Player != this.Player && sq.Piece.GetMoves().Any( move => move.Captive == king))) { // Existuje soupeˇ rova figurka, kter´ a by // po vykon´ an´ ı toho tahu mohla // zajmout kr´ ale aktu´ aln´ ıho hr´ aˇ ce. // -> Tah je zak´ az´ an. m.IsRestricted = true; } // Vr´ at´ ı tah zpˇ et m.Undo();
Zaj´ımav´ y je algoritmus pro z´ısk´ an´ı vyhodnocen´ ych tah˚ u. Metoda GetEvaluatedMoves() nejprve z´ısk´a surov´e tahy od metody GetMoves(). N´ aslednˇe je proveden foreach cyklus na kolekci tah˚ u; kaˇzd´a iterace n´ aleˇz´ı jednomu surov´emu tahu a vykon´a n´ asleduj´ıc´ı: 1. Zkuˇsebn´ı pˇresunut´ı figurky na c´ılov´e pole tahu 2. Z´ısk´ an´ı tah˚ u vˇsech figurek soupeˇre; pokud se mezi nimi nach´ az´ı alespoˇ n jeden tah, jehoˇz vykon´ an´ım by byl sebr´ an kr´ al aktu´aln´ıho hr´ aˇce, je tah (nikoliv soupeˇr˚ uv) oznaˇcen jako zak´ azan´ y nastaven´ım vlastnosti IsRestricted = true. V opaˇ cn´em pˇr´ıpadˇe je tah povolen´ y.
} chessboard.Squares.IsNotifying = true; return moves; ´ K´ od 1: Uryvek k´ odu z metody pro z´ısk´ an´ı vyhodnocen´ych tah˚ u ve tˇr´ıdˇe Piece
3. Pˇresunut´ı figurky zpˇet na v´ ychoz´ı polohu a uveden´ı ˇsachovnice do p˚ uvodn´ıho stavu 8
3.5.3
hr´aˇc m˚ uˇze vykonat nˇejak´ y tah. Z´ısk´a tahy vˇsech figurek aktu´aln´ıho hr´aˇce a pokud mezi nimi nen´ı ˇz´ adn´ y povolen´ y tah, podm´ınka je splnˇena. Tehdy se vyhodnocuje vnoˇren´a podm´ınka. Mohou nastat situace:
Proveden´ı tahu
K proveden´ı tahu doch´ az´ı v pˇr´ıpadˇe 3. Vybran´e pole m´ a ve vlastnosti Moove uloˇzen tah, kter´ y je vykon´ an zavol´ an´ım metody IMove.Do(): Metoda vykon´a n´ asleduj´ıc´ı:
1. Hr´ aˇ c je v ˇ sachu. Ze situace vypl´ yv´a, ˇze kr´ al hr´aˇce je ohroˇzen a nelze tuto situaci nelze zvr´atit ˇz´adn´ ym tahem → Nast´av´a ˇsachmat.
1. Odstran´ı figurku Piece IMove.Captive (sebran´a figurka) ze ˇsachovnice, pokud nen´ı hodnotou t´eto vlastnosti null
2. Hr´ aˇ c nen´ı v ˇ sachu. Ze situace vypl´ yv´ a, ˇze kr´al hr´aˇce nen´ı ohroˇzen a hr´aˇc nem˚ uˇze vykonat ˇz´adn´ y povolen´ y tah → Nast´av´a pat.
2. Odstran´ı stoj´ıc´ı figurku na aktivn´ım poli a tut´eˇz figurku nastav´ı jako stoj´ıc´ı na vybran´em poli.
Metoda v obou pˇr´ıpadech nastav´ı pˇr´ısluˇsn´ ym hr´aˇc˚ um odpov´ıdaj´ıc´ı stav, nastav´ı vlastnost ˇsachovnice IsGameOver = true a vyvol´a ud´ alost GameEnded s argumenty popisuj´ıc´ımi konec hry. View na vyvolanou ud´alost reaguje otevˇren´ım okna, kter´e oznamuje konec hry a dodateˇcn´e informace (data ˇcerp´a z argument˚ u ud´alosti – objektu GameEndedEventArgs).
Po samotn´em tahu je aktu´ aln´ımu hr´ aˇci nastavena vlastnost Turns = false a n´ asleduj´ıc´ımu true. T´ım se n´ asleduj´ıc´ı hr´ aˇc st´ av´ a aktu´ aln´ım a naopak. N´ asleduje ovˇeˇren´ı, zda tah nezp˚ usobil ˇsach, mat ˇci pat aktu´ aln´ımu hr´ aˇci. Vyhodnocen´ı ˇ sachu Nejprve je vyhodnocen ˇsach zavol´ an´ım metody CheckCheck(). Metoda z´ısk´a tahy vˇsech figurek soupeˇre a je-li mezi nimi takov´ y tah, jehoˇz vykon´ an´ım by byl sebr´ an kr´ al, je nastaven stav hr´ aˇce na PlayerState.Check.
// Podm´ ınka je splnˇ ena, existuje-li figurka // aktu´ aln´ ıho hr´ aˇ ce, kter´ a m´ a alespoˇ n // jeden povolen´ y tah. if (!Squares.Any(p => sq.Piece != null && sq.Piece.Player == CurrentPlayer && sq.Piece.GetEvaluatedMoves().Any( m => !m.IsRestricted))) {
bool check = false; // Najde vˇsechna pole s figurkou soupeˇ re, // kter´a m´a alespoˇ n jeden tah ohroˇ zuj´ ıc´ ı kr´ ale foreach (Square sq in Squares.Where(sq => sq.Piece != null && sq.Piece.Player != CurrentPlayer && sq.Piece.GetMoves().Any(m => m.Captive == KingOf(CurrentPlayer)))) { // Vˇsechny figurky stoj´ ıc´ ı na takov´ ych // pol´ıch ohroˇ zuj´ ı kr´ ale a zp˚ usobuj´ ı ˇ sach sq.Piece.ThreatensKing = true; check = true; }
if (CurrentPlayer.State == PlayerState.Check) { /* Mat */ } else { /* Pat */ } } K´ od 3: Podm´ınka oveˇruj´ıc´ı mat a pat
D´ale
je do kolekce ObservableCollection < HistoryRecord> History pˇrid´ ana nov´a instance tˇr´ıdy HistoryRecord, kter´a shromaˇzd’uje informace o vykonan´em tahu. Kolekce History tvoˇr´ı kompletn´ı
if (check) { SetPlayerState(CurrentPlayer, PlayerState.Check); return true; }
z´aznam pr˚ ubˇehu hry.
4
return false;
Z´ avˇ er
K´ od 2: K´ od metody oveˇruj´ıc´ı ˇsach
4.1 Vyhodnocen´ı matu a patu D´ ale je vyvol´ana metoda CheckEnd(), kter´ a vyhodnot´ı konec hry. Metoda obsahuje dvˇe podm´ınky, druhou vnoˇrenou v prvn´ı. Vnˇejˇs´ı podm´ınka vyhodnot´ı, zda aktu´aln´ı
V´ yvoj n´ avrhu, probl´ emy
N´avrh aplikace se v pr˚ ubˇehu v´ yvoje znaˇcnˇe mˇenil a pˇri konfliktech s probl´emy bylo potˇreba prov´est nˇekolik kl´ıˇcov´ ych pˇrebudov´an´ı projektu. P˚ uvodn´ı myˇslenka byla n´asleduj´ıc´ı. 9
• Hlavn´ı aplikaˇcn´ı tˇr´ıda (ˇsachovnice) bude obsahovat kolekci objekt˚ u figurek.
moˇzn´e pˇridat libovoln´ y speci´aln´ı tah a upˇresnit akci pˇri jeho vykon´an´ı.
• Projekt obsahuje tˇr´ıdu Position; kaˇzd´a figurka m´ a vlastnost tohoto typu, kter´ a znaˇc´ı, na jak´e pozici se figurka nach´ az´ı.
Vyhodnocen´ı tah˚ u Obt´ıˇzn´e bylo poradit si s tahy, jejichˇz vykon´an´ı by zp˚ usobilo ohroˇzen´ı vlastn´ıho kr´ale (zak´azan´e tahy). P˚ uvodn´ı ˇreˇsen´ı zobrazovalo uˇzivateli zak´azan´ y tah jako povolen´ y. Pˇri vykon´an´ı takov´eho tahu vˇsak byl uˇzivatel upozornˇen a tah vr´acen zpˇet.
• Figurka vrac´ı kolekci objekt˚ u Position jako pozice, na kter´e je moˇzn´e vykonat tah. Toto rozvrˇzen´ı bylo z´ akladem aplikace a pozdˇeji se uk´ azalo jako nev´ yhodn´e. Vykreslen´ı uˇzivatelsk´eho rozhran´ı podle tohoto modelu bylo obt´ıˇzn´e a n´avrh neumoˇzn ˇoval zapamatov´ an´ı stavu pol´ı, na kter´ ych se nenach´ azela figurka. Nab´ızely se dvˇe moˇznosti n´ avrhu aplikace:
N´ahradn´ım ˇreˇsen´ım bylo vyhodnocen´ı tah˚ u, kter´e spoˇc´ıvalo v zabr´anˇen´ı uˇzivateli ve vykon´ an´ı zak´azan´eho tahu. Kaˇzd´ y tah z´ıskan´ y od figurky je zkuˇsebnˇe vykon´an a podle ohroˇzen´ı vlastn´ıho kr´ale je tah vyhodnocen jako povolen´ y ˇci zak´ azan´ y. Na z´akladˇe t´eto informace se takov´ y tah na ˇsachovnici zobraz´ı odliˇsnˇe a uˇzivateli nen´ı povoleno jej vykonat.
1. Kolekce figurek s vlastnost´ı pole, na kter´em figurka stoj´ı. 2. Kolekce pol´ı s vlastnost´ı figurky, kter´a na poli stoj´ı.
Probl´emem byla skuteˇcnost, ˇze zkuˇsebn´ı vykon´ an´ı tahu se zobrazovalo i v UI, coˇz bylo neˇz´adouc´ı. P˚ uvodn´ım konceptem ˇreˇsen´ı bylo vytvoˇren´ı kopie ˇsachovnice, na kter´e budou tahy vykon´any nez´ avisle na UI. Jednoduˇsˇs´ım a fin´aln´ım ˇreˇsen´ım bylo vypnut´ı vol´an´ı ud´alosti PropertyChanged pˇri zmˇenˇe vlastnosti Square bˇehem vykon´av´an´ı zkuˇsebn´ıch tah˚ u, coˇz zabr´anilo aktualizac´ım UI. Zkuˇsebn´ı tah mimo jin´e neobn´aˇs´ı vˇsechny akce jako tah na ostro“. ”
Zv´ıtˇezil n´ avrh #2 (kv˚ uli jednoduˇsˇs´ımu bindingu) a projekt proˇsel prvn´ı pˇrestavbou. Tˇr´ıda Position se vyvinula ve tˇr´ıdu Square, nyn´ı pˇredstavuj´ıc´ı samotn´e pole sp´ıˇse neˇz jen pozici; kromˇe souˇradnic obsahuje informace jako figurku, kter´ a na poli stoj´ı, barvu a stav (tj. jestli je aktivn´ı, jestli je na toto pole moˇzn´e vykonat tah atd.). Hlavn´ı aplikaˇcn´ı tˇr´ıda Chessboard obsahuje kolekci objekt˚ u figurek (Piece) a pol´ı (Square), pˇriˇcemˇz figurky nev´ı, na kter´em poli stoj´ı. Figurky ovˇsem obsahuj´ı referenci na Chessboard instanci a proto mohou jednoduˇse vr´ atit pozici vyhled´ an´ım pˇr´ısluˇsn´eho pole v kolekci. Figurky z´ aroveˇ n potˇrebuj´ı m´ıt referenci na ˇsachovnici pro z´ısk´ an´ı tah˚ u.
4.2
Splnˇ en´ı zad´ an´ı
ˇ V pr˚ ubˇehu v´ yvoje aplikace Sachy se mi podaˇrilo naplnit vˇsechny body zad´an´ı, vˇc. z´akladn´ı i bonusov´e funkcionality. V´ yjimkou je zapoˇc´ıt´av´an´ı bod˚ u, nebot’ pravidla hry ˇsachy ˇz´adn´e body nepopisuj´ı. M´ısto toho aplikace umoˇzn ˇuje v oknˇe Statistics zobrazit v´ yvoj poˇctu figurek v pr˚ ubˇehu hry, coˇz m˚ uˇze b´ yt povaˇzov´ano za alternativu k bodov´emu hodnocen´ı.
Nejprve byly tahy z´ısk´ av´ any ve formˇe vracen´ı kolekce pol´ı ˇci pozic, na kter´e je moˇzn´e vykonat tah. Pot´e bylo pouˇzito zapisov´ an´ı stav˚ u pˇr´ımo do objekt˚ u Square bez vracen´ı kolekce, coˇ z se pozdˇeji uk´azalo b´ yt neefektivn´ı ze dvou d˚ uvod˚ u: bylo obt´ıˇzn´e realizovat speci´ aln´ı tahy (napˇr. tah mimochodem, kdy se sebran´ a figurka neshoduje s figurkou, jeˇz stoj´ı na c´ılov´em poli) a tak´e nebylo moˇzn´e tahy pˇred zobrazen´ım na ˇsachovnici zpracovat (vyhodnocen´ı tah˚ u). Jako ˇreˇsen´ı se jevilo vracen´ı kolekce objekt˚ u pˇredstavuj´ıc´ıch tahy (s vlastnostmi jako startovn´ı a c´ılov´e pole, pˇremist’ovan´ a figurka, sebran´a figurka, ...). Pro tento u ´ˇcel bylo vytvoˇreno interface IMove, specifikuj´ıc´ı vlastnosti tahu, a kter´ ykoliv druh tahu implementuje toto rozhran´ı. D´ıky tomuto syst´emu je 10