Prezentarea proiectului

1. Prezentarea algoritmului de rezolvare

      Vom da mai intai cateva definitii:
      Definitia 1. La un anumit pas al jocului numim punct folosit un punct care este capatul unui segment deja trasat.
      Definitia 2. La un anumit pas al jocului numim punct blocat un punct care nu mai poate fi unit cu nici un alt punct respectand regulile jocului.
      Definitia 3. La un anumit pas al jocului numim punct liber un punct pentru care mai exista cel putin un alt punct cu care poate fi unit respectand regulile jocului.
      Definitia 4. La un anumit pas al jocului numim zona o multime de puncte libere astfel incat orice punct din multime nu poate fi unit cu nici un alt punct care nu apartine multimii.
      Definitia 5. La un anumit pas al jocului numim jocul asociat unei zone jocul care porneste cu zona respectiva ca multime a punctelor. Acest joc se joaca numai in zona respectiva, tinand seama de constrangerile initiale ale zonei. Numim numar posibil de mutari un numar de mutari dupa care jocul asociat zonei se poate termina. In general, exista mai multe numere posibile de mutari. Multimea acestora o vom numi multime de numere posibile de mutari asociate zonei.
      Definitia 6. La un anumit pas al jocului numim grupaj nedecis o zona pentru care multimea de numere posibile de mutari asociate are doua elemente si acestea sunt 1 si 2. Practic, grupajul nedecis este acea zona care poate fi jucata intr-una sau doua mutari.
      Mai jos, avem 2 zone de cate 4 puncte fiecare. Prima reprezinta un grupaj nedecis, deoarece unind pe 1 cu 3 jocul s-a terminat intr-o singura mutare, iar unind pe 1 cu 2, mai este posibil sa se uneasca 3 cu 4, deci jocul se termina in 2 mutari.


      A doua nu reprezinta un grupaj nedecis, deoarece oricum am uni 2 puncte, mai este posbila inca o mutare, deci jocul se va termina in 2 mutari oricum. Aceasta zona este o zona mica.


      Grupajele nedecise au o mare importanta, deoarece jucatorul care ataca grupajul castiga jocul asociat grupajului respectiv. Grupajele nedecise trebuie sa aiba cel putin patru puncte; ne vom axa pe cele de patru sau de cinci puncte, deoarece acestea sunt mai usor de observat.
      Definitia 7. La un anumit pas al jocului numim zona mica o zona pentru care multimea de numere posibile de mutari asociate are un singur elemente.
      S-a ales aceasta denumire, deoarece zonele ce au doua sau trei puncte evident zone mici. Vom tine cont si de zonele mici formate din 4 sau 5 puncte.
      Definitia 8. La un anumit pas al jocului numim numar sigur de mutari suma numerelor posibile de mutari asociate fiecarei zone mici.
      Numarul sigur de mutari da in fond numarul minim cunoscut de mutari in care se va termina jocul de la pasul respectiv.

      Dam in continuare urmatoarea propozitie:
      Propozitia 1. Fie urmatoarea situatie la un anumit pas al jocului: toate zonele sunt grupaje nedecise sau zone mici; notam cu A jucatorul care este de mutat, cu B celalt jucator; notam ned numarul grupajelor nedecise si cu mut numarul sigur de mutari. Atunci:
      a) Daca ned este par si mut este par, exista o strategie castigatoare pentru jucatorul B.
      b) Pentru celelalte situatii exista o strategie castigatoare pentru jucatorul A.

      Demonstratie:

      Vom demonstra acest rezultat prin inductie dupa numarul grupajelor nedecise.
      Cazuri de baza: Pentru zero grupaje nedecise, jocul este deja hotarat, indiferent de mutarile celor 2 jucatori. In acest caz, exista numai zone mici, deci se cunoaste numarul de mutari in care se va termina jocul (care este egal in acest caz cu numarul sigur de mutari). Daca acest numar este impar, va castiga jucatorul care este de mutat (jucatorul A), invers va castiga jucatorul B.
      Pentru un singur grupaj nedecis, jucatorul A va avea o strategie de castig. Intr-adevar, dupa ce A muta (presupunand ca va rezolva grupajul nedecis), revenim in situatia cu zero grupaje nedecise, in care jocul este hotarat. Strategia lui A este sa rezolve grupajul astfel incat cand B vine la mutare, numarul de mutari in care se termina jocul (numarul sigur de mutari) sa fie par. Daca numarul sigur de mutari cand A este de mutat este par, atunci A va rezolva grupajul nedecis printr-o mutare; invers, il va rezolva prin 2 mutari.
      Ipoteza de inductie: Aratam ca P(2k) implica P(2k+1) si P(2k+2), adica presupunand propozitia adevarata pentru 2k grupaje nedecise, vom arata ca este adevarata pentru 2k+1 si pentru 2k+2 grupaje nedecise.
      Aratam P(2k) -> P(2k+1). Pentru 2k+1 grupaje nedecise, jucatorul A are o strategie castigatoare. Intr-adevar, A va rezolva un grupaj nedecis astfel incat cand B vine la mutare numarul sigur de mutari sa fie par. Cum numarul grupajelor nedecise va fi atunci 2k si P(2k) este adevarata, rezulta ca B va pierde, deci A are o strategie castigatoare.
      Aratam ca P(2k+2) este adevarata. Observam mai intai ca jucatorul A nu va rezolva nici un grupaj nedecis (deoarece vor ramane 2k+1 grupaje nedecise, P(2k+1) este adevarata, jucatorul B va fi la mutare si deci B va avea o strategie castigatoare), deci A va uni puncte numai din zonele mici. Daca nu exista zone mici, A pierde, B avand o strategie castigatoare. Presupunem ca exista zone mici. Prin mutarea lui A, numarul sigur de mutari s va micsora cu 1, numarul grupajelor nedecise va ramane neschimbat; deci B va fi fortat si el sa uneasca puncte dintr-o zona nedecisa. Situatia se continua pana cand nu vor mai fi zone mici, jucatorul ce trebuie sa mute in acest moment va fi fortat sa rezolve un grupaj nedecis, deci va pierde (deoarece celalt va fi la mutare intr-o situatie cu 2k+1 grupaje nedecise, deci va castiga). In concluzie, daca numarul sigur de mutari este par, A va fi jucatorul ce este fortat in cele din urma sa rezolve un grupaj nedecis si deci B va avea strategie castigatoare; daca numarul sigur de mutari este impar, B va fi jucatorul ce este fortat in cele din urma sa rezolve un grupaj nedecis si deci A va avea strategie castigatoare.
      Propozitia este demonstrata.

      Strategia de rezolvare pe care am adoptat-o se bazeaza pe impartirea punctelor in zone cat mai mici astfel incat sa ajungem la o situatie in care zonele sunt grupaje nedecise sau zone mici. Vom testa o zona pentru a stabili daca este zona mica sau grupaj nedecis numai daca zona are 4 sau 5 elemente (daca zona are 2 sau 3 puncte, este sigur zona mica; daca are 4 sau 5 puncte nu poate fi decat zona mica sau grupaj nedecis; daca are mai multe puncte poate sa nu fie nici zona mica, nici grupaj nedecis, iar stabilirea acestui fapt se face greu).
      Algoritmul

      -> La fiecare pas alegem zona cu cele mai multe de puncte;
      -> Daca zona are mai mult de 12 puncte, se imparte zona respectiva. Se uneste printr-un segment doua puncte ce se pot uni din zona respectiva. Am ales segmentul potential cu lungimea cea mai mare;
      -> Daca zona are cel mult cinci puncte, atunci vedem ce jucator are o strategie castigatoare, conform propozitiei 1. Daca are calculatorul strategia castigatoare, atunci se face mutarea urmatoare conform acestei strategii; altfel, calculatorul muta la intamplare;
      -> Daca zona are cel mult 12 puncte si cel putin 6 puncte, se cauta in zonele de acest fel mutarea care va da strategia castigatoare la pasul urmator pentru configuratia "cunoscuta" (adica zonele mici si grupajele nedecise); daca nu exista, se face o mutare la intamplare in zona maxima;

