Proiectarea Unei Aplicatii Ce Simuleaza Jocul Moara cu Norocdocx

=== Proiectarea unei aplicatii ce simuleaza jocul Moara cu noroc ===

CUPRINS

Capitolul 1.Introducere

Rezumat

Această lucrare este constituită din 4 capitole. În primul capitol se prezintă propunerea și structura aplicației de asemena și o serie de concepte general folosite în această lucrare. De asemenea sunt prezentate concepte de bază și te teorie privind metoda Model View ViewModel și totodată ce este Reactive Extension. În capitolul doi este prezentat modul de cuantificare a datelor și implementarea acestora.

De asemenea explică funcționalitatea și tipurile de date utilizate. Capitolul trei prezintă din punct de vedere al programatorului noțiuni care au fost folosite pentru a crea design-ul si interfata acestei aplicații. Lucrarea se încheie cu un capitol destinat utilizatorului, prin prezenatarea modului de utilizare a aplicației.

1.2 Propunerea aplicației

În această lucrare se dorește construirea unei o aplicații practice sub limbajul de programare C# ce simulează jocul moara cu următoarele facilități:

Dezvoltarea unui joc de logică pe diferite nivele de dificultate. În cazul în care dorește, utilizatorul va putea să aleagă nivelul de dificultate. Fiecare nivel arată diferit și nu în ultimul rând are un anumit număr de piese care pot fi folosite în joc.

Această aplicație poate fi folosită de două persoane. Doi jucători vor putea sa-și introducă numele și fiecare jucător va fi informat, întru-n anumit mod, când urmează.

Utilizatorul aplicației va ști la fiecare pas câte piese are, deoarece va fi afișat.

Iar la sfârșitul aplicației se va afișa numele jucătorului care a câștigat.

1.3 Resursele aplicației

În prima fază a construcției aplicației se vor cuantifica datele conform cerințelor propuse anterior. Resursa aplicației va fi un fișier de tip rich text format, pentru butonul Help în care va conține regulile aplicației:

“HelpPage.rtf”

Pentru completarea acestui fișier a fost folosit o parte din sursa: http://www.mastersgames.com/rules/morris-rules.htm

De asemenea, imaginile Level1.png, Level2.png, Level3.png se vor găsi în fișierul Resurse din proiect. Acestea se vor folosi mai târziu pentru opțiunea de alegere între nivele.

Structura aplicației. Metoda MVVM.

Modelul Model-View-ViewModel (MVVM) ajută la separarea prezentării logice de prezentarea aplicației de interfața de utilizator (UI). Această separare ajută la abordarea numeroaselor probleme de dezvoltare și de proiectare și poate face aplicația mult mai ușor pentru testare, menținere, și evoluare. De asemenea, poate îmbunătăți oportunitățile de reutilizare a codului și permite dezvoltatorilor si designerilor de Interfața de utilizator să colaboreze mai ușor în dezvoltarea aplicației. Folosind modelul MVVM, User Interface-ul este separate de business logic fiind împărțit în trei clase distincte: View, care încapsulează UI și logica UI; View Model, care încapsulează logică de prezentare și Model, care încapsulează logica și datele. Prism include probe și implementări de referință, care arată cum să pună în aplicare modelul MVVM într-o aplicație Windows Presentation Foundation (WPF). Biblioteca Prism prevede, de asemenea, caracteristici care vă pot ajuta să pună în aplicare modelul în propriile aplicații.Aceste caracteristici întruchipează cele mai comune practici pentru punerea în aplicare a modelului MVVM și sunt concepute pentru a sprijini testabilitate și de a lucra bine cu Expression Blend și Visual Studio.

View-ul interacționează cu View-Model-ul prin intermediul data binding, comenzi, și evenimente de notificare de schimbare. View Model-ul observă și coordonează actualizând Model-ul. El convertește, valideazță datele necesare pentru afișarea în View. (Fig. 1.4.1 -MVVM)

Fig. 1.4.1 – MVVM

Sursa figurii “Fig. 1.4.1 – MVVM” este: https://msdn.microsoft.com/en-us/library/gg405484%28v=pandp.40%29.aspx

