Joaca-te si programeaza SOKOBAN online
Salutare! A inceput scoala, asa ca e timpul sa ne punem creierele in miscare si mai serios decat pana acum. Iti propun o usoara incalzire cu un nivel destul de dificil din jocul Sokoban. Iar dupa incalzirea asta provocarea e sa parcurgi si sa intelegi codul sursa al jocului. (Pentru a te ajuta, am pus destul de multe comentarii in program.) Dar mai intai, hai sa ne jucam!
Pentru a porni un joc nou, apasa “Reseteaza…”, iar apoi “Executa…”. Apoi deplaseaza-ti omuletul (punctul albastru) folosind “sagetile” ‘w’, ‘a’, ‘s’ si ‘d’. Scopul e sa umpli toate destinatiile (punctele rosii) cu cutii (punctele galbene). (Daca te-ai blocat, apasa din nou “Reseteaza” si “Executa”.)
// Vreau sa programez un joc de Sokoban. // De genul celui de aici (si o sa incep chiar cu nivelul asta (ultimul :-) ): // http://sokoban.info/?4_40 // E un joc de genul labirintului si al lui Reversi, // asa ca in primul rand imi trebuie o matrice in care // sa memorez starea punctelor de pe ecran. // Voi numi matricea asta X (din lipsa de inspiratie). // In matricea X voi avea 5 tipuri de elemente: // 0: spatiu_gol (ALB) // 1: zid (GRI) // 2: destinatie_cutie (ROSU) // 3: cutie_pe_gol (GALBEN) // 4: cutie_pe_destinatie (VERDE) var spatiu_gol = 0; var zid = 1; var destinatie_cutie = 2; var cutie_pe_gol = 3; var cutie_pe_destinatie = 4; // Deci hai sa incep prin a defini matricea X si // a o completa cu valorile potrivite inceperii // nivelului de aici: http://sokoban.info/?4_40 var X = Matrice(10, 10); var i; var j; // Cum spatiile goale sunt cele mai multe, // parcurg intreaga matrice si initializez // fiecare element cu spatiu_gol i = 0; while (i<10) { j = 0; while (j<10) { X[i][j] = spatiu_gol; j = j+1; } i = i+1; } // Apoi completez ce mai e de completat prin matrice. // Adica zidurile... X[1][4]=zid; X[1][5]=zid; X[1][6]=zid; X[1][7]=zid; X[2][3]=zid; X[2][4]=zid; X[2][7]=zid; X[3][2]=zid; X[3][3]=zid; X[3][7]=zid; X[3][8]=zid; X[4][2]=zid; X[4][8]=zid; X[5][2]=zid; X[5][6]=zid; X[5][8]=zid; X[6][2]=zid; X[6][4]=zid; X[6][8]=zid; X[7][2]=zid; X[7][6]=zid; X[7][7]=zid; X[7][8]=zid; X[8][2]=zid; X[8][3]=zid; X[8][4]=zid; X[8][5]=zid; X[8][6]=zid; // ... Si destinatiile de cutii... X[3][5] = destinatie_cutie; X[5][3] = destinatie_cutie; X[5][5] = destinatie_cutie; // ... Si cutiile. X[4][4] = cutie_pe_gol; X[4][5] = cutie_pe_gol; X[4][6] = cutie_pe_gol; // Imi mai trebuie si pozitia omuletului pe matrice: var om_i = 4; var om_j = 3; // Scriu deja functia de afisare a ecranului // pe baza continutului matricei X, ca sa am // niste feedback care sa ma motiveze si sa // si vad daca am initializat bine matricea. function AfiseazaEcran() { // Parcurg matricea X si afisez fiecare element // folosind culoarea potrivita. i = 0; while (i<10) { j = 0; while (j<10) { // Mai intai verific daca am de afisat omuletul. if ((i == om_i) && (j == om_j)) Aprinde(j+1, 10-i, ALBASTRU); // Iar apoi verific ce fel de element am de afisat. else if (X[i][j] == spatiu_gol) Aprinde(j+1, 10-i, ALB); else if (X[i][j] == zid) Aprinde(j+1, 10-i, GRI); else if (X[i][j] == destinatie_cutie) Aprinde(j+1, 10-i, ROSU); else if (X[i][j] == cutie_pe_gol) Aprinde(j+1, 10-i, GALBEN); else if (X[i][j] == cutie_pe_destinatie) Aprinde(j+1, 10-i, VERDE); else // Daca cumva am pus o valoare gresita in X, // imi vor aparea pe ecran puncte turcoaz. Aprinde(j+1, 10-i, TURCOAZ); j = j+1; } i = i+1; } } // In functia de raspuns la apasarea tastelor // e toata logica jocului. Aici permit deplasarea // omuletului in cele 4 directii (sus, jos, stanga, // dreapta) daca nu e zid in directia respectiva, si tot // aici verific daca in cazul deplasarii impinge // vreuna dintre cutii (si efectueaza deplasarea ei). // Verificarea terminarii nivelului (adica atunci cand // toate destinatiile au fost ocupate de cutii) o las ca // exercitiu! :-) function FunctieTaste(ev) { // Mai intai vad ce tasta a fost apasata/ var tasta = TastaApasata(ev); // Apoi verific daca s-a apasat vreuna din tastele // de deplasare omulet (adica 'w', 'a', 's', 'd'). if (tasta == 'a') // deplasare stanga { // Daca la stanga omuletului e zid, nu fac nimic. if (X[om_i][om_j-1] == zid) {} else { // Daca la stanga omuletului e cutie urmata de // cutie sau de zid, nu fac nimic. if ( ((X[om_i][om_j-1] == cutie_pe_gol) || (X[om_i][om_j-1] == cutie_pe_destinatie)) && ((X[om_i][om_j-2] == zid) || ((X[om_i][om_j-2] == cutie_pe_gol) || (X[om_i][om_j-2] == cutie_pe_destinatie))) ) {} else { // Daca la stanga omuletului e spatiu liber, // deplasez omuletul acolo. if ((X[om_i][om_j-1] == spatiu_gol) || (X[om_i][om_j-1] == destinatie_cutie)) { om_j = om_j-1; } // Daca la stanga omuletului e cutie, // deplasez cutia la stanga o pozitie, si // omuletul la fel. else if ((X[om_i][om_j-1] == cutie_pe_gol) || (X[om_i][om_j-1] == cutie_pe_destinatie)) { // Pun cutia in noua pozitie. if (X[om_i][om_j-2] == spatiu_gol) X[om_i][om_j-2] = cutie_pe_gol; else // destinatie_cutie X[om_i][om_j-2] = cutie_pe_destinatie; // Sterg cutia de la vechea pozitie. if (X[om_i][om_j-1] == cutie_pe_gol) X[om_i][om_j-1] = spatiu_gol; else // cutie_pe_destinatie X[om_i][om_j-1] = destinatie_cutie; // Si deplasez si omul in noua pozitie. om_j = om_j-1; } } } AfiseazaEcran(); } // Si acuma urmeaza o serie de Copy-Paste la greu // (dar cu multa grija sa fac modificarile necesare)... else if (tasta == 'd') // deplasare dreapta { // Daca la dreapta omuletului e zid, nu fac nimic. if (X[om_i][om_j+1] == zid) {} else { // Daca la dreapta omuletului e cutie urmata de // cutie sau de zid, nu fac nimic. if ( ((X[om_i][om_j+1] == cutie_pe_gol) || (X[om_i][om_j+1] == cutie_pe_destinatie)) && ((X[om_i][om_j+2] == zid) || ((X[om_i][om_j+2] == cutie_pe_gol) || (X[om_i][om_j+2] == cutie_pe_destinatie))) ) {} else { // Daca la dreapta omuletului e spatiu liber, // deplasez omuletul acolo. if ((X[om_i][om_j+1] == spatiu_gol) || (X[om_i][om_j+1] == destinatie_cutie)) { om_j = om_j+1; } // Daca la dreapta omuletului e cutie, // deplasez cutia la dreapta o pozitie, si // omuletul la fel. else if ((X[om_i][om_j+1] == cutie_pe_gol) || (X[om_i][om_j+1] == cutie_pe_destinatie)) { // Pun cutia in noua pozitie. if (X[om_i][om_j+2] == spatiu_gol) X[om_i][om_j+2] = cutie_pe_gol; else // destinatie_cutie X[om_i][om_j+2] = cutie_pe_destinatie; // Sterg cutia de la vechea pozitie. if (X[om_i][om_j+1] == cutie_pe_gol) X[om_i][om_j+1] = spatiu_gol; else // cutie_pe_destinatie X[om_i][om_j+1] = destinatie_cutie; // Si deplasez si omul in noua pozitie. om_j = om_j+1; } } } AfiseazaEcran(); } else if (tasta == 'w') // deplasare sus { // Daca in susul omuletului e zid, nu fac nimic. if (X[om_i-1][om_j] == zid) {} else { // Daca in susul omuletului e cutie urmata de // cutie sau de zid, nu fac nimic. if ( ((X[om_i-1][om_j] == cutie_pe_gol) || (X[om_i-1][om_j] == cutie_pe_destinatie)) && ((X[om_i-2][om_j] == zid) || ((X[om_i-2][om_j] == cutie_pe_gol) || (X[om_i-2][om_j] == cutie_pe_destinatie))) ) {} else { // Daca in susul omuletului e spatiu liber, // deplasez omuletul acolo. if ((X[om_i-1][om_j] == spatiu_gol) || (X[om_i-1][om_j] == destinatie_cutie)) { om_i = om_i-1; } // Daca in susul omuletului e cutie, // deplasez cutia in sus o pozitie, si // omuletul la fel. else if ((X[om_i-1][om_j] == cutie_pe_gol) || (X[om_i-1][om_j] == cutie_pe_destinatie)) { // Pun cutia in noua pozitie. if (X[om_i-2][om_j] == spatiu_gol) X[om_i-2][om_j] = cutie_pe_gol; else // destinatie_cutie X[om_i-2][om_j] = cutie_pe_destinatie; // Sterg cutia de la vechea pozitie. if (X[om_i-1][om_j] == cutie_pe_gol) X[om_i-1][om_j] = spatiu_gol; else // cutie_pe_destinatie X[om_i-1][om_j] = destinatie_cutie; // Si deplasez si omul in noua pozitie. om_i = om_i-1; } } } AfiseazaEcran(); } else if (tasta == 's') // deplasare jos { // Daca in josul omuletului e zid, nu fac nimic. if (X[om_i+1][om_j] == zid) {} else { // Daca in josul omuletului e cutie urmata de // cutie sau de zid, nu fac nimic. if ( ((X[om_i+1][om_j] == cutie_pe_gol) || (X[om_i+1][om_j] == cutie_pe_destinatie)) && ((X[om_i+2][om_j] == zid) || ((X[om_i+2][om_j] == cutie_pe_gol) || (X[om_i+2][om_j] == cutie_pe_destinatie))) ) {} else { // Daca in josul omuletului e spatiu liber, // deplasez omuletul acolo. if ((X[om_i+1][om_j] == spatiu_gol) || (X[om_i+1][om_j] == destinatie_cutie)) { om_i = om_i+1; } // Daca in josul omuletului e cutie, // deplasez cutia in jos o pozitie, si // omuletul la fel. else if ((X[om_i+1][om_j] == cutie_pe_gol) || (X[om_i+1][om_j] == cutie_pe_destinatie)) { // Pun cutia in noua pozitie. if (X[om_i+2][om_j] == spatiu_gol) X[om_i+2][om_j] = cutie_pe_gol; else // destinatie_cutie X[om_i+2][om_j] = cutie_pe_destinatie; // Sterg cutia de la vechea pozitie. if (X[om_i+1][om_j] == cutie_pe_gol) X[om_i+1][om_j] = spatiu_gol; else // cutie_pe_destinatie X[om_i+1][om_j] = destinatie_cutie; // Si deplasez si omul in noua pozitie. om_i = om_i+1; } } } AfiseazaEcran(); } } // Acuma jocul e gata. Trebuie doar sa afisez // pe ecran continutul variabilelor care memoreaza // starea jocului si sa dau startul ascultarii tastelor // ce permit deplasarea omuletului (care, la randul lui, // permite deplasarea cutiilor). // Pe locuri... Fiti gata... AfiseazaEcran(); // ... Start! AscultaTaste(FunctieTaste);
Vrei o provocare ceva mai serioasa? Modifica programul astfel incat atunci cand jocul a ajuns la final (adica toate punctele rosii au devenit verzi) omuletul sa dispara de pe ecran si ascultarea tastelor sa inceteze.
Nu cunosti limba calculatoarelor? “Abecedarul” te va invata ABC-ul fara dureri de cap.
Anteriorul: Cum se programeaza jocul Reversi
Urmatorul: Ce sa mananci pentru un creier puternic