2. Implementarea

      S-au folosit urmatoarele clase:
      -Proiect2AA pentru interfata grafica;
      -Punct ce implementeaza imaginea unui punct pe ecran;
      -JucCalc ce implementeaza practic algoritmul       -Mutari ce implementeaza mutarile (facute de calculator sau de utilizator);
      La fiecare pas al jocului (fiecare "mutare"), se actualizeaza o situatie a jocului. Aceasta situatie a jocului este reprezentata de urmatoarele:
      -multimea zonelor punctelor libere, implementata ca un vector de multimi (HashSet) de obiecte de tip Punct, fiecare multime reprezentand o zona in sensul definitiei date mai sus;
      -multimea punctelor folosite, implementata ca o multime (HashSet) de obiecte de tip Punct;
      -multimea punctelor blocate, implementata ca o multime (HashSet) de obiecte de tip Punct;
      -multimea liniilor existente (trasate), implementata ca un vector de obiecte de tip Line2D.Float;
      Avem o functie care stabileste daca doua puncte se pot uni, pur si simplu vazand daca segmentul dat de cele 2 puncte nu intersecteaza vreo linie existenta.
      Exista o functie care uneste doua puncte prin segmentul corespunzator si actualizeaza situatia jocului dupa aceasta mutare. Astfel, se introduce noul segment in multimea liniilor trasate, se introduc cele 2 puncte in multimea punctelor folosite. Trebuie apoi actualizat vectorul zonelor punctelor libere. Pentru aceasta, se determina mai intai zona din care fac parte cele 2 puncte (evident, ca sa poata fi unite trebuie sa faca parte din aceeasi zona). Se elimina punctele respective din zona. Prin unirea acestor puncte, probabil ca zona respectiva s-a impartit in mai multe zone; de asemenea, pot sa apara noi puncte blocate. Exista o functie ce intoarce un vector de multimi pentru fosta zona, fiecare multime reprezentand sau o zona (caz in care are cel putin 2 puncte) sau o multime formata dintr-un singur punct (atunci nu este zona, punctul respectiv este un punct blocat). In continuare se parcurge acest vector de multimi, eliminandu-se multimile formate dintr-un singur punct (aceste puncte vor fi adaugate punctelor blocate), apoi se scoate fosta zona din vectorul zonelor si se adauga in acest vector zonele noi formate.
      Prezentam acum modul in care se imparte fosta zona in noi zone. Pornim cu un vector de multimi de puncte ce contine initial toate multimile formate dintr-un singur punct. Formam o multime de perechi de puncte ce pot fi unite. Parcurgem aceasta multime si la fiecare pas luam punctele din perechea respectiva, vedem daca fac parte din aceeasi multime de puncte (zona potentiala), daca nu reunim cele 2 multimi corespunzatoare celor 2 puncte.

      Strategia calculatorului este implementata in clasa JucCalc. Functia muta este cea prin care se realizeaza mutarea calculatorului. In aceasta functie, se determina mai intai configuratia "cunoscuta" (grupaje nedecise + zone mici), de asemenea zona de marime maxima. In functie de marimea acestei zone, se iau urmatoarele decizii:
      -Daca zona are cel putin 13 puncte, ea se imparte in zone mai mici, alegand sa se traseze segmentul cu lungimea cea mai mare din ea.
      -Daca zona are cel mult 5 puncte, atunci inseamna ca toate zonele au cel mult cinci puncte, deci avem numai zone mici si grupaje nedecise. In acest caz, daca calculatorul are o strategie castigatoare, se aplica aceasta; iar daca nu, va muta la intamplare.
      -Daca zona are cel putin 6 puncte si cel mult 12 puncte (zona mijlocie), atunci incepand cu zona maxima vom cauta in toate zonele mijlocii o mutare care sa aduca configuratia "cunoscuta" (zonele mici si grupajele nedecise) intr-o situatie avantajoasa.




      Clasa interioara GrupajNedecis gestioneaza zonele de 4 sau 5 puncte. Ea are printre membrii 2 perechi de puncte ce corespund a doua mutari posibile (o mutare duce la rezolvarea grupajului nedecis in 2 mutari, cealata conduce la rezolvarea grupajului nedecis intr-o singura mutare). O functie gaseste aceste doua perechi (daca nu va gasi una dintre ele, atunci zona nu este grupaj nedecis, ci zona mica).



      Clasa interioara ZonaMijlocie trateaza zonele de la 6 la 12 puncte. O functie determina mutarea urmatoare, in functie de numarul sigur de mutari si de numarul grupa de grupaje nedecise dorit (de fapt, conteaza doar paritatea acestor numere) prin simularea unei mutari a calculatorului si analiza situatiei create.



