AVIOANE

Stefanescu George

332 CB

DESPRE JOC

IMPLEMENTARE

ALGORITM

Nivel: F. Usor

Nivel: Usor

Nivel: Mediu

Nivel: Greu

 

 

Applet

 

Download

DESPRE JOC

Jocul “Avioane” este un joc cunoscut in copilarie. El se joaca intre doi adversari, care au fiecare cate doua “radare”. In primul radar, jucatorul isi poziţioneaza cele 2 avioane, iar in al doilea incearca sa loveasca avioanele adversarului. Cele 2 radare sunt 2 matrice 10x10.

Un avion este distrus daca este lovit in cap sau este ciuruit total.

Loviturile se dau alternativ, sub forma de coordonate.

Câstiga cel care reuseste sa distruga cele doua avioane ale adversarului.

IMPLEMENTARE

Jocul l-am implementat in Java. Am folosit functii si clase care nu necesita mai mult de Java 1.2.

In partea de sus a applet-ului sunt 8 butoane. Primele 4 se refera la orientarea avionului, iar urmatoarele 4 se alege nivelul de dificultate si porneste un nou joc.

In partea centrala avem cele doua “radare”. Cel din stanga este cel pe care jucatorul isi pozitioneaza avionele, iar pe cel din dreapta da loviturile.

In coltul din stanga-jos, este afisat nivelul de dificultate, iar in dreapta, scorul curent (numarul de avioane nedoborate).

In radarul din stanga apar si loviturile date de calculator. In radarul din dreapta apar loviturile date de jucator. Ele sunt codificate astfel: galben – lovitura data si esuata, rosu – lovitura reusita in capul avionului, roz – lovitura reusita.

Pentru fiecare jucator (Jucatorul si Computerul), am cate 2 matrici: radarJucator1[][] si radarJucator2[][], respectiv radarComputer1[][] si radarComputer2[][].

In radarul 1, fiecare isi are harta propriilor avioane, cu codificarea: 1 pentru corpul avionului si 2 pentru cap.

In radarul 2, fiecare are harta loviturilor date, cu codificarea: 3 ratare, 2 lovit avion inamic, 1 lovit in cap avionul inamic, 0 nu am lovit acolo inca.

Pentru jucatorul uman, folosesc aceasta harta la afisare. Am creeat corespondenta: 0 alb, 1 rosu, 2 roz, 3 galben.

ALGORITM

Am diferite strategii in functie de nivelul selectat.

 

Nivelul: F. Usor

Calculatorul da lovituri random pe radar, avand totusi grija sa nu repete vreo lovitura. Generez lovitura si verific cu functia verificaRadar() daca nu cumva am mai dat acea lovitura. In cazul in care se repeta lovitura, generez alta lovitura.

 

       public void compFUsor() {

              int k = 100;

              hi = k/10;

              hj = k%10;

              while ((k == 100)||(!verificaRadar())) {

                     k = (int)(Math.random()*100);

                     hi = k/10;

                     hj = k%10;

              }

              loveste();

       }

 

Functia loveste() marcheaza, in functie de efect (lovitura aiurea, in corpul avionului sau in cap cu codificarea respectiva 3, 2, respectiv 1), lovitura pe radarul 2 si preda “turn”-ul celuilalt jucator. Acest lucru il realizez cu o variabila intreaga turn care e 0 (e randul jucatorului) sau 1 (randul calculatorului).

 

Nivelul: Usor

Nivelul Usor este doar o mica imbunatatire a nivelului F. Usor. Se observa ca nu se poate ca un avion inamic sa se afle cu capul in colt, si nu numai patratica din colt, ci chiar 4 patratele din colt.

 

Nivelul: Mediu

La nivelul mediu, pana la prima lovitura nimerita, se foloseste algoritmul de la nivelul Usor. Cand a gasit o lovitura valida (a nimerit corpul unui avion inamic), atunci el incearca sa loveasca direct in capul avionului inamic. Dupa un mic studiu, am descoperit 32 de mutari posibile dintr-un punct lovit din care sigur una nimereste. Aceasta lista am bagat-o in matriceMediu[]. Ca sa nu repet vreo valoare din ea, mai am un vector maska[] de 0 si 1, cu care maschez matriceMediu.

 

       public void compMediu() {

              int k = 100, val;

              hi = k / 10;

              hj = k % 10;

              if (lastGoodHit == 100) {

                     while ((k == 100)||(!verificaRadar())) {

                           k = (int)(Math.random()*100);

                           switch (k) {

                                  case 0: case 1: case 8: case 9: case 10: case 11: case 18: case 19:

                                  case 80: case 81: case 88: case 89: case 90: case 91: case 98: case 99: k = 100; break;

                           }

                           hi = k/10;

                           hj = k%10;

                     }

                     loveste();

                     if (radarComputer2[hi][hj] != 3) {

                           lastGoodHit = k;

                           for (int i = 0; i < 32; i++) maska[i] = 0;

                     }

                     if (radarComputer2[hi][hj] == 1) lastGoodHit = 100;

              } else {

                     do {

                           val = (int)(Math.random()*31);

                           k = lastGoodHit + matriceMediu[val];

                     } while ((k >= 100)&&(k < 0));

                     hi = k/10;

                     hj = k%10;

                     while ((maska[val] == 1)||(!verificaRadar())) {

                           val = (int)(Math.random()*31);

                           k = lastGoodHit + matriceMediu[val];

                           if ((k < 0)||(k >= 100)) {

                                  hi = k/10;

                                  hj = k%10;

                           }

                     }

                     maska[val] = 1;

                     loveste();

                     if (radarComputer2[hi][hj] == 1) lastGoodHit = 100;

              }

       }

 

         

Nivelul: Greu

In nivelul Greu am aplicat un mic backtracking. Pana la prima lovitura buna, se foloseste algoritmul de generare de la nivelul Usor.

Dupa ce am o lovitura reusita, prelucrez acel nod. Daca are vecin in jos (e o lovitura buna), bag nodul intr-o stiva lovituri si nodul curent de prelucrat este vecinul de jos. Urmatorul vecin prelucrat este cel de deasupra. Daca e deja in stiva, trec la stanga. Ultima prelucrare este la dreapta.

Daca nodul curent este prelucrat in totalitate, extrag din stiva nodul anterior, dar neprelucrat in totalitate.

Din calcule, rezulta ca in cazul cel mai nefavorabil, dupa o lovitura reusita, se nimereste capul din maxim 24 de lovituri. Deci cea mai buna strategie pentru jucatorul uman este sa-si orienteze avioanele spre stanga.

         

       public void compGreu() {

              int k = 100;

              hi = k / 10;

              hj = k % 10;

              if (lastGoodHit == 100) {

                     while ((k == 100)||(!verificaRadar())) {

                           k = (int)(Math.random()*100);

                           switch (k) {

                                  case 0: case 1: case 8: case 9: case 10: case 11: case 18: case 19:

                                  case 80: case 81: case 88: case 89: case 90: case 91: case 98: case 99: k = 100; break;

                           }

                           hi = k/10;

                           hj = k%10;

                     }

                     loveste();

                     if (radarComputer2[hi][hj] != 3) lastGoodHit = k;

                     if (radarComputer2[hi][hj] == 1) lastGoodHit = 100;

              } else do {

                     k = lastGoodHit+1; //in jos

                     hi = k / 10;

                     hj = k % 10;

                     if ((k >= 0)&&(k < 100))

                           if (verificaRadar()) {

                                  loveste();

                                  if (radarComputer2[hi][hj] != 3) {

                                         lovituri.push(new Integer(lastGoodHit));

                                         lastGoodHit = k;

                                  }

                                  if (radarComputer2[hi][hj] == 1) {

                                         lastGoodHit = 100;

                                         golesteStiva();

                                  }

                                  return;

                           }

                     k = lastGoodHit - 1; // in sus

                     hi = k / 10;

                     hj = k % 10;

                     if ((k >= 0)&&(k < 100))

                           if (verificaRadar()) {

                                  loveste();

                                  if (radarComputer2[hi][hj] != 3) {

                                         lovituri.push(new Integer(lastGoodHit));

                                         lastGoodHit = k;

                                  }

                                  if (radarComputer2[hi][hj] == 1) {

                                         lastGoodHit = 100;

                                         golesteStiva();

                                  }

                                  return;

                           }

                     k = lastGoodHit - 10; // in stanga

                     hi = k / 10;

                     hj = k % 10;

                     if ((k >= 0)&&(k < 100))

                           if (verificaRadar()) {

                                  loveste();

                                  if (radarComputer2[hi][hj] != 3) {

                                         lovituri.push(new Integer(lastGoodHit));

                                         lastGoodHit = k;                                      

                                  }

                                  if (radarComputer2[hi][hj] == 1) {

                                         lastGoodHit = 100;

                                         golesteStiva();

                                  }

                                  return;

                           }

                     k = lastGoodHit + 10; // in dreapta

                     hi = k / 10;

                     hj = k % 10;

                     if ((k >= 0)&&(k < 100))

                           if (verificaRadar()) {

                                  loveste();

                                  if (radarComputer2[hi][hj] != 3) {

                                         lovituri.push(new Integer(lastGoodHit));

                                         lastGoodHit = k;                                      

                                  }

                                  if (radarComputer2[hi][hj] == 1) {

                                         lastGoodHit = 100;

                                         golesteStiva();

                                  }

                                  return;

                           } else lastGoodHit = (Integer)lovituri.pop()).intValue();

              } while (true);

       }