View-ului are responsabilitatea de a defini structura și aspectul a ceea ce utilizatorul vede pe ecran. În mod ideal, cod din spatele unui view conține doar un constructor care solicită metoda Initialize Component. View-ul este un element vizual, cum ar fi o fereastră, pagină, de control al utilizatorului, sau template date. View-ul definește comenzile conținute în view și aspectul lor vizual cu stilul. View-ul se refera la view model prin proprietatea sa DataContext. Controalele din ecranul sunt date legate de proprietățile și comenzile expuse de view model.

 De exemplu, view-ul poate folosi convertoare de valoare pentru a formata datele care urmează să fie afișate în interfața, sau poate folosi reguli de validare pentru a oferi validarea datelor de intrare suplimentare pentru utilizator. View-ul definește și se ocupă de comportamentul vizual al User Interface-ului, cum ar fi animații care pot fi declanșate de o modificare în view model sau prin interacțiune a utilizatorului cu UI. 

View Model-ul (MVVM) încapsulează logica de prezentare și datele pentru view. Nu are nici o referire directă la view sau orice cunoștințe despre implementarea view-ului. View Model-ul implementează proprietăți și comenzi la care view-ul poate lega date și trimite notificări view-ului cu privire la modificările făcute prin organizarea de evenimente de notificare și schimbare. Proprietățile și comenzile pe care View Model-ul le oferă definește funcționalitatea User Interface-ului, dar view-ul determină cum va fi folosită această funcționalitate.

View Model-ul este o clasă non-vizual și nu derivă din nici o clasă de baza WPF. Acesta încapsulează logica de prezentare. View Model-ul este independent de View și de Model. View Model-ul de obicei nu se referiră în mod direct la View. Implementează proprietăți și comenzi la care View-ul se poate lega prin data binding. Notifică view-ul cu privire la orice schimbare, cu evenimentele de notificare și schimbare prin intermediul interfețelor INotifyPropertyChanged și INotifyCollectionChanged. View Model-ul coordonează interacțiunea View-ului cu Model-ul. Poate să convertească sau să manipuleze date, astfel încât să poată fi ușor consumate de View și poate aplica proprietăți suplimentare, care nu pot fi prezenți în Model.  (Fig. 1.4.2 – Model View ViewModel)

Fig. 1.4.2 – Model View ViewModel

Sursa figurii “Fig. 1.4.2 – Model View ViewModel” este: https://msdn.microsoft.com/en-us/library/ff798384.aspx

Data binding este procesul care stabilește o legătură dintre User Interface și business logic.Când UI este schimbat, atunci datele care stau la bază vor reflecta această schimbare.

Binding markup extension oferă o valoare de proprietate, astfel încât valoarea este amânată până în momentul în care va rula. O extensie de marcare este transformat într-un obiect de expresie intermediară în XAML. Expresia și contextul datelor sunt folosite de motorul de legare Silverlight pentru a determina valoarea proprietății la momentul execuției.

În cadrul XAML, orice valoare atribut care este înconjurat în acolade {…} este o extensie de marcare. În timp ce cele mai multe dintre markup-ul XAML sunt folosite pentru a construi controale și panouri, pentru a asambla arborele vizual al cererii, extinderea markup injecta funcționalități suplimentare în XAML. Legarea Markup Extension construiește un binding și asociază cu UIElement sau FrameworkElement ca proprietatea la care aparține. Toate legăturile au o proprietate obiect sursă, proprietate sursă, obiect țintă și țintă.(Fig. 1.4.3 – Binding)

Fig. 1.4.3 – Binding

Sursa figurii “Fig. 1.4.3 – Binding” este: http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

Un exemplu în XML de binding :

Fig. 1.4.4 – Binding XAML

Sursa figurii “Fig. 1.4.4 – Binding” este: http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

Reactive Extension

Reactive User Interface este un MVVM framework care ne permite să accesăm Reactive Extension pentru .NET ca să se creeze User Interfaces care rulează pentru orice platformă mobilă sau desktop.

Reactive Extension este o bibliotecă pentru a compune programe asincrone și bazate pe evenimente (event-base) utilizând secvențe observable și operatori de interogare LINQ.

Operațiunile Input/Output în mod normal sunt mai lente decât alte operațiuni.

Programarea sincronă este atunci când firele de execuție trebuie să aștepte până când operațiunile I/O s-au terminat. Când firele de execuție se pot continua fără să aștepte ca operațiunile să fie complete, spunem că firele de execuție pot efectua I/O asincron.

Utilizând Reactive Extension putem reprezenta data streams asincrone, adică transfer de date la viteză mare.

IReactiveCommnad implementează Reactive Commnad, care descriu acțiuni făcute în User Interface ca și copy, open și ok.

Metode Icommand sunt Can Execute și Execute. Can Execute definește metoda care determină dacă comanda se poate executa în starea curentă.Iar Execute definește metoda care va fi apelată când comanda este invocată.

Reactive Object este obiectul de bază pentru clasa View Model și implementează INotify Property Changed. Deci Reactive Object va face schimbări la nivel de observable pentru a monitoriza obiectele care se schimbă.

Inotify Property Changed nu este o colecție, ci o interfață pentru obiectele din clase pentru a face notificări Property Changed în cazul în care valuarea unei proprietăți se schimbă. Acesta ne permite să invocăm evenimentul Property Changed de câte ori un obiect se schimbă. Adică se adaugă, se scoate sau se modifică. Este compatibil cu următoarele colecții List<T>, Observable Collecton<T>.

Observable Collection este o colecție de date, de tip dinamic care oferă notificări utilizând INotify Collection Changed când obiectele sunt modificate.Acest lucru se întâmplă din cauza că se poate face data binding la un observable collection.

Fig. 1.5.1 – View Model

Sursa figurii “Fig. 1.5.1 – View Model” este: https://reactiveproperty.codeplex.com/

2.Structura Programării Orientate pe Obiecte. Cuantificarea problemei

2.1 MVVM. Model

Se vor construi următoarele enumerări, care fac parte din clasa Enum.cs.

Prima enumerare va fi PlaceStatus care are urmatoarele componente:

Unoccupied, va fi variabila care care va fi folosită la verificarea locului daca este ocupat

P1, va reprezenta jucătorul 1 ( Player 1 )

P2 va reprezenta jucătorul 2 ( Player 2 )

A doua enumerare numită GameState, va arata starea jocului:

Placing, va fi folosită la introducerea piselor în joc

Moving, va reprezenta a cea parte din joc în care piesele vor fi deplasate

Flying, variabila care va arăta dacă jocul poate continua

Over, va arăta sfârșitul jocului.

Cu ajutorul următoarei clase vom modifica aspectul unui Place. În accest caz un Place va reprezenta tabla de joc, mai exact punctele unde se vor putea plasa piesele.

2.2 Construcția aplicației moara

Această clasă derivată moștenește clasa de bază ReactiveObject din clasa ReactiveUI.ReactiveObject .

ReactiveObject este obiectul de bază pentru calsele View Model și implementează INotifyPropertyChanged. INotifyPropertyChanged este o interfață folosită în clasele de obiecte, care actualizează UI ( interfața de utilizator ) de câte ori un obiect este adăugat, șters sau schimbat.

Se va construi o variabilă UnoccupiedColor de tip Brush folosit pentru a a umple cu culoarea alba obiectul fillColor. În continuare cele doua metode P1Color si P2Color vor returna culoarea albastra pentru piesa jucatorului P1 respectiv violet pentru piesa jucatorului P2.

Vom avea nevoie de următoarele variabile:

private Brush fillColor, pentru a umple un tile

private int strokeThickness, grosimea unui tile, această variabilăa va fi folositoare în momentul în care dorim sa mutăm o piesă

private PlaceStatus, pentru a verifica dacă se poate pune o culoare sau se poate pune o piesă în acel loc.

Metoda “OnPlaceStatusChange” va lua valarea care intră și va verifica pe rând cele 3 condiții. Practic această metoda verifică daca tile-ul curent este neocupat, adică deocamdată nici un jucator nu a plasat o piesă pe locul respectiv, atunci va fi colorată in alb. Dacă starea acestui loc, este P1 se va colora in albastru. Asta înseamnă ca e rândul jucatorului numărul 1. Iar dacă starea este P2 se va colora in violet, deoarece este rândul jucătorlui numărul 2.