3. Exemplu

      Comentam in continuare rezultatele obtinute la un joc.

      Muta intai calculatorul. Deoarece sunt mai mult de 13 puncte, va trasa segmentul cel mai mare:

      Muta utilizatorul. Exista 2 zone mijlocii: (5,6,1,13,12,14,11) si (4,8,9,16,3,10). Nu exista zone mici si nici grupaje nedecise. Calculatorul va lua zona cea mai mare si va incerca sa faca o mutare astfel incat sa se formeze un numar par de grupaje nedecise si un numar sigur de mutari par (nr par poate fi si 0). Face mutarea (1-13), care formeaza 2 zone mici (5,6) si (11,12,14) (deci numarul sigur de mutari va fi 2) si nici un grupaj nedecis.

      Utilizatorul face mutarea (5-6). Numarul sigur de mutari devine 1, avem o zona mijlocie, zero grupaje nedecise. Calculatorul va cauta in zona mijlocie o mutare din care sa rezulte un numar sigur de mutari impar (pentru zona respectiva -pe total trebuie sa fie par) si un nr par de grupaje nedecise. Va face mutarea (4-8), obtinand zona mica (16,3,0). In acest moment, singurele zone sunt zone mici, numarul sigur de mutari este 2, deci utilizatorul pierde (jocul e hotarat):


      Urmatoarele mutari nu mai conteaza: