|
AVIOANE Stefanescu George 332 CB |
|
DESPRE JOCIMPLEMENTAREALGORITM |
DESPRE JOCJocul “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. IMPLEMENTAREJocul 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. ALGORITMAm diferite strategii in functie
de nivelul selectat. Nivelul: F. UsorCalculatorul 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: UsorNivelul 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: MediuLa 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: GreuIn 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); } |