Aceste metode sunt proprietăți auto-implementate, care mai târziu vor fi folosite pentru a crea diferitele nivele ale acestui joc.

PlaceName, pentru fiecare loc unde se poate plasa o piesă

Row, pentru linia pe care se vor afla punctele pe care se pot pune piesele

Column, pentru coloana pe care se vor afla punctele pe care se pot pune piesele.

De exemplu pentru pătratul cel mai mare in stânga sus, PlaceName va fie egal cu "OuterTopLeft", Row va fie egal cu 0, iar Column va fi tot 0. Atunci primul tile va fi pe locul [0][0].

Toate aceste lucruri vor fi posibile pentru că IEnumerable<Place> suportă o metodă de iterare, în acest caz Place, putând alstfel sa creăm mai încolo un vector.( Fi. 2.1 – Places )

Fig. 2.1 – Places

Proprietatea “Status” va citi variabila “placeStatus” și îl va modifica în funcție de cerințele metodei ”OnPlaceStatusChanged”, iar proprietățile “FillColor” și “StrokeThickness” vor modifica variabilele “fillColor” și “strokeThickness” care reprezintă culoarea și grosimea marginii unei elipse în caz că undeva in cod s-a făcut o modificare. “RaiseAndSetIfChanged” va face ca modificarea să fie vizibilă și la nivel User Interface ( Interfața de utilizator ).

2.3 Tabla de joc

În clasa ”Game” vom avea variabilele cu următoarele specificări:

winner, pentru jucătorul câștigător

state, pentru starea jocului, dacă jocul s-a terminat

places, dacă apar schimbări la nivel de places, adică locul unde se pot plasa piesele.

Fiecare proprietate din partea aceasta de cod vor salva modificările facute în cazul în care s-a produs vre-o schimbare.

Pe baza clasei ”Place” vom crea țigle (tiles) pentru fiecare nivel în parte. Avem 3 nivele, deci vom avem 3 cazuri. Fiecare caz în parte va conține o metodă asociată variabilei “Places” după cum urmează:

Prin această parte de cod:

Vom obține o clasă care poate fi legat direct la codul XAML utilizând Reactive Extension. Iar în paranteze avem expresia care reprezintă proprietatea “Places”. Adică clasa care va putea fi legată de codul XAML va fi clasa “Places”.

Prin metoda “GeneratePlacesForLevel1” vom crea o variabilă “Places” de tipul var implicit pentru primul nivel al jocului, în care vom instanția și vom crea noi tiles. Adică locurile unde vor putea jucătorii sa plaseze piesele, ca în figura Fig. 2.1 –Places. Mai întâi vom crea tile-urile pentru pătratul de dinafară, după care pentru pătratul din mijloc, iar în cele din urma pe cele din interior.

În continuare vom face conexiunile între places, deoarece moara se poate face numai dacă 3 țigle sunt conectate sau 3 piese sunt unul lângă celălalt.

Mai jos este un exemplu pentru “Places[0].AdjacentPlaces = new[] { Plaes[1], Places[3] };” , unde locurile numerotate sunt punctele unde se pot plasa piesele. În acest exemplu există o conexiune între locul 0 și locul 1, și de asemenea între locul 0 și 3. (Fig. 2.2 – The connections)

Iar primul nivel vom avea conexiunile: (Fig. 2.3 – Level 1)

La fel se va proceda în toate celelalte cazuri. Pentru nivelul 2 vom avea codul:

Și nivelul 2 vom avea conexiunile (Fig. 2.4 – Level 2):

Pentru nivelul 3 vom avea codul:

Următoarea figura reprezintă cum va arăta nivelul 3 (Fig. 2.5 – Level 3):

“GameOverEventHandler” este un delegat care conține o referință la o metodă care nu întoarce o valoare. Primul parametru a metodei este de tip Object și se referă la instanța care ridică evenimentul. Al doilea parametru său este derivat din EventArgs tip și deține datele de eveniment. Dacă evenimentul nu generează datele despre evenimente, al doilea parametru este pur și simplu valoarea câmpului EventArgs.Empty. În caz contrar, al doilea parametru este un tip derivat din EventArgs și furnizează orice câmpuri sau proprietăți necesare de a organiza datele de eveniment ca în codul de mai jos:

“GameOver” este un eveniment, care va conține notificări în caz că user-ul va face modificări.

Evenimentul “GameOver” va fi fie nul, în cazul în care nici un client nu a fost legat de un delegat la eveniment, sau se referă la un delegat care ar trebui să fie numit în cazul în care evenimentul este invocate, toate acestea întâmplându-se la sfârșitul jocului.

Vom reține fiecare loc în parte a unei moare, într-o variabilă. La fel vom face și cu moara curentă.

2.4 Verificarea moarei

Clasa Players are următoarele variabile cu caracteristicile:

isPlayerTurn, care va arăta dacă e răndul jucătorului curent,

name, numele jucătorului

piecesLeft, piesle rămase în joc

backgroud, va fi folosit pentru schimbarea culorii numelui a jucătorului

previousMills, pentru reținerea moarei de dinaintea celui curent

piecesCanRemove, piesele care se pot muta, după ce toate piesele au fost puse în joc

invisiblePieces, pentru piesele rămase care se pot pune în joc

InactiveColor, va reprezenta culoarea numelui jucătorului căruia nu îi este rândul, culoarea va fi albă

ActiveColor, va reprezenta culoarea numelui jucătorului căruia îi este rândul, culoarea va fi roșie

Pentru fiecare nivel în parte numărul de piese diferă. Acest lucru va fi evidențiat în switch-ul următor:

Numerele din metoda apelată vor fi numărul de piese pentru fiecare nivel în parte. Cazul 1 va fi nivelul 1 și așa mai departe.

Numerotarea piselor va începe de la 0, și va fi reținută în “PiecesLeft”. În clipa în care va veni rândul unui jucător, numele jucătorului se va face în roșu, altfel, dacă nu este rândul lui va fi alb.

La un moment dat când vom avea 3 piese aliniate una lângă alta, vom putea să luăm o piese de adverar, de aceea vom avea nevoie de metoda ”PiecesCanRemove”.

Variabilele ”invisiblePieces” și ”piecesLeft” vor reține numărul de pise ce pot fi puse în joc, respective numărul de piese care sunt în joc.

Se va verifica fiecare loc din moară și în funcție de nivelul ales, se vor verifica unde se poate face moară. Pentru cazul 1 de mai jos avem acestă verificare la nivelul 1.

Pentru nivelul 1 se face verificarea după metoda de mai sus, numerele reprezentând locurile unde se pot face legăturile, “movedPlace” va arăta dacăo piesă a fost mutată în alt loc, iar variabila “places” restul locurilor. Modificarea fiind salvată prin “ref currentMill”.

Adică în moara curentă se vor adăuga fiecare număr în parte care reprezintă locul.

În cazul în care moara curentă este null se va returna false.

În continuare se va adăuga moara curentă la cea precedent prin:

La fel se va proceda și pentru celelalte 2 nivele. Diferenîța va fi “Board Pattern”-ul.

În continuare vom avea următoarea clasă ”PlayersViewModel, care va conține un constructor prin care vom seta ca primul jucător sa fie ”PlayerOne” cu numele "Player 1".

2.5 View-Model

Se vor salva modificările facute la nivel de User Control.

În cazul în care “PlayerOne.IsPlayersTurn” are valuarea true, înseamnă că e rândul primul jucător, iar dacă “PlayerTwo.IsPlayersTurn” are valuarea true, înseamnă ca e rândul celui de-al doilea jucător.

Se va evita ca la un jucător sa îi vină rândul de două ori, una după alta.

Se va pune culoarea albă, ca și culoare de bază prin variabila “DefaultPlaceFill”, iar prin varibila “Game” vom instanția clasa “Games” și se vor face modificările prin “this.RaiseAndSetIfChanged“.

Vom face legătura între User Control și vom pune “ButtonPage” ca fiind cea principlă.

Vom instanția fiecare din clasele de mai sus dacă valuarea la fiecare variabilă în parte este null și vom seta valuarea inițială după cum urmează:

3. Dezvolatarea proiectului din punct de vedere a utilizatorului

3.1 Pagina principală

Pagina principală constă în figura de mai jos (Fig. 3.1 – Button Page) unde am creat un User Control.

Fig. 3.1 – Button Page

Acesta va fi legat prin Data Binding la “ViewModel”.

Pentru această pagină am creat un grig și 5 butoane, Option, New Game, Help, License și Exit. Iar la fiecare buton în parte am atribuit culoarea de mai sus și de asemenea o metodă.

Obiectul de mai sus “ViewModel” aparține aplicației “Application.Resources” este folosit pentru a transmite resurse prin Window și elementele aplicației. În plus, proprietatea resurselor este inclusă în calea de căutare a resurselor, care este traversată în următoarea ordine: Elemente, Ferestre, Application.Resources, Sistem, interfața cu utilizatorul (UI) elemente pot lega la resursele aplicatie domeniul de aplicare. În plus, în cazul în care schimbarea de resurse, sistemul de resurse asigură că proprietățile elementelor care sunt legate de aceste resurse sunt actualizate automat pentru a reflecta schimbarea. Iar clasa de bază după care aceste schimbări vor avea loc va fi “ViewModel”.

Vom avea un obiect “oldContent” căruia îi vom da valuarea Content.

Vom crea o metodă pentru butonul NewGame, unde vom crea o nouă pagină de jocuri:

Vom salva nivelul ales din pagina de opțiune:

După salvarea nivelului afișăm un mesaj cu opțiunea salvată, după care prin obiectul ”Content” revenim la pagina principlă.

Pentru butonul Help și License vom crea pagini noi schimbând și obiectul Content.

Iar în cele din urmă, prin butonul Exit vom putea închide aplicația. Codul de mai jos face acest lucru automat.

3.2 Pagina de nivel

În acest User Contrl vom avea un Grid, împarțit în 7 linii și 7 coloane. Iar o celulă este locul unde se pot plasa piesele. În acest caz le-am numit places, mai sus. (Fig. 3.4 – Level Page)

Fig. 3.2 – Level Page

Vom avea următoarea enumerare “SelectState” în care:

Neutral, va fi folosit la început

PlaceNew, va fi folosit pentru plasarea pieselor

RemoveOpponentPieces, pentru a lua o piesă de la adversar

MoveExisting, pentru a muta o piesă

Aici vom folosi Neutral din enumerare, pentru al atribui variabilei “currentState”.

Varibila “place” este egal cu “game.Places.FirstOrDefault” care returnează primul element din secvența de mai jos, iar dacă nu s-a gasit acest element default.

Vom verifica dacă starea jocului îi să se ia o piesă de la celălalt jucător. După care vom mai verifica dacă jucătorul care urmează este numărul 1 și dacă starea de loc al jucătorului este P2. Adică dacă jucătorul are piese.

În acest caz se va lua o piesă de la jucătorul 2.

Dacă jucatorul al doilea are 3 piese pe tablă, dar nu mai are piese pe care sa le poată pune pe tablă, jocul va continua.

Dar dacă jucatorul al doilea are doar 2 piese pe tablă, dar nu mai are piese pe care sa le poată pune pe tablă, jocul va lua sfârșit. Și o nouă pagină va aparea: “GameOverPage”.

Același lucru va trebui făcut și pentru al doilea jucător.

După care vom mai verifica dacă jucătorul care urmează este numărul 1 și dacă starea de loc al jucătorului este P1. Adică dacă jucătorul are piese.

În acest caz se va lua o piesă de la jucătorul 1. Dacă primul jucator are 3 piese pe tablă, dar nu mai are piese pe care sa le poată pune pe tablă, jocul va continua.

Dar dacă primul jucatorul are doar 2 piese pe tablă, dar nu mai are piese pe care sa le poată pune pe tablă, jocul va lua sfârșit. Și o nouă pagină va aparea: “GameOverPage”.

Se va schimba rândul jucătorului apelând metoda SwitchTurns.

