Dezvoltarea de Aplicatii Web Pentru Crearea de Puzzle Uri Online

Dezvoltarea de aplicații WEB pentru crearea de puzzle-uri online

Cuprins

INTRODUCERE

CAPITOLUL 1. PREZENTAREA TEHNOLOGIEI FOLOSITE

1.1. MICROSOFT SILVERLIGHT 5

1.1.1. Microsoft Silverlight în general

1.1.2. Plug-in-ul Silverlight

1.1.3. Instalarea plug-in-ului Silverlight

1.1.4. Cerințe de sistem

1.2. FRAMEWORK-UL .NET PENTRU SILVERLIGHT

1.3. SILVERLIGHT ȘI ALTE TEHNOLOGII

1.3.1. Silverlight versus Adobe Flash

1.3.2. Silverlight și HTML5

1.3.3. Silverlight versus Metro (și Windows 8)

1.3.4. Silverlight și Windows Presentation Foundation (WPF)

1.4. EVOLUȚIA SILVERLIGHT

1.5. APLICAȚII WEB SILVERLIGHT

1.5.1. Tipuri de aplicații

1.5.2. Compilarea aplicației Silverlight

1.5.3. Pagina de test HTML

1.6. XAML- EXTENSIBLE APPLICATION MARKUP LANGUAGE

1.6.1. Clasa de „Code-behind”

1.6.2. Resurse XAML

1.7. COMPONENTE SILVERLIGHT

1.7.1. Containere de layout

1.7.2. Proprietăți ale Layout-ului

1.7.3. Elemente de bază în Silverlight

1.8. PROPRIETĂȚI

1.8.1. Proprietăți simple

1.8.2. Proprietăți complexe

1.8.3. Proprietăți atașate (Attached Properties)

1.9. ROUTED EVENTS

1.9.1. Evenimente Core Elements

1.10. DATA BINDING ÎN SILVERLIGHT

1.11. MICROSOFT EXPRESSION BLEND

1.12. SERVICII WCF PENTRU RIA (RICH INTERNET APPLICATIONS)

CAPITOLUL 2. PREZENTAREA APLICAȚIEI

2.1. PAGINA DE START

2.2. ALEGEREA IMAGINILOR

2.3. 3X3 SLIDING PUZZLE

2.3.1. Solvabilitatea 8-puzzle

2.3.2. Rezolvare automată

2.3.3. Clasament

2.4. 4X4 ROTATING PUZZLE

2.4.1. Clasament

2.5. BAZA DE DATE

CONCLUZII

BIBLIOGRAFIE

ANEXE

Introducere

Ideile acestor două jocuri de puzzle sunt unele foarte simple, dar în același timp cuprinzătoare, ele fiind două jocuri cunoscute și iubite de multă lume. Eu mi-am ales această temă de licență și anume Dezvoltarea de aplicații Web pentru crearea de puzzle-uri online, pentru a crea o lucrare care îmbină în mod plăcut ideea jocului 8-puzzle, care în mod clasic se joacă utilizând numere, cu imagini și prelucrarea acestora, într-un mediu accesibil multor oameni, Web-ul. În cazul jocului 4×4, provocarea este de a termina cât mai repede recrearea imaginii inițiale și astfel clasarea pe un loc cât mai înalt în clasament.

Partea mai dificilă constă în faptul că, deși aceste jocuri au principii și reguli destul de simple și clare, transpunerea acestei logici de joc în logica și algoritmica calculatorului presupune un proces destul de minuțios și dificil pe-alocuri. Alegerea imaginii, tăierea acesteia în bucățile de joc, aranjarea acestora astfel încât în cazul puzzle-ului 3×3 să conducă la soluție sau în cazul puzzle-ului 4×4 să fie cât mai dificil și astfel să ofere o provocare utilizatorului, sunt pași care trebuie gândiți în mod logic și apoi transpuși în logica computațională pentru crearea unei aplicații complete, complexe și cu un parcurs bine pus la punct.

Ca și tehnologie am ales Microsoft Silverlight pentru că am considerat că reprezintă un avantaj faptul că întregul cod din spatele aplicației a putut fi scris în C Sharp. Consider că C Sharp este un limbaj de nivel înalt foarte ofertant, în cadrul lui Visual Studio, un mediu de lucru care pune la dispoziție diverse facilități pentru rezolvarea unei mulțimi de probleme. Interfața a fost scrisă cu ajutorul limbajului de marcare XAML, un limbaj intuitiv al cărui mod de scriere a fost ușor de învățat și de adaptat în diverse situații.

Această lucrare este împărțită în două capitole. În primul capitol am explicat tehnologia folosită pentru rezolvarea acestei teme, iar în capitolul al doilea am prezentat aplicația cu interfața, funcționalitatea și logica jocurilor. Pe subiectul tehnologiei Silverlight am vorbit despre evoluția acesteia de-a lungul anilor, despre compararea acesteia cu alte tehnologii existente și de ce ar putea să devină tehnologia Silverlight mai bună decât ele în viitor. Am prezentat diversele facilități oferite de Silverlight pentru a duce la bun sfârșit această lucrare, cum ar fi: data binding-ul, multiplele containere și controale existente, facilitarea lucrului cu servicii Web pentru baza de date. În capitolul care conține descrierea aplicației am vrut sa tratez patru aspecte, patru părți în care am împărțit aplicația și anume: Alegerea imaginilor, care se face la fel indiferent de tipul de puzzle pentru care va opta utilizatorul ulterior, puzzle-ul 3×3 cu toate aspectele sale de rezolvare automată, afișarea clasamentului ș.a.m.d., puzzle-ul 4×4 cu întreaga logică din spate și baza de date cu tabelele mapate în situația de față.

O dezvoltare ulterioară a acestei aplicații o poate reprezenta faptul că aceste două jocuri pot fi incorporate în viitor în jocuri mai complexe, ca părți ale unor sarcini sau ca nivele de trecut în cadrul lor.

În concluzie, pot spune că dezvoltarea acestor jocuri, înțelegerea și rezolvarea tuturor erorilor apărute, învățarea și familiarizarea cu Microsoft Silverlight au reprezentat o provocare benefică și, consider că prin pașii urmați pentru a duce la bun sfârșit această lucrare, am învățat multe lucruri noi. Pot spune că, deși tema nu este una de actualitate, puzzle-urile acestea existând de multă vreme, am încercat să creez o aplicație îmbunătățită prin adăugarea imaginilor și astfel schimbarea „aspectului învechit” al puzzle-urilor.

Capitolul 1. Prezentarea tehnologiei folosite

Microsoft Silverlight 5

Microsoft Silverlight în general

Microsoft Silverlight este o platformă pentru crearea unor aplicații găzduite în browser, care rulează pe o varietate de sisteme de operare și care funcționează printr-un plug-in. Dacă dorim să navigăm pe o pagină care include un conținut Silverlight, atunci plug-in-ul din browser rulează, execută codul și randează conținutul într-o zonă a paginii cu un design specific. Aspectul important este că plug-in-ul Silverlight posedă un mediu de lucru mult mai bogat decât tradiționalele medii HTML și JavaScript, cu ajutorul cărora se realizează pagini Web obișnuite.

Folosit cu grijă și într-o manieră creativă se pot crea aplicații cu ajutorul lui Silverlight, care conțin grafică interactivă, animații și care pot să redea fișiere video și audio.

Aceste lucruri au mai fost încercate și cu alte tehnologii care folosesc plug-in-uri și care au vrut să depășească limitele programării Web: de exemplu Java, ActiveX și poate cea mai de succes, Adobe Flash. Chiar dacă aceste alternative se mai folosesc și astăzi, nu se poate spune că una dintre ele a reușit să se detașeze de celelalte, pentru a deveni o platformă prioritară în dezvoltarea aplicațiilor Web.

Silverlight își propune să combine puterea și suportul cross-platform (rulează pe diferite platforme) al lui Adobe Flash cu o platformă de programare de cea mai înaltă clasă care încorporează concepte fundamentale ale platformei .NET.

Deși se poate spune că deocamdată Adobe Flash are o popularitate mai mare, Silverlight prezintă câteva caracteristici arhitecturale pe care Flash nu le poate egala, si, cea mai importantă este aceea că permite dezvoltatorilor să scrie cod pe parte de client (client-side) folosind C# (C Sharp) pur.

Plug-in-ul Silverlight

Microsoft Silverlight este un plug-in pentru browser care permite aplicațiilor Web să fie dezvoltate cu feature-uri ca: animație, grafică vectorială, playback audio-video – caracteristici specifice aplicațiilor internet bogate.

Silverlight folosește o tehnică familiară pentru a extinde capabilitățile unei pagini Web standard: un plug-in de „categorie ușoară” în browser.

Avantajul acestui model „plug-in” este acela că utilizatorul este nevoit să instaleze o singură componentă pentru a vedea conținutul creat de o serie de oameni și companii diferite.

Instalarea plug-in-ului Silverlight

Instalarea plug-in-ului Silverlight presupune o descărcare sigură care trebuie mai întâi permisă de utilizator. Astfel, o dată ce plug-in-ul este instalat, browser-ul poate procesa orice conținut care folosește plug-in-ul într-un mod corect, fără alte solicitări.

Figura 1.1. Fereastra de instalare a Silverlight

Cerințe de sistem

Cu orice tehnologie Web este foarte importantă compatibilitatea cu o gamă cât mai largă de sisteme de calcul și dispozitive. Chiar dacă Silverlight este încă în dezvoltare, are un principiu bine stabilit: „să suporte toate browser-ele majore de pe MAC OS X și Windows“.

Compatibilitatea plug-in-ului Silverlight este și în acest moment bine stabilită:

Sisteme de calcul care rulează sub platforma Windows

Sisteme de calcul care rulează sub sistemul de operare Mac

Sisteme de calcul care rulează sub Linux – proiect cunoscut sub numele de Moonlight, care este dezvoltat având suportul Microsoft.

Framework-ul .NET pentru Silverlight

Framework-ul .NET pentru Silverlight este un subset al întregii platforme .NET. Aceasta pune la dispoziție caracteristicile esențiale ale dezvoltării de aplicații orientate pe obiecte, pentru acele categorii de aplicații pentru care acest tip de suport nu era în mod tradițional disponibil, cum sunt aplicațiile Web.

Următorul tabel descrie o listă parțială de caracteristici din acest framework.

Tabelul 1.1. .NET Framework pentru Silverlight

Silverlight și alte tehnologii

Silverlight versus Adobe Flash

Cel mai de succes plug-in pentru browser este Adobe Flash, care este instalat pe mai mult de 90% din browser-ele Web din lume. Flash are o lungă istorie, care se întinde pe mai mult de zece ani, începând ca o unealtă pentru adăugare de animații grafice și evoluând gradual spre o platformă pentru dezvoltarea de conținut interactiv.

Silverlight vrea să ofere dezvoltatorilor .NET o opțiune mai bună pentru crearea unui conținut Web bogat. Acesta furnizează un plug-in în browser, având caracteristici similare cu Flash, dar construit de la bază pentru platforma .NET. Silverlight suportă în mod nativ limbajul C# și încorporează o serie din conceptele platformei .NET. Ca rezultat, dezvoltatorii pot să scrie cod pe partea de client (- client-side) pentru Silverlight în același limbaj pe care îl folosesc și pentru codul pe partea de server (- server-side), cum ar fi C# sau Visual Basic.

Plug-in-ul Silverlight are o listă impresionantă de caracteristici, unele dintre ele întâlnite și la Adobe Flash, iar unele pe deplin inedite. Unele exemple sunt:

Desenare 2D: Silverlight oferă un model bogat de desenare 2D. Conținutul poate fi manipulat pe partea de client, astfel încât să răspundă la evenimente, ceea ce face ușoară adăugarea de interactivitate în orice desenăm.

Controale: Silverlight are câteva controale predefinite, esențiale, incluzând butoane, casete de text, liste. Lor li se poate oferi un stil diferit dacă nu se dorește păstrarea aspectului predefinit, ci doar a funcționalității.

Animații: Silverlight dispune de un model de animații bazat pe timp, care lasă utilizatorul să decidă ce se întâmplă și cât timp să dureze.

Media: Silverlight oferă posibilitatea redării unei serii de formate video.

Data binding: Silverlight împreună cu „data binding“ oferă un mod convenient de afișare a unei cantități mari de date scriind un minim de cod.

Multithreading: o aplicație Silverlight poate profita de capacitatea de multithreading a sistemelor de operare moderne. Se poate rula foarte ușor cod în background care să realizeze sarcini consumatoare de timp.

Silverlight și HTML5

Deși există un consens că HTML5 va fi viitorul Web-ului, se poate spune că funcționalitățile pe care această tehnologie le promite sunt destul de departe de ceea ce pot oferi astăzi, Silverlight sau Flash.

Se poate spune că Silverlight oferă posibilitatea creării unor aplicații bogate cu un set de funcționalități puternic și bine dezvoltat, dar pe de altă parte HTML5 poate să cuprindă orice browser modern pentru desktop.

HTML5 are deocamdată mai puțin suport decât Silverlight și, deși au fost promise mai multe funcționalități și noutăți pe viitor, acest lucru va mai putea dura câțiva ani.

Silverlight are funcționalități și caracteristici la care HTML nu are echivalentte în orice desenăm.

Controale: Silverlight are câteva controale predefinite, esențiale, incluzând butoane, casete de text, liste. Lor li se poate oferi un stil diferit dacă nu se dorește păstrarea aspectului predefinit, ci doar a funcționalității.

Animații: Silverlight dispune de un model de animații bazat pe timp, care lasă utilizatorul să decidă ce se întâmplă și cât timp să dureze.

Media: Silverlight oferă posibilitatea redării unei serii de formate video.

Data binding: Silverlight împreună cu „data binding“ oferă un mod convenient de afișare a unei cantități mari de date scriind un minim de cod.

Multithreading: o aplicație Silverlight poate profita de capacitatea de multithreading a sistemelor de operare moderne. Se poate rula foarte ușor cod în background care să realizeze sarcini consumatoare de timp.

Silverlight și HTML5

Deși există un consens că HTML5 va fi viitorul Web-ului, se poate spune că funcționalitățile pe care această tehnologie le promite sunt destul de departe de ceea ce pot oferi astăzi, Silverlight sau Flash.

Se poate spune că Silverlight oferă posibilitatea creării unor aplicații bogate cu un set de funcționalități puternic și bine dezvoltat, dar pe de altă parte HTML5 poate să cuprindă orice browser modern pentru desktop.

HTML5 are deocamdată mai puțin suport decât Silverlight și, deși au fost promise mai multe funcționalități și noutăți pe viitor, acest lucru va mai putea dura câțiva ani.

Silverlight are funcționalități și caracteristici la care HTML nu are echivalent:

HTML5 nu poate oferi același suport pentru redare video și accelerare hardware a graficii.

Silverlight oferă integrare ASP.NET: Silverlight facilitează interogări către o bază de date pe server printr-un serviciu Web

HTML5 nu are posibilitatea să apeleze la componente din sistemul Windows

Silverlight posedă un API de nivel înalt de programare

Silverlight versus Metro (și Windows 8)

Când Microsoft a anunțat Windows 8 și împreună cu acesta un nou model de programare al aplicațiilor client bogate, unii s-au gândit că această tehnologie ar putea înlocui Silverlight. Totuși Metro a fost construit să faciliteze un fel de aplicații total diferit: o aplicație de categorie ușoară care să ruleze în viitor pe tablete care rulează sub Windows 8. De fapt, Metro poate fi văzută ca un potențial succesor al framework-ului de la Microsoft, numit Windows Presentation Foundation. Metro nu poate rula pe alte platforme care nu aparțin de Microsoft sau pe altă versiune de Windows decât Windows 8.

Silverlight și Windows Presentation Foundation (WPF)

Unul dintre cele mai importante aspecte este faptul că Silverlight împrumută modelul folosit de WPF pentru realizarea de interfețe bogate pentru utilizator.

Windows Presentation Foundation este un kit modern pentru crearea de aplicații Windows. A fost introdus în .NET 3.0 ca succesorul pentru Windows Forms. WPF este remarcabil nu doar pentru că simplifică dezvoltarea cu un set puternic de caracteristici de nivel înalt, ci și pentru că mărește performanța prin randarea direct prin DirectX.

Silverlight nu poate să preia toate caracteristicile WPF-ului, pentru că cele mai multe dintre ele se bazează pe capacitățile sistemului de operare, incluzând drivere de afișaj specifice Windows și tehnologia DirectX. De aceea Silverlight folosește un subset al modelului WPF.

Câteva dintre detaliile comune sunt:

Pentru a defini o interfață pentru utilizator în Silverlight se poate folosi XAML, la fel ca în WPF.

Silverlight împrumută mai multe dintre controalele de bază din WPF împreună cu același sistem de customizare.

Pentru a desena grafice 2D în Silverlight, se folosesc forme (shapes), transformări, geometrii și brushes, toate foarte similare cu corespondentele lor din WPF.

Silverlight oferă un model de animații bazat pe storyboards care funcționează în același mod ca sistemul de animații din WPF.

Pentru afișarea de conținut video sau audio se folosește clasa MediaElement, la fel ca în WPF.

Evoluția Silverlight

Silverlight 1

Prima versiune de Silverlight a fost lansată în anul 2007. Ea includea caracteristici pentru desenarea 2D, dar nu includea motorul CLR (Common Language Runtime Engine) și suport pentru limbajele .NET, astfel că programatorii erau nevoiți să scrie codul în JavaScript. Această versiune a fost văzută ca o mutare împotriva lui Adobe Flash.

Silverlight 2

A apărut în anul 2008 și a constituit o mare schimbare. A adăugat CLR, un subset al claselor platformei .NET și un model de interfață bazat pe Windows Presentation Foundation. Astfel Silverlight 2 a fost una dintre cele mai așteptate lansări în istoria Microsoft.

Silverlight 3

A treia versiune a fost anunțată pe data de 12 septembrie 2008 și lansată în anul 2009. S-a dorit îmbunătățirea performanțelor și au fost incluse controale noi, efecte grafice și un sistem de navigare.

Silverlight 4

Silverlight 4 a fost lansat pe 15 aprilie 2010 și aduce funcționalități noi precum funcția „drag and drop”, suport pentru printare, suport pentru camera Web și microfon. Aceasta este versiunea care primește cele mai multe actualizări.

Silverlight 5

Silverlight 5 a fost lansat pe 9 decembrie 2011. Pe lângă adăugarea de multiple funcționalități, această versiune poate funcționa pe procesoare pe 64 de biti.

Aplicații Web Silverlight

Tipuri de aplicații

Se pot crea două tipuri de site-uri Silverlight:

Un site obișnuit cu pagini HTML. În acest caz, punctul de intrare în aplicația Silverlight este o pagină HTML care include o regiune de conținut Silverlight.

Un site ASP.NET. În acest caz, Visual Studio creează două proiecte: unul care conține aplicația Silverlight și unul care să conțină site-ul ASP.NET server-side care va fi implementat împreună cu fișierele Silverlight. Punctul de intrare în aplicație poate să fie o pagină HTML obișnuită sau poate să fie o pagină Web ASP.NET care include conținutul generat de server.

Compilarea aplicației Silverlight

Aplicațiile Silverlight pot fi compilate ca aplicații .NET normale, scrise în cod standard C#, doar că având un set mai limitat de biblioteci. Modelul de compilare al lui Silverlight are mai multe avantaje, incluzând deployment ușor și o performanță mult îmbunătățită în comparație cu JavaScript.

Assembly-ul compilat Silverlight include codul compilat și documentele XAML pentru fiecare pagină din aplicație, care sunt încorporate în acesta ca resurse. Proiectul Silverlight este compilat într-un fișier DLL numit după numele proiectului. Assembly-ul de proiect este depozitat într-un folder Bin\Debug din proiect, împreună cu alte fișiere importante:

Un fișier PDB, care conține informații obligatorii pentru debugging-ul din Visual Studio. Este denumit după numele proiectului cu extensia .pdb.

AppManifest.xaml, care conține dependințe de assembly

Assembly-uri dependente: Directorul Bin\Debug conține assembly-urile pe care le folosește proiectul Silverlight.

Pagina de test este pagina de intrare pe care utilizatorul o cere pentru a porni aplicația Silverlight

Un fișier XAP ce reprezintă un pachet Silverlight care conține tot ce este nevoie pentru a face deploy aplicației, incluzând manifestul aplicației, assembly-ul proiectului și alte assembly-uri pe care le folosește aplicația.

Pagina de test HTML

Această pagină poate fi punctul de intrare într-o aplicație Silverlight, mai exact în conținutul Silverlight al acesteia. Ea nu conține cod C# sau XAML efectiv, ci doar setează regiunea unde va exista conținut Silverlight, folosind și cod JavaScript.

O pagină de test HTML este creată automat de către Visual Studio, care o denumește după numele proiectului adăugându-i „TestPage” la sfârșit, obținând următorul rezultat:

SilverlightApplication1TestPage.html.

Conținutul unei astfel de pagini este următorul:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>PuzzlePhotos</title>

<style type="text/css">

</style>

<script type="text/javascript">

</script>

</head>

<body>

<form id="form1" runat="server" style="height:100%">

<div id="silverlightControlHost">

<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="200%">

<param name="source" value="ClientBin/PuzzlePhotos.xap"/>

<param name="onError" value="onSilverlightError" />

