Proiectarea Unei Aplicatii Sub Limbajul C# Ce Simuleaza Jocul Moara
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. În capitolul doi este prezentat modul de cuantificare a datelor și implementarea acestora. 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.
2.Structura Programării Orientate pe Obiecte. Cuantificarea problemei
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.
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 ).
Î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ă.
Clasa Player 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".
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.Structura Programării Orientate pe Obiecte. Cuantificarea problemei
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.
Î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
Î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):
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.
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.
Î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)
În continuare, în următorul User Control vom vom afișa caștigă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
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.
Ș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.
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Proiectarea Unei Aplicatii Sub Limbajul C# Ce Simuleaza Jocul Moara (ID: 150256)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