Dacă jocul poate continua, și dacă locul este diferit de neocupat, înseamnă că pe acel loc este deja o piesă, iar în acest caz nu vom face nimic, ci vom trece la următoarea etapă, în care dacă este rândul primul jucător, se va pune status-ul corespunzător.

Se va scădea de fiecare dată pisele invizibile, iar numărul pieselor rămase va crește. Cu alte cuvinte jucătorul va pune o piesă pe tablă și va veni rândul celuilalt să mute.

Același lucru se va face și pentru al doilea jucâtor.

Dacă jocul poate continua, și dacă locul este diferit de neocupat, înseamnă că pe acel loc este deja o piesă, iar în acest caz nu vom face nimic, ci vom trece la următoarea etapă, în care dacă este rândul primul jucător, se va pune status-ul corespunzător.

Se va scădea de fiecare dată pisele invizibile, iar numărul pieselor rămase va crește. Cu alte cuvinte jucătorul va pune o piesă pe tablă și va veni rândul celuilalt să mute.

În caz ca toate piesele sau pus deja pe tablă jocul poate continua.

În cazul în care nu s-a selectat nici o piesă ca să se poată muta, se va putea scoate în evidență piesa, prin îngoșarea marginii piesei respective.

Când s-a selectat piesa, se va putea muta. Acest lucru se va întâmpla în continuare pentru fiecare dintre jucători, separate.

Se va verifica dacă s-a selectat sau nu o piesă. În continuare, când va fi rândul primului jucător și s-a ales o piesă pentru mutare se v-a putea muta piesa

3.3 Pagina de opțiune

În pagina de opțiuni vom avea 3 butoane de tip radio. Prin cele 3 cazuri din switch, se poate alege nivelul dorit. Cazul 1 corespunde cu nivelul 1, cazul 2 cu nivelul 2, iar ultimul cu nivelul 3.

Și nu în ultimul rând se va salva opțiunea în variabila “Level”.

Pagina de opțiune de asemenea va avea un buton de salvare, după cum am spus mai sus.

Fugura de mai jos arată această pagină (Fig. 3.3 – Option Page):

3.4 Pagina de joc

Pagina ”The Games Page” va arăta în felul următor (Fig. 3.4 – The Games Page)

Fig. 3.4 – The Games Page

În această pagină vom crea liniile roșii care reprezintă legăturile dintre tiles ( sau places, locurile unde se pot plasa piesele ).

De fapt liniile sunt 5 pătrate.

Primul îi cel de dinafară, al doilea cel din mijloc, iar în cele din urmă 3 în mijloc.

Pentru primul nivel vom ascunde pătratele 3, 4 și 5 deci numai cele din mijloc.

Pentru cazul al doilea, pentru nivelul 2, nu vom ascunde nici un pătrat, deoarece așa va arăta nivelul.

Iar pentru ultimul caz, nivelul al treilea, vom ascunde din nou pătratele 3, 4 și 5.

După care vom face ca modificările să fie vizibile și la nivel de window.

3.5 Pagina de nume

Numele ”Player1”, “Player2”vor fi de tip TextBlock și de asemenea numerele scrise de desuptul ”Pieces Left” deoarece acestea se vor modifica prin data binding.(Fig 3.5 – Player Name)

Fig. 3.5 – Player Name

Se va face la ”layer1” binding la ”PlayerOne.Name”, adică se face update automat la numele introdus. La numărul de sub ”Pieces Left” se va face binding la "{Binding Player1.PiecesLeft}". Desigur toate astea se vor fce în interiorul unui Stack Panel.

La se va proceda și pentru cel deal doilea jucător.

3.6 Pagina de jucători

În acest User Control vom folosi un buton cu textul ”Next” Două textboxuri care pot fi completate cu numele jucătorilor și un text block cu textul ”VERSUS”. (Fig. 3.6 – Player Page)

3.7 Pagina de câștigător

În continuare, în următorul User Control vom vom afișa jucătorul care câștigă. Acest lucru se va face tot prin binding “Game.Winner”.

Un exemplu va fi figura următoare:

Fig.3.7 – The Winner Page

3.8 Pagina de ajutor

Fig. 3.8- Help Page