<param name="background" value="white" />

<param name="minRuntimeVersion" value="5.0.61118.0" />

<param name="autoUpgrade" value="true" />

<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=5.0.61118.0" style="text-decoration:none">

<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>

</a>

</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe>

</div>

</form>

</body>

</html>

Conținutul Silverlight se află între tag-urile elementului <div>. Acesta conține un element <object> care încarcă plug-in-ul Silverlight. Acest element include patru atribute cheie la care se mai pot adăuga și altele. Aceste elemente sunt specificate prin tag-ul <param> și arată opțiuni adiționale ale plug-in-ului Silverlight.

Parametrul source – un Uri (Uniform Resource Identifier) care pointează către fișierul XAP din aplicație. Acest parametru este unul obligatoriu.

Parametrul onError – este un handler de eveniment JavaScript care este declanșat atunci când o eroare netratată apare în plug-in-ul Silverlight sau în codul aplicației.

Parametrul background – reprezintă culoarea folosită pentru fundalul zonei de conținut Silverlight, în spatele oricărui conținut afișat, dar în fața conținutului HTML care ocupă același spațiu.

Parametrul minRuntimeVersion – reprezintă versiunea minimă de Silverlight pe care clientul trebuie să o aibă pentru a putea rula aplicația.

Parametrul autoUpgrade – reprezintă o valoare booleană care specifică dacă plug-in-ul Silverlight ar trebui să încerce să se actualizeze singur. Valoarea sa implicită este setată pe true.

Parametrul enableHtmlAccess – reprezintă o valoare booleană care specifică dacă plug-in-ul Silverlight are acces la modelul de obiecte HTML. Se setează pe true atunci când se dorește o interacțiune cu elemente HTML din codul Silverlight.

Parametrul initParams – reprezintă un string care se poate folosi pentru a transmite informații customizate de inițializare. Este util atunci când se dorește să se folosească aceeași aplicație Silverlight în moduri diferite, pe pagini diferite.

Parametrul splashScreenSource – reprezintă locația paginii XAML de „splash screen” care apare pe ecran cât timp se descarcă fișierul XAP.

Parametrul windowless – reprezintă o valoare booleană care specifică dacă plug-in-ul randează pagina în mod windowed sau windowless.

Parametrul onSourceDownloadProgressChanges – reprezintă un handler de eveniment JavaScript care este declanșat atunci când o parte din fișierul XAP a fost descărcat.

Paramterul onSourceDownloadComplete – reprezintă un handler de eveniment JavaScript care este declanșat atunci când s-a terminat întreaga descărcare a fișierului XAP.

Parametrul onLoad – reprezintă un handler de eveniment JavaScript care este declanșat atunci când limbajul de marcare din fișierul XAP a fost procesat, iar prima pagină a fost încărcată.

Parametrul onResize – reprezintă un handler de eveniment JavaScript care este declanșat atunci când dimensiunea unei regiuni de conținut Silverlight a fost modificată.

XAML- Extensible Application Markup Language

XAML este un limbaj de marcare folosit pentru a instanția obiecte .NET. Chiar dacă XAML este o tehnologie care poate fi aplicată în mai multe domenii, ea a fost inițial construită ca parte a Windows Presentation Foundation, unde le permite dezvoltatorilor să construiască interfețe bogate pentru utilizatori. Același standard se folosește și pentru a construi aplicații în Silverlight.

Pentru a manipula elemente XAML, se scrie cod C# client-side. XAML este un limbaj bazat pe XML, care constă în elemente ce pot fi imbricate în orice ordine și aranjamente dorite.