Help page ca fi la îndemâna tuturor. În această pagină s-a utilizat Rich Text Box, pentru a putea fi folosite și fonturile, dar și pentru a putea modifica mărimea scrisului. Acesta a fost introdus într-un Scroll Viewer.(Fig. 3.8 – Help Page).

Se va folosi metoda ”SetRtf” pentru a localiza fișierul în care se află HelpPage.rtf.

Această metodă va deschide fisierul de care avem nevoie, va citit din el, după care-l va afișa.

2.9 Pagina de licență

Și aici se va folosi aceeași metoda ca mai sus.( Fig. 3.9- License Page)

Fig. 3.9- License Page

În această pagină s-a utilizat Rich Text Box, pentru a putea fi folosite și fonturile, dar și pentru a putea modifica mărimea scrisului. Acesta a fost introdus într-un Scroll Viewer.(Fig. 3.9 – License Page).

Se va folosi metoda ”SetRtf” pentru a localiza fișierul în care se află HelpPage.rtf.

Această metodă va deschide fisierul de care avem nevoie, va citit din el, după care-l va afișa.

4.Utilizarea aplicației.

Acestă apliacație este un joc de strategie. Pe prima pagină se pot găsi 5 butoane.

Primul buton, este opțiunea jocului, adică aici se poate alege nivelul dorit pentru joc. Al doilea buton este New Game, aici se poate începe jocul. La al treilea buton se află regulile jocului. Al patrulea buton conține drepturile de autor asupra aplicației. Și nu în ultimul rând butonul de ieșire.

La pagina de opțiuni exită 3 nivele din care se pot alege, cu câte o imagine corespunzătoare. În clipa în care se salvează opțiunea, va apărea o fereastră cu va informa și va duce înapoi jucătorul la pagina principală. De unde dacă se dorește se pot citi din nou regulile, iar dacă nu se poate începe jocul.

Înainte de a începe jocul se vor putea introduce numele celor 2 jucători.

Jocul în sine, constă în a pune una lângă alta sau în aceeși linie 3 piese pentru a face moara. Liniile roșii de pe tablă vor arăta legaturile. În funcție de nivelul ales numărul pieselor diferă. Fiecare jucător are la dispoziție: pentru primul nivel 5 piese, pentru al doilea 7, iar pentru ultimul 9 piese.

Când toate piesele au fost puse în joc, pisele se vor putea muta de pe o poziție pe alta. Scopul va fi același, de a face moara. Când se face moara, jucătorul care a realizat acest lucru, va putea sa ia o piesă de la adversar. Jocul se termină când unul dintre cei doi jucători va rămâne numai cu două piese, caz în care celălalt câștigă, deoarece avem nevoie de trei piese pentru a face moara.

În partea de sus a paginii va apărea numele jucătorilor, cu numărul de piese puse sau disponibile în joc.

La sfârșitul aplicației se va afișa câștigătorul și numele acestuia.

Bibliografie

https://msdn.microsoft.com/library/windows/apps/xaml/Hh758320#change_notification

https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx

http://www.c-sharpcorner.com/UploadFile/dacca2/implement-ienumerable-interface-in-C-Sharp/

http://jen20.com

http://leecampbell.blogspot.ro/2010/08/reactive-extensions-for-net.html

http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

http://www.codeproject.com/Articles/646361/Reactive-Programming-for-NET-and-Csharp-Developers

https://msdn.microsoft.com/en-us/library/gg405484%28v=pandp.40%29.aspx

https://reactiveproperty.codeplex.com/

https://www.nuget.org/

http://www.codeproject.com/Articles/328361/Understanding-and-Implementing-Observer-Pattern-in

http://www.introtorx.com/

http://www.danharman.net/2011/06/13/using-reactiveui-to-integrate-inotifypropertychanged-iobservable/

https://msdn.microsoft.com/library/windows/apps/xaml/Hh758320#change_notification

What is NuDoq?

http://blogs.msdn.com/b/mikehillberg/archive/2009/03/20/icommand-is-like-a-chocolate-cake.aspx

http://reactiveui.readthedocs.org/en/latest/

http://blog.scottlogic.com/2012/04/20/everything-you-wanted-to-know-about-databinding-in-wpf-silverlight-and-wp7-part-two.html

Similar Posts