XAML este limbajul din spatele prezentării vizuale ale unei aplicații. Orice cod scris în XAML poate fi exprimat folosind și un limbaj mai tradițional în .NET (C# sau Visual Basic).

Figura 1.2. XAML și C#

Câteva reguli ale XAML:

Fiecare element din XAML se mapează cu o instanță a unei clase din Silverlight. Numele elementului este identic cu cel al clasei. De exemplu elementul <Button> creează un obiect de tipul „Button”.

Ca în orice document XML, se pot imbrica elemente în interiorul altor elemente, ceea ce de obicei înseamnă apartenența și includerea unui element în elementul în care va fi introdus.

Proprietățile fiecărei clase se pot seta prin atribute.

În Silverlight, clasele sunt referențiate prin maparea spațiilor de nume XML cu spațiile de nume din Silverlight. Atributul xmlns este un atribut specializat în XML și este rezervat pentru declararea de spații de nume.

Clasa de „Code-behind”

XAML permite construirea unei interfețe pentru utilizator, dar pentru a face o aplicație funcțională, este nevoie de o cale de conectare a handler-elor de evenimente la codul aplicației. XAML face ca acest lucru să fie simplu prin atributul Class:

<UserControl x:Class="SilverlightApplication1.MainPage">

Atributul Class comunică parser-ului Silverlight să genereze o clasă nouă cu numele specificat. Această clasă derivă din clasa numită de elementul XAML. Astfel se creează clasa numită SilverlightApplication1.MainPage, care derivă din clasa UserControl.

În mod uzual, fiecare pagină XAML va avea o clasă corespunzătoare de code-behind, scrisă în cod C#. Visual Studio creează o clasă de code-behind pentru MainPage.xaml numită MainPage.xaml.cs care arată pentru început așa:

namespace SilverlightApplication1

{

public partial class MainPage : UserControl

{

public MainPage()

{

InitializeComponent();

}

(…)

}

Momentan această clasă nu are o funcționalitate anume, dar include un detaliu important și anume constructorul implicit care apelează funcția InitializeComponent(), atunci când se creează o instanță a acestei clase. Această funcție parsează limbajul de marcare, creează obiectele corespunzătoare, le setează proprietățile și le atașează handler-ele de evenimente care au fost definite.

Resurse XAML

Silverlight include un sistem de resurse care se integrează strâns în XAML. Folosind resursele se pot face următoarele:

Crearea unor obiecte non-vizuale: Acest lucru este util dacă alte elemente folosesc aceste obiecte.

Refolosirea obiectelor: o dată definită o resursă, multiple alte elemente o pot folosi.

Centralizarea detaliilor: este mai simplu să centralizăm informații într-un singur loc și să le extragem de acolo la nevoie, decât să le căutăm în pagini diferite, unde ar fi mai dificil de găsit și eventual de modificat.

Componente Silverlight

Containere de layout

O fereastră în Silverlight poate conține un singur element. Pentru a crea o interfață cu mai multe elemente, trebuie să plasăm în pagina noastră un container și apoi să adăugăm elementele dorite pe acest container.

Toate containere-le de layout în Silverlight sunt panel-uri derivate din clasa abstractă System.Windows.Controls.Panel.

StackPanel: Plasează elementele într-o stivă verticală sau orizontală. Acest layout container este folosit de obicei pentru secțiuni mici dintr-o pagină mai mare și complexă.

Figura 1.3. StackPanel

WrapPanel: Plasează elementele într-o serie de linii înfășurate. În orientare orizontală, acest container pune obiectele într-un rând de la stânga la dreapta, de sus în jos. În orientare verticală, acest container plasează elementele pe coloane de sus în jos și apoi folosește coloane adiționale pentru a pune elementele rămase.

Figura 1.4. WrapPanel

DockPanel: Aliniază elementele pe toată marginea container-ului.

Figura 1.5. DockPanel

Grid: Aranjează elementele pe linii și coloane după un tabel invizibil. Este unul dintre cele mai flexibile și cele mai folosite containere.

Figura 1.6. Grid

Canvas: Permite elementelor să fie poziționate absolut cu ajutorul coordonatelor fixe. Acest container este cel mai simplu, dar și cel mai puțin flexibil.

Figura 1.7. Canvas

Proprietăți ale Layout-ului

HorizontalAlignment

Această proprietate determină cum este un element copil poziționat în interiorul unui layout container, atunci când este un spațiu orizontal mai mare disponibil. Se poate alege una din următoarele opțiuni: Center (centru), Left (stânga), Right (dreapta) sau Stretch.

VerticalAlignment

Această proprietate determină cum este poziționat un element copil în interiorul unui layout container, atunci când este un spațiu vertical mai mare disponibil. Se poate alege una din următoarele opțiuni: Center (centru), Top (sus), Bottom (jos), sau Stretch.

Margin

Se folosește pentru a adăuga spațiu în jurul unui element.

MinWidth și MinHeight

Aceste proprietăți setează dimensiunile minime ale unui element. Dacă un element este prea mare pentru layout containerul de care aparține, acesta va fi trunchiat pentru a se potrivi.

MaxWidth și MaxHeight

Aceste proprietăți setează dimensiunile maxime ale unui element.

Width și Height

Aceste proprietăți sunt folosite pentru a seta în mod explicit dimensiunea unui element. Acestea nu o să aibă efect dacă depășesc sau dacă nu sunt în limitele valorilor stabilite de MinWidth, MinHeight respectiv MaxWidth, MaxHeight.

Elemente de bază în Silverlight

AutoCompleteBox – o casetă de text specializată care oferă o listă de posibile potriviri pe măsură ce utilizatorul tastează un text.

Border – un contur sau o margine rectangulară sau rotunjită, care este desenată în jurul unui singur element.

Button – un buton cu un fundal gri, pe care utilizatorul poate să dea click pentru a lansa o comandă.

Calendar – un calendar care permite utilizatorului să selecteze o dată.

Canvas – un container de layout care permite așezarea componentelor la coordonate precise.

CheckBox – o casetă care poate fi bifată sau debifată, cu un conținut opțional lângă ea.

ComboBox – o listă de elemente, din care poate fi ales unul singur.

ContentControl – este controlul de bază din care derivă toate controalele. Deși poate fi utilizat direct, este mai probabil să se lucreze direct cu descendenții lui.

DataGrid – un control de date bogat, care arată o colecție de obiecte într-un tabel cu mai multe coloane și oferă posibilități de selecție sau sortare.

DataPager – un control care oferă paginare pentru alte surse de date și poate să lucreze împreună cu alte elemente, cum ar fi DataGrid.

DatePicker – o casetă de text pentru introducerea de dată calendaristică, cu un calendar pentru o selecție ușoară.

Ellipse – un element de desenare geometrică, ce reprezintă o elipsă.

Frame – un container care afișează o pagină XAML separată, în interiorul unei pagini obișnuite. Acestea se pot folosi în diferite moduri pentru a crea un sistem de navigare complex.

Grid – este un container de layout, care plasează elemente într-un tabel invizibil, pe linii și coloane.

GridSplitter – o bară care permite utilizatorului să schimbe înălțimea unor rânduri adiacente, respectiv lățimea coloanelor adiacente într-un Grid.

HyperlinkButton – un link care direcționează utilizatorul către o altă pagină.

Image – un element care afișează o imagine.

Label – este un control de afișare de text, o etichetă.

ListBox – o listă de elemente, din care unul singur poate fi selectat.

MediaElement – un fișier de tip media, cum ar fi o fereastră de video.

MultiScaleImage – un element care suportă caracteristica de Deep Zoom a lui Silverlight și permite utilizatorului să facă zoom într-o locație specifică, într-o imagine de dimensiuni mari.

PasswordBox – o casetă de text care ascunde textul pe care îl introduce utilizatorul.

ProgressBar – o bară colorată care indică un procent din completarea unei anumite sarcini sau acțiuni.

RadioButton – un cerc mic, care reprezintă o alegere dintr-un grup de opțiuni, cu un conținut opțional afișat lângă el.

Rectangle – un element de desenare geometrică, ce reprezintă un dreptunghi.

RichTextBox – o casetă de text editabilă, care suportă text formatat.

ScrollViewer – un container care ține orice conținut de mari dimensiuni și îl face scrollable.

Slider – un control care lasă utilizatorul să seteze o valoare numerică prin tragerea unui buton pe o anumită direcție.

StackPanel – un container de layout care stivuiește elemente de sus în jos sau de la stânga la dreapta.

TabControl – un container care plasează elemente în file (tab-uri) separate și permite utilizatorului să vadă o singură pagină la un moment dat.

TextBlock – un control de afișare de text, care include abilitatea de a da formatări diferite unor bucăți de text conținut.

TextBox – un control familiar de introducere de text.

TreeView – un control de date bogat, care arată un arbore de obiecte cu câte nivele ierarhice este nevoie.

ViewBox – un container care poate să își scaleze conținutul în sus sau în jos, în funcție de nevoi.

WebBrowser – o fereastră cu un browser în Internet Explorer, care poate fi încorporat într-o fereastră Silverlight, într-o aplicație de tip out-of-browser.

Proprietăți

Atributele unui element XML setează proprietățile elementului corespunzător din Silverlight. Sintaxa constă în numele atributului care numește proprietatea, urmat de operatorul de atribuire (=). Valoarea atributului este întotdeauna specificată ca un șir de caractere, între ghilimele („ ”) și de aceea parser-ul XAML trebuie să facă mai multe conversii între tipul „string” și tipurile proprietăților obiectelor, care pot reprezenta orice tip .NET. Aceste conversii sunt realizate de type converters (convertori de tipuri), o piesă de bază, împrumutată de la întreaga platformă .NET.

Un convertor de tipuri are un rol foarte important și anume să ofere metode care să poate să convertească un tip de date .NET la un alt tip, iar pentru aceasta parser-ul XAML urmează doi pași pentru a găsi un astfel de convertor:

Examinează declarația proprietății, căutând un atribut de tip TypeConverter. Dacă se folosește, spre exemplu, atributul Foreground, (care reprezintă culoarea fontului) .NET verifică declarația proprietății Foreground.

Dacă nu există un atribut de tip TypeConverter în declarația proprietății, parser-ul XAML verifică declarația clasei de care aparține tipul respectiv. Dacă nu se găsește niciun element de tip TypeConverter în declarația proprietății sau respectiv declarația clasei, parser-ul XAML va genera o eroare.

Proprietăți simple

<Button Background="Transparent" Width="90" Height="40" Content="Content"/>

În acest exemplu, clasa Button trebuie să furnizeze următoarele proprietăți: Background (fundal), Width (lățime), Height (înălțime), Content (conținut).

Proprietăți complexe

În unele cazuri, proprietățile pot să reprezinte obiecte care la rândul lor au un set propriu de proprietăți. Pentru aceasta XAML oferă sintaxa „property-element”. Cu această sintaxă, se pot adăuga elemente copil cu numele în forma Părinte.NumeProprietate. De exemplu, dacă avem nevoie să setăm fundalul unui element de tip Grid și nu vrem să fie o culoare simplă (care ar fi fost ușor de setat printr-o proprietate simplă), putem adăuga un tag de tipul Grid.Background după cum urmează:

<Grid Width="360" Height="360" x:Name="grid1" >

<Grid.Background>

</Grid.Background>

</Grid>

Un detaliu important este punctul (.), care deosebește proprietățile de alte tipuri de elemente încuibărite.

Proprietăți atașate (Attached Properties)

Împreună cu proprietățile ordinare, XAML include și conceptul de proprietăți atașate, proprietăți care pot fi aplicate unor elemente diferite, care sunt definite într-o altă clasă. În Silverlight, ele sunt folosite adeseori pentru controlul de layout. Fiecare element are propriul set de proprietăți, iar dacă îl plasăm în interiorul unui anumit container, acesta obține proprietăți adiționale, care depind de tipul container-ului. Dacă, spre exemplu, plasăm o casetă de text (TextBox) pe un container de tip Grid, dorim să putem specifica poziția acestui element (linia și coloana în Grid). Acest lucru se realizează cu ajutorul proprietăților atașate, care au tot timpul un nume format din doi termeni: TipulDefinit.NumeProprietate, fapt care ajută parser-ul XAML să distingă o proprietate normală, obișnuită de una atașată.

<TextBox x:Name="text1" Grid.Row="0"></TextBox>

Proprietățile atașate sunt parsate de către parser-ul XAML în apeluri de funcții de forma TipulDefinit.SetNumeProprietate(). În exemplul de mai sus tipul definit este reprezentat de Grid, proprietatea este Row (setăm rândul în Grid), iar apelul parsat va fi de forma: Grid.SetRow(). Atunci când se apelează această metodă, parser-ul transmite doi parametri: obiectul care este modificat și valoarea proprietății specificate. În exemplul de mai sus, parser-ul XAML execută codul:

Grid.SetRow(text1,0);

Routed Events

Evenimentele sunt mesaje trimise de un obiect (un element Silverlight) pentru a semnala codului că se întâmplă ceva important. Windows Presentation Foundation a îmbunătățit modelul existent de evenimente din .NET cu un concept nou de „event routing”, care permite unui eveniment să provină dintr-un element, dar să fie apelat de altul. De exemplu, acest nou concept permite unui click, care începe într-un element de tip formă (shape) să continue la container-ul formei, apoi la pagina conținătoare, înainte să fie tratat de cod.

Silverlight împrumută o parte din modelul de evenimente al Windows Presentation Foundation (WPF), dar într-o formă mult simplificată. În timp ce WPF-ul suportă mai multe tipuri de „Routed Events”, Silverlight permite doar un singur tip și anume așa numitele „Bubbled Events”, care se deplasează doar în sus pe ierarhia de conținut, de la elemente încuibărite spre container-ele lor. Aceste evenimente nu se folosesc pentru elemente de nivel înalt, ci doar pentru câteva din elementele de nivel scăzut (pentru unele evenimente de citire de la tastatură și evenimente de mouse).

Figura 1.8. Event bubbling

Evenimente Core Elements

Evenimentele moștenesc setul lor de bază de evenimente de la două clase: UIElement și FrameworkElement.

Figura 1.9. Ierarhia elementelor Silverlight

Clasa UIElement definește cele mai importante evenimente pentru a trata input-ul utilizatorului:

KeyDown – se întâmplă atunci când o tastă este apăsată.

KeyUp –se întâmplă atunci când o tastă apăsată este eliberată.

TextInput – se întâmplă când elementul primește un caracter (de obicei dat de la tastatură).

GotFocus – se întâmplă când focusul se schimbă pe elementul curent (când utilizatorul dă click). Elementul care deține focus-ul este elementul care va primi primul un eveniment de la tastatură.

LostFocus – se întâmplă când obiectul curent pierde focus-ul.

MouseLeftButtonDown – se întâmplă atunci când butonul din stânga al mouse-ului este apăsat, în timp ce mouse-ul se află poziționat asupra unui element.

MouseLeftButtonUp – se întâmplă atunci când butonul din stânga al mouse-ului este eliberat.

MouseRightButtonDown – se întâmplă atunci când butonul din dreapta al mouse-ului este apăsat, în timp ce mouse-ul este poziționat asupra unui element.

MouseRightButtonUp – se întâmplă atunci când butonul din dreapta al mouse-ului este eliberat.

MouseEnter – se întâmplă atunci când cursorul mouse-ului se mișcă pentru prima dată pe un element.

MouseLeave – se întâmplă atunci când cursorul mouse-ului se mută de pe un anumit element în altă parte.

MouseMove – se întâmplă atunci când cursorul mouse-ului se mișcă în timp ce se află pe un anumit element.

MouseWheel – se întâmplă atunci când utilizatorul învârte scroll-ul mouse-ului în timp ce se află poziționat pe un element.

DragEnter – se întâmplă atunci când utilizatorul trage cu mouse-ul pentru prima dată un anumit fișier asupra unui element.

DragLeave – se întâmplă atunci când utilizatorul trage cu mouse-ul un anumit fișier de pe un anumit element.

DragOver – se întâmplă (în mod repetat) atunci când utilizatorul mișcă mouse-ul asupra unui element, în timp ce trage cu mouse-ul un anumit fișier pe acel element.

Drop – se întâmplă atunci când utilizatorul lasă (dă drumul) un fișier selectat pe un element.

LostMouseCapture – se întâmplă atunci când un element pierde captura mouse-ului (Mouse Capture – este o tehnică prin care un element primește evenimente de mouse chiar și atunci când cursorul se mută în altă parte și nu se mai află pe suprafața acestuia)

Clasa FrameworkElement mai adaugă unele evenimente modelului din Silverlight:

Loaded – se întâmplă după ce un element a fost creat și adăugat arborelui de obiecte.

SizeChanged – se întâmplă după ce dimensiunea unui element se schimbă.

LayoutUpdated – se întâmplă după ce layout-ul din interiorul unui element se schimbă.

BindingValidationError – se întâmplă în cazul în care un obiect de date relaționat aruncă o excepție atunci când utilizatorul încearcă să schimbe o proprietate.

Data Binding în Silverlight

Data binding este un proces care comunică Silverlight-ului să extragă o valoare a unei proprietăți dintr-un obiect sursă și să o folosească pentru a seta o proprietate într-un obiect destinație. Elementul sursă poate reprezenta orice, de la un element obișnuit Silverlight până la obiecte customizate. Obiectul destinație trebuie să fie o instanță a unei clase care derivă din clasa DependencyObject.

De obicei, target-ul unui data binding este un element, având în vedere că scopul acestui binding este afișarea unor informații pe interfață. Totuși, data binding-ul se poate folosi și pentru a extrage informații dintr-un obiect sursă, pentru a-l insera într-un obiect de tip brush sau pentru a efectua unele transformări.

Pentru a lucra cu caracteristicile data binding-ului, se creează așa numitele Data Objects, pachete de informații relaționate, care reprezintă de fapt orice clasă care conține proprietăți publice. Aceste clase pot conține și câmpuri sau proprietăți private, dar din acestea nu se pot extrage informații pentru a le lega de alte obiecte (prin data binding).

Pentru a folosi data binding, trebuie setată proprietatea țintă, utilizând o expresie de tip binding. O expresie de tip binding este o expresie markup, delimitată prin acolade, care începe tot timpul cu cuvântul „Binding”. Cea mai simplă construcție în care putem folosi o astfel de expresie este:

<TextBlock Text="{Binding NumeProprietate}"></TextBlock>

Figura 1.10. Data Binding la un TextBox

În expresia de binding se specifică numele proprietății sursă, dar nu se indică și obiectul sursă. Se poate seta sursa obiectului în două moduri: unul prin care setăm proprietatea DataContext a unui element și altul prin setarea proprietății Source a binding-ului.

Microsoft Expression Blend

Microsoft Blend pentru Visual Studio este un tool pentru design-ul de interfețe, dezvoltat și vândut de Microsoft, pentru crearea de interfețe grafice atât pentru aplicații Web cât și pentru aplicații Desktop. Numele „Blend” reiese tocmai din acest fapt, întrucât încorporează ambele tipuri de aplicații într-o singură interfață care poate fi proiectată cu acest instrument. Această aplicație este folosită pentru a schița și crea interfețe XAML, ea fiind construită și optimizată în mod special pentru Silverlight și Winows Presentation Foundation. În Expression Blend se poate schița aplicația în mod vizual, se pot desena forme, controale și mai apoi oferă posibilitatea să li se modifice aspectul și comportamentul. Expression Blend suportă importul de imagini, video și sunete.

Microsoft consolidează design-ul și ofertele pentru dezvoltare, pentru a oferi o soluție unificată, care aduce împreună cele mai bune aspecte din programarea Web și pattern-urile moderne de dezvoltare.

Unele scenarii în care ar fi util de folosit Expression Blend sunt:

Modelarea lumii reale: Se pot customiza efecte vizuale și interacțiuni pentru a face unele controale să arate și să se comporte precum corespondenții lor din viața reală. Această tehnică este cel mai corect folosită atunci când utilizatorii sunt familiarizați cu obiectele reale.

Vizualul este mai bun decât explicatul: Se pot folosi animații și tranziții pentru a arăta relații, cauze și efecte. Această tehnică este cel mai bine folosită atunci când oferim o informație, care în alte cazuri ar trebui scrisă pentru a putea fi înțeleasă.

Folosirea unei mapări naturale: Maparea naturală este o relație clară între ce vrea utilizatorul să facă și cum vrea să o facă.

Îmbunătățirea răspunsului: Se pot customiza controale vizuale și animații pentru a oferi feedback atunci când utilizatorul face ceva corect sau incorect sau pentru a arăta progresul.

Focus: Se pot folosi elemente vizuale de layout pentru a accentua elemente de pe ecran care sunt importante pentru o anumită sarcină, respectiv pentru a le ascunde pe cele secundare.

Servicii WCF pentru RIA (Rich Internet Applications)

Serviciile WCF (Windows Communication Foundation) reprezintă un framework pentru crearea de aplicații orientate spre servicii (Service-oriented). Acest framework simplifică dezvoltarea de aplicații pe mai multe niveluri (n-tier solutions) pentru că oferă instrumente, componente de framework și servicii astfel încât logica aplicației de pe server să fie disponibilă serviciilor RIA, fără a se duplica logica programării aplicației.

Figura 1.11. Aplicație pe n-nivele

În figura 1.11. este ilustrată o versiune simplificată a unei aplicații pe mai multe nivele, în care se poate vedea ca serviciile RIA se focusează pe partea dintre nivelul de prezentare și nivelul de acces la date.

Aceste servicii sunt baza pentru crearea de servicii Web într-o aplicație Silverlight, pentru că acesta este un mod foarte simplu de comunicare, atunci când programatorul are controlul asupra datelor și asupra server-ului care ține datele.

Un scenariu tipic în care se folosesc servicii este următorul:

Serverul web găzduiește o bază de date

Baza de date este împachetată de cel puțin un domain service, care reprezintă un fel special de servicii Web. Pentru a face operații pe baza de date, clientul apelează metode din domain service. În general aceste metode folosesc LINQ, pentru a permite interogări cât mai naturale și flexibile.

Domain service-ul folosește o entitate pentru a reprezenta fiecare obiect. Acesta se ocupă cu inserarea, actualizarea și ștergerea entităților de date din baza de date.

Avantajele acestui model de servicii WCF RIA sunt multiple:

Ele reprezintă un mod ușor pentru a genera cod de acces la date: programatorii care folosesc servicii WCF RIA le combină cu Entity Framework pentru a le genera automat clasele de date și serviciile de domeniu.

Serviciile oferă un mod mai simplu de a împărtăși logica de business: Clasele generate cu serviciile WCF RIA oferă un loc natural pentru a scrie logica aplicației, iar acest cod va fi pus în legătură cu elementele și controalele din Silverlight aproape fără efort.

Ele oferă suport LINQ: Chiar dacă LINQ se poate folosi și atunci când interogăm servicii Web obișnuite, WCF RIA permite scrierea de expresii LINQ pe partea de client (în aplicația proprie Silverlight) și executarea acestora pe server. Rezultatul este acela că domain service-ul va avea un set de metode mai mici și concise, care oferă clientului o flexibilitatea mare de interogare a bazei de date.

Extensii ASP.NET: servicii WCF RIA includ servicii Web încorporate care oferă mai multă ușurință în sistemul de autentificare și autorizare al ASP.NET. Acest lucru face mai ușoară folosirea modelului de securitate din ASP.NET pentru a controla o aplicație Silverlight.

Figura 1.12. Servicii WCF RIA

Capitolul 2. Prezentarea aplicației

Pagina de start

Pagina de start este pagina care apare atunci când se pornește aplicația și în același timp este cea care face trimiterea către pagina de joc.

Ea conține un tabel cu explicații în legătură cu modul de joc pentru cele două tipuri de puzzle-uri. Sunt explicate ideile și ceea ce trebuie făcut pentru a ajunge la soluție și a termina jocul cu succes.

Pentru implementare s-a folosit XAML pentru partea de interfață: este vorba de un container de layout de tip Grid cu trei coloane. Prima coloană este „Joc”, care specifică numele (tipul) jocului de puzzle, a doua coloană este creată doar pentru a evidenția mai bine despărțirea coloanelor, este vorba despre bara orizontală de culoare gradientă de la alb la verde. A treia coloană, „Cum se joacă?” reprezintă descrierea jocului și modul de joc.

<Grid x:Name="LayoutRoot" HorizontalAlignment="Center" VerticalAlignment="Stretch">

<Grid.RowDefinitions>

<RowDefinition />

<RowDefinition/>

<RowDefinition />

<RowDefinition />

<RowDefinition />

<RowDefinition />

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<ColumnDefinition Width="Auto"/>

<ColumnDefinition Width="Auto"/>

<ColumnDefinition Width="Auto"/>

</Grid.ColumnDefinitions>

<TextBlock FontSize="40" FontFamily="Arial Rounded MT Bold" Grid.Row="0" Grid.Column="0" Text="Joc"/>

<TextBlock FontSize="40" FontFamily="Arial Rounded MT Bold" Grid.Row="0" Grid.Column="2" Text="Cum se joaca?"/>

<TextBlock Grid.Row="2" Grid.RowSpan="3" Grid.Column="0" Text="3×3 Sliding Puzzle" FontSize="30" FontFamily="Arial Rounded MT Bold"/>

<TextBlock FontSize="20" FontFamily="Arial Rounded MT Bold" Grid.Row="1" Grid.Column="2" Text="Rearanjati piesele amestecate pentru a reface poza…"/>

<TextBlock Grid.Row="4" Grid.Column="0" Grid.RowSpan="2" Text="4×4 Rotating Puzzle" VerticalAlignment="Center" FontSize="30" FontFamily="Arial Rounded MT Bold"/>

<TextBlock FontSize="20" FontFamily="Arial Rounded MT Bold" Grid.Row="4" Grid.Column="2" Text="Refaceti poza initiala prin rotiri succesive ale partilor… "/>

</Grid>

Figura 2.1. Pagina de start a aplicației

La apăsarea butonului „Începe jocul”, se va face trimiterea către pagina efectivă de joc unde utilizatorul poate începe puzzle-ul în orice moment.

Figura 2.2. Pagina de joc a aplicației

Alegerea imaginilor

Alegerea unei imagini pentru a începe jocul se poate face în două moduri: utilizatorul poate să încarce o imagine proprie, de pe calculator sau poate să aleagă o imagine predefinită din lista care apare în dreapta paginii.

Alegerea unei imagini proprii

Atunci când utilizatorul vrea să încarce o imagine proprie, el va merge cu mouse-ul deasupra blocului de text „Imagini proprii” și, astfel va apărea un buton care va permite alegerea imaginii.

Figura 2.3. Blocul de text „Imagini proprii”

Figura 2.4. Butonul pentru a alege o imagine proprie

La apăsarea butonul din imagine, se va deschide o casetă de dialog, pentru a permite utilizatorului să aleagă o poză proprie din calculator și astfel să înceapă jocul de puzzle.

Caseta de dialog este creată printr-un obiect de tipul OpenFileDialog:

OpenFileDialog openImage = new OpenFileDialog();

Este vorba de o clasă predefinită a platformei .NET cu ajutorul căreia se pot selecta și deschide fișiere din calculator, pentru a putea fi procesate și folosite în diverse moduri.

După instanțiere i se pot adăuga filtre pentru a restrânge lista de fișiere afișate, la un anumit format care ne interesează în această situație.

openImage.Filter = "Image files (*.jpg, *.jpeg, *.jpe, *.jfif, *.png) | *.jpg; *.jpeg; *.jpe; *.jfif; *.png";

bool? IsSelected = openImage.ShowDialog();

try

{

if (IsSelected == true)

{

bitImage.SetSource(openImage.File.OpenRead());

(…)

}

}

După deschidere, se verifică prin variabila booleană IsSelected dacă s-a ales vreun fișier, în acest caz o imagine cu una din extensiile specificate la filtru, și dacă da, se salvează sursa imaginii în vederea folosirii ei mai departe în aplicație.

Figura 2.5. Caseta de dialog pentru alegerea imaginii

La selectarea unei imagini și apoi apăsarea butonul „Open”, imaginea va fi încărcată pentru a începe jocul. La încărcarea cu succes a imaginii va fi afișat un mesaj corespunzător.

Figura 2.6. Încărcarea imaginii

Alegerea unei imagini predefinite

Alegerea unei imagini predefinite se face din lista de imagini care apare în partea stângă a paginii atunci când utilizatorul merge cu mouse-ul deasupra blocului de text „Imagini predefinite”.

Figura 2.7. Blocul de text „Imagini predefinite”

Figura 2.8. Lista de imagini predefinite

La selectarea unei imagini din listă, aceasta va apărea în dreapta listei împreună cu un mesaj de informare în legătură cu imaginea aleasă.

Figura 2.9. Alegerea unei imagini predefinite

Pentru lista de imagini predefinite s-a creat o clasă numită DefaultImage în fișierul DefaultImages.cs, care are ca și date membru două string-uri reprezentând numele imaginii și sursa acesteia.

Astfel după crearea listei de imagini predefinite prin funcția GetImages din clasa DefaultImage se poate face binding pe componenta ListBox cu numele DefaultImageList definită în XAML.

List<DefaultImage> defaultImage= DefaultImage.GetImages();

DefaultImageList.ItemsSource = defaultImages;

În XAML este definită lista și apoi se definește tiparul pentru un element al listei care va conține într-un container de layout de tip StackPanel cu orientare orizontală o imagine și un bloc de text cu numele acesteia.

<ListBox HorizontalAlignment="Stretch" SelectionChanged="selectImage" Width="250" Height="430" x:Name="DefaultImageList">

<ListBox.ItemTemplate>

<DataTemplate>

<StackPanel Orientation="Horizontal">

<TextBlock Width="130" FontFamily="Century Gothic" FontSize="20" Height="50" Text="{Binding ImageName}"/>

<Image x:Name="defaultImage" Width="80" Height="80" Source="{Binding SourceString}"/>

</StackPanel>

</DataTemplate>

</ListBox.ItemTemplate>

</ListBox>

3×3 Sliding Puzzle

Ideea jocului de puzzle 3×3 este un simplă: după alegerea imaginii și apăsarea butonului de start „Joacă 3×3”, imaginea aleasă va fi împărțită în 9 bucăți, care vor fi aranjate aleatoriu pe matricea de joc. Piesa goală va fi tot timpul pusă în colțul din dreapta, jos. Pentru rezolvarea puzzle-ului este necesară rearanjarea pieselor amestecate pentru a reface poza inițială, prin interschimbări succesive între piesa goală și piesele din vecinătatea acesteia.

Figura 2.10. Startul jocului 3×3

În funcția evenimentului de click a butonului „Joacă 3×3”, se creează tabla de joc de dimensiune trei , se pornește cronometrul care este doar în scop orientativ și se aranjează piesele de joc, astfel încât configurația generată să fie una solubilă.

private void Start3x3(object sender, RoutedEventArgs e)

{

dimension = 3;

createGrid();

gameTimer.Start();

shufflePieces(3);

(…)

}

În funcția shufflePieces se amestecă și se aranjează piesele de imagini pe tabla de joc în mod aleatoriu cu condiția ca puzzle-ul generat să fie solubil.

void shufflePieces(int dimension)

{

blankLine = dimension – 1;

blankColumn = dimension – 1;

piecesNumber[dimension * dimension – 1] = -1;

do

{

Image[,] randomPieces = imageArray(dimension);

photoGrid.Children.Clear();

int posLine = randomPosition.Next(0, dimension);

int posColumn = randomPosition.Next(0, dimension);

bool[,] testMatrix = new bool[dimension, dimension];

int nr = 0;

blankButton = new Button();

blankButton.SetValue(Grid.RowProperty, dimension – 1);

blankButton.SetValue(Grid.ColumnProperty, dimension – 1);

photoGrid.Children.Add(blankButton);

testMatrix[dimension – 1, dimension – 1] = true;

nr++;

for (int i = 0; i < dimension; i++)

{

for (int j = 0; j < dimension; j++)

{

while (testMatrix[posLine, posColumn] == true && nr != dimension * dimension)

{

posLine = randomPosition.Next(0, dimension);

posColumn = randomPosition.Next(0, dimension);

}

if (testMatrix[posLine, posColumn] == false)

{

Button button = new Button();

button.BorderThickness = new Thickness(3);

button.Click += new RoutedEventHandler(SlideEvent);

button.Content = randomPieces[i, j];

button.SetValue(Grid.RowProperty, posLine);

button.SetValue(Grid.ColumnProperty, posColumn);

testMatrix[posLine, posColumn] = true;

piecesNumber[posLine * dimension + posColumn] = i * dimension + j + 1;

photoGrid.Children.Add(button);

nr++;

}

}

}

} while (countInversions(piecesNumber) % 2 != 0);

}

Matricea piecesNumber este folosită pentru a reține poziția pieselor de imagini, dar ca și cifre de la 1 la 8 și spațiul liber -1. Ea va fi utilizată la algoritmul A* pentru rezolvarea automată a puzzle-ului.

Solvabilitatea 8-puzzle

O configurație inițială a acestui puzzle este solubilă, dacă prin mutări succesive și valide se poate reface imaginea inițială.

Solvabilitatea pentru 8-puzzle se determină cu ajutorul formulei următoare: dacă lățimea puzzle-ului este un număr impar, în acest caz 3, atunci acesta va fi solubil în cazul în care numărul inversiunilor este un număr par.

O inversiune înseamnă plasamentul unei piese cu un număr mai mare în fața unei piese cu un număr mai mic. În exemplul de mai jos se observă că

1 nu ne dă nicio inversiune

3 ne dă o singură inversiune

4 ne dă o singură inversiune etc

Astfel, dacă calculăm suma inversiunilor și aceasta va fi un număr par, înseamnă că jocul de puzzle are soluție.

Această formulă este una validă și adevărată tot timpul pentru că toate mutările valide pe care le poate face utilizatorul păstrează polaritatea numărului inversiunilor.

Pentru a genera doar configurațiile inițiale de la care se poate ajunge la soluție, s-a folosit în implementare o funcție care verifică numărul inversiunilor pentru o anumită configurație generată aleatoriu. Dacă numărul inversiunilor nu este un număr par (caz în care configurația generată nu ar fi solubilă), va fi generată altă configurație. Astfel se controlează doar afișarea unor configurații solubile pentru utilizator.

public static int countInversions(int[] p)

{

int inversions = 0;

for (int i = 0; i < p.Length – 1; i++)

{

for (int j = i + 1; j < p.Length; j++)

if (p[i] > p[j]) inversions++;

if (p[i] == -1 && i % 2 == 1) inversions++;

}

return inversions

}

Rezolvare automată

Algoritmul A* pentru 8-puzzle

Algoritmul A* este unul dintre cei mai cunoscuți algoritmi de căutare euristică. Astfel de algoritmi sunt folosiți pentru probleme pentru care nu există un model matematic de rezolvare sau în cazul în care există, acesta este prea complicat pentru a fi implementat. Algoritmii euristici reprezintă o tehnică pentru rezolvarea unei probleme mai rapid, atunci când o metodă clasică este prea înceată din punct de vedere al timpului de execuție sau pentru găsirea unei soluții aproximative, atunci când metodele clasice de rezolvare nu pot să ofere nicio soluție exactă. Obiectivul euristicii este să producă o soluție într-un interval de timp suficient de bun pentru rezolvarea problemei cerute. Soluția găsită poate să nu fie cea mai bună dintre toate soluțiile problemei sau poate să aproximeze o soluție exactă, care va fi totuși acceptată pentru că timpul de găsire al soluției este unul mic. Funcțiile euristice sunt folosite adeseori împreună cu algoritmi de optimizare pentru a le îmbunătăți eficiența, iar în decizia folosirii acestora se pot face unele compromisuri privind mai multe criterii care depind de fiecare problemă în parte: optimalitatea, caracterul complet, acuratețea și precizia, timpul de execuție.

Prezentare generală

Pentru rezolvarea unei probleme cu algoritmi euristici de căutare este necesară definirea exactă a problemei prin definirea mai multor caracteristici și anume:

Starea inițială reprezintă configurația inițială de la care se începe pentru a ajunge la soluție.

Acțiunile posibile sau regulile sunt mutări sau schimbări posibile de făcut la un moment dat

Testarea stării finale reprezintă o funcție care verifică dacă s-a ajuns, prin acțiuni valide la configurația finală cerută de problemă.

Funcția de cost atribuie un cost fiecărei mutări valide în procesul de explorare.

Dacă algoritmul găsește o soluție, el va fi numit algoritm complet, iar dacă găsește și drumul cu cost minim către starea finală, el va fi numit algoritm optim. În cadrul explorării stărilor, se generează un arbore care va avea drept rădăcină, starea inițială. Fiecare nod al arborelui va conține mai multe informații cum ar fi: starea, părintele, costul drumului până acolo. Pentru fiecare nod se definește și o funcție f, care reprezintă cât de aproape este un nod în perspectiva ajungerii la starea finală. De asemenea se utilizează o informație suplimentară, așa numita funcție euristică h și reprezintă drumul estimat de la nod la starea finală, deci la soluție. Aceste funcții pot fi definite în mai multe feluri, dar există o singură regulă: ca h(nod) să fie 0 atunci când s-a ajuns la starea finală.

Admisibilitatea euristicii folosite

Pentru ca un algoritm euristic să fie considerat admisibil pentru problema de căutare, costul estimat trebuie să fie întotdeauna mai mic sau egal cu costul real pentru a ajunge la starea de final cerută de algoritm.

(2.1)

pentru fiecare nod din arborele creat, unde reprezintă costul estimat de la nodul curent la soluție, reprezintă costul real pentru a ajunge la soluție.

Algoritmul de căutare A* folosește euristica admisibilă pentru a găsi un drum optimal estimat de la nodul curent către nodul țintă. În concluzie, funcția f, funcția de evaluare este descrisă astfel:

, (2.2)

unde g(n) reprezintă costul de la nodul de start (configurația inițială)

h(n) reprezintă costul estimat de la nodul curent la soluție

Comportamentul lui A* în rezolvarea a 8-puzzle

Pentru a începe soluționarea problemei, aceasta trebuie abstractizată și reprezentată într-un mod înțeles de calculator. În cazul 8-puzzle-ului se definesc următoarele caracteristici specifice pentru a putea începe rezolvarea problemei prin algoritmul A*:

Starea inițială este reprezentată de un nod cu cifrele de la 1 la 8 , spațiul gol fiind reprezentat de -1 și aflându-se în colțul din dreapta, jos. Acest nod este reprezentat în limbaj de programare printr-o matrice de dimensiune 3X3. Un exemplu de stare inițială ar putea fi:

Pentru a începe exploatarea opțiunilor, este necesară și definirea acțiunilor posibile de făcut la un moment dat. În cazul acestui puzzle, se pot interschimba doar căsuțele din imediata apropiere a căsuței libere (cea care conține -1) cu aceasta, adică în exemplul de mai sus există două mutări posibile (maximul este patru, în funcție de locația căsuței libere). În cazul configurației inițiale date ca exemplu la punctul anterior, acțiunile sau mutările posibile de făcut, reprezentate și grafic, sunt următoarele:

3 mutări posibile (…) 3 mutări posibile(…)

Spațiul de stări posibile

Starea finală a problemei este un nod care are cifrele de la 1 la 8 în ordine, începând din stânga sus și căsuța liberă pe ultima poziție, în dreapta jos.

Pseudocod. Principiu de funcționare

Figura 2.11. Algoritmul A*- Pseudocod (Sursa http://en.wikipedia.org/wiki/A*_search_algorithm)

La fel ca alți algoritmi de căutare informată, A* caută mai întâi rutele care par să fie cele mai probabile să conducă la soluție. Ceea ce separă acest algoritm de alți algoritmi (care folosesc tehnica Greedy de exemplu) este faptul că se ia în considerare și distanța deja parcursă: g(n) reprezintă distanța de la punctul inițial și nu doar de la nodul anterior. Începând de la configurația inițială, se rețin nodurile de parcurs într-o coadă de priorități (open set). Cu cât este mai mică funcția f pentru un nod n, cu atât mai mare este prioritatea acestuia.

La fiecare pas, nodul cu scorul f cel mai mic este scos din coadă, valorile f și g ale vecinilor lui sunt actualizate corespunzător, iar apoi acești vecini vor fi adăugați în coadă. Algoritmul continuă până când se ajunge la starea finală sau când coada va fi goală. La sfârșit scorul f al nodului țintă este lungimea celui mai scurt drum, iar scorul h va fi 0.

Se folosește și o coadă (closed set) pentru a reține nodurile deja traversate, pentru a face căutarea mai eficientă.

Pentru implementarea algoritmului în C# s-a creat un fișier ClassAStarAlgorithm.cs; pentru implementarea unei configurații, unui nod s-a folosit clasa Node definită astfel:

class Node : IComparable

{

public int[] mNodes;

public int blankIndex;

private string mStateCode;

private int f_score;

private int h_score;

private int g_score;

private Node parent;

}

Clasa Node are ca date membru un vector, reprezentând configurația nodului (ordinea cifrelor de la 1 la 8 și spațiu liber, -1), mNodes; indexul spațiului liber, reprezentând deci poziția căsuței care conține -1 în vectorul de joc, blankIndex; un string folosit pentru a compara două stări între ele, mStateCode; scorurile f, g și h, reprezentând costurile explicate anterior; o referință către nodul părinte, reprezentând predecesorul nodului curent, parent.

Concluzie

„Ca o ultimă observație asupra algoritmului: nici un alt algoritm optimal nu garantează să extindă mai puține noduri decât A* în condițiile aceleiași euristici, conform Dechter și Pearl (1985). O demonstrație a optimalității și completitudinii algoritmului A* o găsiți în Dechter și Pearl (1985).”

Astfel se poate spune că algoritmul A* găsește numărul minim de mutări pentru a rezolva o configurație de 8-puzzle solubilă, într-un timp scurt și cu rezultate optimale.

Clasament

Atunci când utilizatorul reușește să refacă imaginea inițială din părțile de imagine amestecate, el va avea ocazia să înregistreze scorul obținut și să vadă clasamentul precum și locul pe care se află acesta. Scorul este calculat pentru fiecare utilizator în parte și constă în diferența dintre numărul ideal de mutări și numărul mutărilor făcute de utilizator pentru a câștiga jocul. Astfel, scorul ideal este 0 și, cu cât utilizatorul se îndepărtează mai mult de numărul ideal de mutări, cu atât mai jos va fi locul său în clasament.

Figura 2.12. Puzzle 3×3

În această imagine s-a ales o imagine predefinită, s-a apăsat butonul „Joacă 3×3” și astfel totul este pregătit și utilizatorul poate să înceapă să mute piesele.

De la configurația de mai sus, s-a ajuns prin mutări succesive la următoarea configurație, care este foarte aproape de configurația câștigătoare.

Figura 2.14. Puzzle 3×3

Astfel următoarea mutare va fi a părții de imagine din dreapta jos cu căsuța liberă pentru a reface imaginea inițială.

La terminarea jocului apare o casetă de dialog care permite utilizatorului să înregistreze scorul în baza de date. Acesta are posibilitatea să își scrie numele sau să treacă o poreclă cu care mai apoi să se identifice în clasamentul afișat. În această casetă apar atât numărul de mutări cât și scorul obținut.

Figura 2.15. Caseta de dialog la terminarea jocului 3×3

Funcția pentru evenimentul de click al butonului „Înregistrează scor”:

private void OKButton_Click(object sender, RoutedEventArgs e)

{

Mutari = int.Parse(mutari.Text);

Scor = int.Parse(scor.Text);

Nume = nickname.Text;

(…)

webService.InsertDataCompleted += new EventHandler<ServiceReference1.InsertDataCompletedEventArgs>(webService_InsertDataCompleted);

webService.InsertDataAsync(Mutari, Scor, Nume);

(…)

message.Text = "Joc inregistrat cu succes!";

}

La apăsarea butonului „Înregistrează scor” se introduce scorul împreună cu numele utilizatorului și numărul de mutări în baza de date și se afișează un mesaj corespunzător. La apăsarea butonului „Afișează clasament” se va afișa clasamentul în partea dreaptă a paginii.

Figura 2.16. Clasament pentru jocul 3×3

La apăsarea butonului „Rezolvare automată”, utilizatorul nu mai are posibilitatea înregistrării scorului, ci doar a consultării clasamentului.

Figura 2.17. Caseta de dialog la rezolvarea automată

Clasamentul va fi afișat și în acest caz, la apăsarea butonului „Ce au făcut ceilalți jucători”.

4×4 Rotating Puzzle

Ideea jocului de puzzle 4×4 este aceea că imaginea inițială trebuie refăcută prin rotirea pieselor de imagine de pe tabla de joc, într-un timp cât mai scurt. Tabla de joc va fi împărțită în 16 piese de imagini fiecare rotite de un număr de ori, calculat aleatoriu.

Figura 2.18. Startul jocului 4×4

În funcția evenimentului de click a butonului „Joacă 4×4”, se creează tabla de joc de dimensiune patru , se pornește cronometrul și se aranjează piesele de joc rotite aleatoriu.

private void Start4x4(object sender, RoutedEventArgs e)

{

initializeBoard4x4();

dimension = 4;

gameTimer.Start();

createImageArray();

(…)

}

În funcția createImageArray se ia matricea de poze rotite, reprezentată de rotatedPieces și le așază pe tabla de joc, reprezentată de grid-ul de dimensiuni 4×4, numit photoGrid.

void createImageArray()

{

createGrid();

photoGrid.Children.Clear();

Image[,] rotatedPieces = createRotatedPieces();

for (int i = 0; i < dimension; i++)

for (int j = 0; j < dimension; j++)

{

Button button = new Button();

button.Click += new RoutedEventHandler(RotateEvent);

button.SetValue(Grid.RowProperty, i);

button.SetValue(Grid.ColumnProperty, j);

button.Content = rotatedPieces[i, j];

photoGrid.Children.Add(button);

}

}

Clasament

Atunci când utilizatorul reușește să refacă imaginea inițială din părțile de imagine rotite, el va avea ocazia să înregistreze scorul obținut și să vadă clasamentul precum și locul pe care se află acesta. Utilizatorii sunt ordonați în clasament în funcție de timpul în care au terminat jocul de puzzle.

Astfel la terminarea jocului apare o casetă de dialog unde utilizatorul poate să își treacă numele, să își înregistreze scorul, reprezentat de timp, și apoi să vizualizeze clasamentul.

Figura 2.19. Caseta de dialog la terminarea jocului 4×4

La apăsarea butonului „Afișează clasament” se va afișa clasamentul în care utilizatorul va vedea ce loc ocupă și cum s-au descurcat și ceilalți jucători.

Figura 2.20. Clasament pentru jocul 4×4

Baza de date

Accesarea unor date aflate într-o bază de date în vederea afișării sau modificării lor, este un scenariu tipic și destul de des întâlnit în aplicațiile de acest gen. În Silverlight, accesul la o bază de date se face cu ajutorul serviciilor Web.

Astfel, această aplicație conține un serviciu Web cu numele „Service.csv” pentru lucrul și interacțiunea cu baza de date. În fișierul creat se va defini un contract care reprezintă operațiile și acțiunile care se doresc a fi făcute cu baza de date.

Operațiile definite în acest caz sunt operații de inserare și de vizualizare a intrărilor pentru fiecare din cele două tabele. Ele sunt definite ca funcții cărora li se setează atributul [OperationContract].

Cele două tabele din baza de date se mapează pe două clase, cu ajutorul lui Visual Studio: după ce s-a făcut conexiunea cu baza de date din Visual Studio, se pot alege simplu acele tabele din baza de date pe care se dorește să se facă maparea, după care Visual Studio creează automat pentru fiecare dintre ele, clase, care respectă tipul de date al câmpurilor, numele lor și tipul cheilor din tabele.

Un exemplu simplificat este această clasă în care s-au prezentat doar câmpurile mapate pe cele din baza de date.

public partial class SlidingPuzzle :

{

private int _Id;

private string _Nume;

private System.Nullable<int> _Scor;

private System.Nullable<int> _Mutari;

(…)

}

Figura 2.21. Baza de date adăugată în Visual Studio, în proiect

Din lista de tabele se aleg ambele tabele , pe rând pentru a fi mapate și a putea fi folosite în continuare.

Figura 2.22. Tabele mapate

Concluzii

Scopul acestei lucrări a fost de a crea jocuri antrenante pentru minte și atractive pentru o gama largă de persoane, cum de altfel au fost considerate de mult timp puzzle-urile. Am ales să fac această aplicație pentru mediul online pentru că în ziua de astăzi foarte multă lume are acces la internet, ceea ce face această aplicație ușor accesibilă și ușor de folosit. Jocul de puzzle 3×3 este un joc pe care mi-l amintesc din copilărie, când se putea juca pe o tablă fizică și nu în formă digitală, pe calculator cum sunt cele mai multe în ziua de azi. Ideea jocului de puzzle rotativ am descoperit-o de curând în cadrul unor alte jocuri de antrenat mintea, ca făcând parte din ele și reprezentând anumite niveluri de trecut.

Mediul de lucru Microsoft Visual Studio conține un set complet de instrumente de dezvoltare de aplicații pe diferite platforme cum ar fi Web sau Desktop și în diferite limbaje de programare. Ele au avantajul că beneficiază de caracteristicile platformei .NET, aceasta oferind acces la tehnologii cheie care ajută la simplificarea dezvoltării aplicațiilor.

Consider că alegerea acestui mediu de lucru, Visual Studio și realizarea acestei aplicații în Microsoft Silverlight a fost o alegere bună, întrucât aplicația finală este un complexă, în care am profitat de multe dintre avantajele oferite de Silverlight și în special de limbajul C#, în care a fost scris codul sursă al aplicației.

Un avantaj mare al lui Silverlight este că permite separarea părții de design, de interfață de partea de programare, folosind limbajul de marcare XAML pentru interfață și respectiv C# pentru partea de logică, de programare. Astfel se creează două părți aparent independente, care de fapt comunică între ele într-un mod simplu și logic, pentru a da funcționalitate design-ului creat.

Jocul de puzzle 3×3 a fost puțin mai complex de realizat decât cel de 4×4, pentru că la jocul 3×3 am combinat puzzle-ul cu inteligența artificială prin algoritmul pe care l-am folosit pentru rezolvarea automată, A*. Algoritmul a fost gândit pentru a lucra cu cifre, ca în cazul lui 8-puzzle clasic, iar apoi transpus în logica de joc cu imagini. Astfel, deși utilizatorul nu este cunoscător al acestui algoritm, am reușit să îl incorporez în ansamblul jocului ca să devină ceva atractiv pentru acesta și în același timp să adauge complexitate aplicației din punct de vedere al caracteristicilor pe care le oferă.

Ideea jocului 4×4 a venit pe parcurs, după ce am început să lucrez la această temă de licență și treptat am evoluat de un stadiu la altul. Cred că și acest al doilea joc se potrivește bine în contextul întregii teme și al subiectului pe care îl reprezintă și pot spune că și în cazul acestui joc am profitat de facilitățile oferite de Silverlight și .NET prin gândirea algoritmului din spate din punct de vedere al unui programator și apoi transpunând logica aceasta în jocul propriu-zis cu imagini.

Astfel, pot spune că am dus la bun sfârșit această lucrare de licență ajutându-mă de mediul de lucru Visual Studio, de tehnologia Microsoft Silverlight, de limbajele C# și XAML și de propria atracție pentru genul acesta de jocuri cum sunt puzzle-urile. Propriile idei și amintiri ale acestui gen de jocuri, care s-au schimbat și care au tot evoluat pe parcurs au dus această temă de la un subiect destul de abstract la început, la materializarea lui în această aplicație online pentru dezvoltare de puzzle-uri .

Bibliografie

Matthew MacDonald, Pro Silverlight 5 in C#, Apress, Fourth Edition.

Solubilitatea 8-puzzle, http://www.cs.bham.ac.uk/~mdr/teaching/modules04/java2/TilesSolvability.html, (data accesării: 20.04.2015)

Solubilitatea 8-puzzle, http://www.sitepoint.com/randomizing-sliding-puzzle-tiles/, (data accesării: 15.04.2015)

Algoritmul A*, http://www.policyalmanac.org/games/aStarTutorial.htm, (data accesării: 25.03.2015).

Algoritmul A*, http://www.dotnetperls.com/pathfinding, (data accesării: 30.03.2015)

Algoritmul A*, http://blogs.msdn.com/b/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx, (data accesării: 25.03.2015)

Algoritmul A*, http://en.wikipedia.org/wiki/A*_search_algorithm, (data accesării: 23.03.2015)

Algoritmul A*-cod open source, http://www.codeproject.com/Articles/616874/Puzzle-using-A-A-Star-Algorithm-Csharp, (data accesării: 30.03.2015)

Algoritmul A*, http://profs.info.uaic.ro/~alaiba/mw/index.php?title=Metode_informate_de_c%C4%83utare_folosite_%C3%AEn_implementarea_agen%C5%A3ilor_inteligen%C5%A3i, (data accesării: 30.03.2015)

Algoritmul A*, http://www.scritub.com/stiinta/informatica/Inteligenta-Artificiala-Struct21486.php, (data accesării: 30.03.2015)

8puzzle, http://www.8puzzle.com/8_puzzle_algorithm.html, (data accesării: 15.04.2015)

8puzzle, https://ece.uwaterloo.ca/~dwharder/aads/Algorithms/N_puzzles/, (data accesării: 10.04.2015)

Evoluția Silverlight, http://en.wikipedia.org/wiki/Microsoft_Silverlight, (data accesării: 01.03.2015)

Euristici admisibile, http://en.wikipedia.org/wiki/Admissible_heuristic, (data accesării: 20.04.2015)

Expression Blend, https://msdn.microsoft.com/en-us/library/cc296376.aspx, (data accesării: 05.03.2015)

Anexe

Baza de date PuzzlePhotos s-a creat în SQL Management Studio și conține două tabele: SlidingPuzzle și RotatingPuzzle.

Tabelul SlidingPuzzle, folosit pentru clasamentul puzzle-ului 3×3 are următoarea structură:

Tabelul RotatingPuzzle, folosit pentru clasamentul puzzle-ului 4×4 are următoarea structură:

Bibliografie

Matthew MacDonald, Pro Silverlight 5 in C#, Apress, Fourth Edition.

Solubilitatea 8-puzzle, http://www.cs.bham.ac.uk/~mdr/teaching/modules04/java2/TilesSolvability.html, (data accesării: 20.04.2015)

Solubilitatea 8-puzzle, http://www.sitepoint.com/randomizing-sliding-puzzle-tiles/, (data accesării: 15.04.2015)

Algoritmul A*, http://www.policyalmanac.org/games/aStarTutorial.htm, (data accesării: 25.03.2015).

Algoritmul A*, http://www.dotnetperls.com/pathfinding, (data accesării: 30.03.2015)

Algoritmul A*, http://blogs.msdn.com/b/ericlippert/archive/2007/10/02/path-finding-using-a-in-c-3-0.aspx, (data accesării: 25.03.2015)

Algoritmul A*, http://en.wikipedia.org/wiki/A*_search_algorithm, (data accesării: 23.03.2015)

Algoritmul A*-cod open source, http://www.codeproject.com/Articles/616874/Puzzle-using-A-A-Star-Algorithm-Csharp, (data accesării: 30.03.2015)

Algoritmul A*, http://profs.info.uaic.ro/~alaiba/mw/index.php?title=Metode_informate_de_c%C4%83utare_folosite_%C3%AEn_implementarea_agen%C5%A3ilor_inteligen%C5%A3i, (data accesării: 30.03.2015)

Algoritmul A*, http://www.scritub.com/stiinta/informatica/Inteligenta-Artificiala-Struct21486.php, (data accesării: 30.03.2015)

8puzzle, http://www.8puzzle.com/8_puzzle_algorithm.html, (data accesării: 15.04.2015)

8puzzle, https://ece.uwaterloo.ca/~dwharder/aads/Algorithms/N_puzzles/, (data accesării: 10.04.2015)

Evoluția Silverlight, http://en.wikipedia.org/wiki/Microsoft_Silverlight, (data accesării: 01.03.2015)

Euristici admisibile, http://en.wikipedia.org/wiki/Admissible_heuristic, (data accesării: 20.04.2015)

Expression Blend, https://msdn.microsoft.com/en-us/library/cc296376.aspx, (data accesării: 05.03.2015)

Anexe

Baza de date PuzzlePhotos s-a creat în SQL Management Studio și conține două tabele: SlidingPuzzle și RotatingPuzzle.

Tabelul SlidingPuzzle, folosit pentru clasamentul puzzle-ului 3×3 are următoarea structură:

Tabelul RotatingPuzzle, folosit pentru clasamentul puzzle-ului 4×4 are următoarea structură:

Similar Posts

  • Informatica Aplicata

    CUPRINS GENERAL Prefață 9 Capitolul 1 Generalități despre Informatică / Computer Science ITC, Sisteme de calcul și platforme software 11 Capitolul 2 Teoria erorilor și a incertitudinilor Calcule statistice și modele de aproximare 45 Capitolul 3 Modele de aproximare neliniare Calcule matematice și aplicații 109 Capitolul 4 Conceperea și elaborarea lucrărilor științifice, Editarea formulelor matematice…

  • Aplicatie Android Joc Mine Sweeper

    Cuprins: Sinteza lucrării I. Introducere II. Stadiul temei în bibliografie și realizări III. Proiectare și implementare III.1 Prezentare generală III.2 Modul classic III.2.1 Alegerea dificultății III.2.2 Inițializare parametri III.2.3 Definirea evenimentului de click și long-click III.2.4 Plasarea bombelor pe suprafața de joc III.2.5 Descoperirea suprafeței de joc III.2.6 Descoperirea sprafețelor de joc adiacente suprafeței 0…

  • Proceduri Computationale Si Structuri de Date

    Introducere Prezentarea temei Aflată la intersecția dintre mai multe discipline ( Cibernetică Economică, Informatică, Modelarea și Simularea Proceselor Economice ), tema aleasă reprezintă un mod de integrare și aplicare a cunoștințelor și rezultatelor din mai multe arii de specialitate, facilitând în același timp o interacțiune accesibilă oricărui tip de utilizator, atât pentru datele introduse în…

  • Retele Neuronale Art

    CUPRINS Introducere……………………………………………………………………………………………………iiiCapitolul 1: Arhitecturi neurale recurente……………………………………………………………..……..1 1.1. Arhitecturi neurale recurente unistrat……………………………………………………………………1 1.1.1. Memorii Hopfield – model asincron cu evoluție in timp discret………………………………………1 1.1.2. Memorii Little – model sincron cu evoluție in timp discret……………………………………………7 1.2 Arhitecturi neurale recurente cu doua straturi……………………………………………………….. 8 1.2.1. Memorii asociative bidirecționale……………….………………………………………………8 1.2.1.1. Noțiuni introductive……………………..………………………………………………8 1.2.1.2. Asociatorul linear………………………..……………………………………………10 1.2.1.3. Funcționarea memorii asociative…

  • Securitatea Datelor pe Internet

    CUPRINS INTRODUCERE………………………………………………..…… 2 Securitatea prin firewall………………………………………..…. 3 1. Conceptul de firewall……………………………………….. 3 2. Avantajele folosirii unui firewall ………………………….. 4 3. Dezavantajele folosirii unui firewall ………………………. 7 4. Componentele unui firewall ……………………………….. 9 4.1 Politica de control al accesului la servicii …..…. 9 4.2 Mecanismele avansate de autentificare ………… 11 4.3 Filtrarea pachetelor………………………………. 15 4.4 Sisteme…

  • Aplicatii Distribuite Aplicatie Avand Ca Scop Gestiunea Unor Conturi Bancare

    CUPRINS CAPITOLUL 1 Aplicatii distribuite 1.1 Introducere In ultimii ani, programarea distribuita apare tot mai des ca solutie la problemele din domeniul tehnologiei informatiei, probleme aparute o data cu dezvoltarea vertiginoasa a Internetului si in general a industriei calculatoarelor si a industriei informatiei. Programarea distribuita poate fi privita, intr-o forma simpla, ca impartirea unei aplicatii…