Programarea unui joc Tic Tac Toe în Visual Basic

Programare jocuri pe calculator poate fi cel mai dificil (și posibil cel mai bine plătit) loc de muncă pe care îl programator poate avea. Jocurile de nivel superior necesită cel mai bun atât din partea programatorilor, cât și a calculatoarelor.

Visual Basic 6 a fost acum ocolit complet ca o platformă pentru programarea jocurilor. (Niciodată nu a fost una. Chiar și în zilele „bune ol”, programatorii serioși de jocuri nu ar folosi niciodată un limbaj la nivel înalt, precum VB 6, deoarece pur și simplu nu puteți obține o tăiere Performanța de margine pe care o necesită majoritatea jocurilor.) Dar jocul simplu „Tic Tac Toe” este o introducere excelentă în programare, care este ceva mai avansat decât "Salut Lume!"

Aceasta este o introducere excelentă în multe dintre conceptele fundamentale ale programării, deoarece combină tehnici, inclusiv:

  • Utilizarea matrice. Marcajele X și O sunt păstrate în tablouri separate și întreaga matrice este trecută între funcții pentru a urmări progresul jocului.
  • Utilizarea graficelor la nivel VB 6: VB 6 nu oferă o capacitate grafică excelentă, dar jocul este o bună introducere în ceea ce este disponibil. O mare parte din restul acestei serii este o explorare a modului în care GDI +, următoarea generație de grafică Microsoft, înlocuiește graficele la nivel VB 6.
    instagram viewer
  • Utilizarea calculelor matematice pentru controlul programului: Programul folosește un modulo inteligent (Mod) și un număr întreg calcule de diviziune folosind tablourile de marcaj cu două jocuri pentru a determina când are un „câștig” cu trei elemente a avut loc.

Clasa de programare din acest articol este probabil doar puțin trecută de nivelul de început, dar ar trebui să fie bună pentru programatorii „intermediari”. Dar haideți să începem la un nivel elementar pentru a ilustra unele dintre concepte și pentru a vă începe cu dvs. Visual Basic cariera de programare a jocurilor. Chiar și studenții mai avansați pot constata că este ușor dificil să obții obiectele sub formă corectă.

Cum se joacă Tic Tac Toe

Dacă nu ai jucat niciodată Tic Tac Toe, aici sunt regulile. Doi jucători alternează la plasarea Xs și Os pe terenul de joc 3 x 3.

Înainte de începerea jocului, ambii jucători trebuie să fie de acord cu cine va merge mai întâi și cine va marca mișcările sale cu ce simbol. După prima mișcare, jucătorii își plasează alternativ semnele în orice celulă goală. Scopul jocului este de a fi primul jucător cu trei mărci pe o linie orizontală, diagonală sau verticală. Dacă nu există celule goale și niciun jucător nu are o combinație câștigătoare, jocul este o remiză.

Înainte de a începe orice codare reală, este întotdeauna o idee bună să schimbați numele componentelor pe care le utilizați. Odată ce începeți de codificare, numele va fi folosit automat de Visual Basic, astfel încât doriți să fie numele potrivit. Vom folosi numele formularului frmTicTacToe și, de asemenea, vom schimba subtitrarea la „Despre Tic Tac Toe”.

Cu forma stabilită, utilizați controlul cutiei de instrumente pentru a trasa o grilă de 3 x 3. Faceți clic pe instrumentul de linie, apoi desenați o linie unde doriți. Va trebui să creezi patru linii în acest fel și să ajustezi lungimea și poziția lor pentru a le face să pară corect. Visual Basic are, de asemenea, câteva instrumente convenabile în meniul Format care vă vor ajuta. Aceasta este o mare șansă de a exersa cu ei.

Pe lângă grila de redare, vom avea nevoie de câteva obiecte pentru simbolurile X și O care vor fi plasate pe grilă. Deoarece există nouă spații în grilă, vom crea un tablou de obiecte cu nouă spații, numite elemente în Visual Basic.

Există mai multe modalități de a face aproape orice în mediul de dezvoltare Visual Basic, iar crearea tablourilor de control nu face excepție. Probabil, cel mai simplu mod este să creezi prima etichetă (faceți clic și desenați la fel ca instrumentul de linie), numiți-o, setați toate atributele (cum ar fi Font și ForeColor), apoi faceți copii ale acesteia. VB 6 vă va întreba dacă doriți să creați un tablou de control. Utilizați numele lblPlayGround pentru prima etichetă.

Pentru a crea celelalte opt elemente ale grilei, selectați primul obiect de etichetă, setați proprietatea Index la zero și apăsați CTRL + C (copiere). Acum puteți apăsa CTRL + V (lipire) pentru a crea un alt obiect de etichetă. Când copiați astfel de obiecte, fiecare copie va moșteni toate proprietățile, cu excepția Indexului de la prima. Indicele va crește cu unu pentru fiecare copie. Acesta este un tablou de control, deoarece toate au același nume, dar valori diferite ale indexului.

Dacă creați tabloul în acest fel, toate copiile vor fi stivuite una peste alta, în colțul din stânga sus al formularului. Trageți fiecare etichetă într-una dintre pozițiile grilei de redare. Asigurați-vă că valorile indexului sunt secvențiale în grilă. Logica programului depinde de acesta. Obiectul etichetei cu valoarea de index 0 ar trebui să se afle în colțul din stânga sus, iar eticheta din dreapta jos ar trebui să aibă index 8. Dacă etichetele acoperă grila de redare, selectați fiecare etichetă, faceți clic dreapta și selectați Trimiteți înapoi.

Deoarece există opt moduri posibile de a câștiga jocul, vom avea nevoie de opt linii diferite pentru a arăta câștigul pe grila de joc. Veți folosi aceeași tehnică pentru a crea un alt tablou de control. Mai întâi, desenați linia, denumiți-o linWin și setați proprietatea Index la zero. Apoi folosiți tehnica copy-paste pentru a produce încă șapte linii. Următoarea ilustrație arată cum să setați corect numerele de index.

Pe lângă obiectele de etichetă și linie, aveți nevoie de câteva butoane de comandă pentru a juca jocul și mai multe etichete pentru a păstra scorul. Pașii pentru crearea acestora nu sunt detaliate aici, dar acestea sunt obiectele de care aveți nevoie.

Două butoane obiecte:

  • cmdNewGame
  • cmdResetScore

Obiect cadru fraPlayFirst care conține două butoane de opțiune:

  • optXPlayer
  • optOPlayer

Obiect cadru fraScoreBoard care conține șase etichete. Numai lblXScore și lblOScore sunt modificate în codul programului.

  • lblX
  • lblXScore
  • lblO
  • lblOScore
  • lblMinus
  • lblColon

În cele din urmă, aveți nevoie, de asemenea, obiectul de etichetă lblStartMsg pentru a „masca” butonul cmdNewGame atunci când nu trebuie făcut clic. Acest lucru nu este vizibil în ilustrația de mai jos, deoarece ocupă același spațiu sub forma butonului de comandă. Este posibil să fie necesar să mutați temporar butonul de comandă pentru a desena această etichetă pe formular.

Până în prezent, nu a fost efectuată o codare VB, dar suntem în sfârșit gata să facem asta.

Inițializarea

Acum trebuie să începeți în sfârșit codificarea programului. Dacă nu ați făcut-o deja, este posibil să doriți să descărcați codul sursă pe care să îl urmați pe măsură ce operațiunea programului este explicată.

Una dintre primele decizii de proiectare care trebuie luate este modul de a urmări „starea” actuală a jocului. Cu alte cuvinte, care sunt actualele X și Os pe grila de joc și cine se mișcă în continuare. Conceptul de „stat” este esențial în multe programe și, în special, este important în programarea ASP și ASP.NET pentru web

Există mai multe moduri în care acest lucru ar putea fi realizat, deci este un pas critic în analiză. Dacă rezolvați singur această problemă, poate doriți să desenați o diagramă de flux și să încercați diferite opțiuni cu „hârtie zgârietură” înainte de a începe orice codare.

Soluția noastră folosește două „tablouri bidimensionale”, deoarece aceasta ajută la urmărirea „stării”, prin simpla schimbare a indexurilor de matrice în buclele de programe. Starea colțului din stânga sus va fi în elementul tabloului cu index (1, 1), colțul din dreapta sus va fi în (1, 3), în dreapta jos în (3,3) și așa mai departe. Cele două tablouri care fac acest lucru sunt:

iXPos (x, y)

și

iOPos (x, y)

Există o mulțime de moduri diferite de a face acest lucru, iar soluția VB.NET finală din această serie vă arată cum să o faceți cu un singur tablou unidimensional.

Programarea pentru a traduce aceste tablouri în decizii de câștig de jucător și afișajele vizibile în formular se află pe pagina următoare.

De asemenea, aveți nevoie de câteva variabile globale după cum urmează. Rețineți că acestea sunt incluse în codul general și declarații pentru formular. Acest lucru îi face „nivelul modulului” variabile la care se poate face referire oriunde în cod pentru acest formular. Pentru mai multe detalii, verificați Înțelegerea domeniului de aplicare a variabilelor din Ajutor Visual Basic

Există două domenii în care variabilele sunt inițializate în programul nostru. În primul rând, câteva variabile sunt inițializate în timp ce se încarcă formularul frmTicTacToe.

Sub Formular privat_Load ()

În al doilea rând, înainte de fiecare joc nou, toate variabilele care trebuie resetate la valorile de pornire sunt atribuite într-o subrutină de inițializare.

Sub InitPlayGround ()

Rețineți că inițializarea încărcării formularului apelează și la inițializarea locului de joacă.

Una dintre abilitățile critice ale unui programator este capacitatea de a utiliza facilitățile de depanare pentru a înțelege ce face codul. Puteți utiliza acest program pentru a încerca:

  • Pasul cu codul cu tasta F8
  • Setarea unui ceas pe variabile cheie, cum ar fi sPlaySign sau iMove
    Setarea unui punct de întrerupere și interogarea valorii variabilelor. De exemplu, în bucla interioară a inițializării:
lblPlayGround ((i - 1) * 3 + j - 1) .Caption = ""

Rețineți că acest program arată clar de ce este o practică bună de programare să păstrați datele în matrice ori de câte ori este posibil. Dacă nu aveți tablouri în acest program, ar trebui să scrieți coduri de genul:

Line0.Visible = False
Line1.Visible = False
Line2.Visible = False
Linia3.Vizibilă = Falsă
Line4.Visible = False
Linie5.Vizibil = False
Linia6.Vizibilă = Falsă
Line7.Visible = False

in loc de asta:

Pentru i = 0 până la 7
linWin (i) .Vizibil = False
Apoi eu

Efectuarea unei mișcări

Dacă orice parte a sistemului poate fi considerată „inima”, este subroutine lblPlayGround_Click. Această subrutină este numită de fiecare dată când un jucător face clic pe grila de redare. (Clicurile trebuie să fie în interiorul unuia dintre cele nouă elemente lblPlayGround.) Observați că această subrutină are un argument: (Index As Integer). Majoritatea celorlalte „subrutine evenimente”, cum ar fi cmdNewGame_Click () nu. Index indică pe ce obiect de etichetă a fost făcut clic. De exemplu, indexul ar conține valoarea zero pentru colțul din stânga sus al grilei și valoarea opt pentru colțul din dreapta jos.

După ce un jucător face clic pe un pătrat din grila de joc, butonul de comandă pentru a începe un alt joc, cmdNewGame, este „pornit”, făcându-l vizibil. Starea acestui buton de comandă are dublă datorie, deoarece este folosită și ca o variabilă de decizie booleană mai târziu în program. Utilizarea unei valori de proprietate ca variabilă de decizie este de obicei descurajată deoarece, dacă devine vreodată necesar să schimbi programul (să zicem, de exemplu, butonul de comandă cmdNewGame vizibil tot timpul), atunci programul va eșua în mod neașteptat, deoarece este posibil să nu vă amintiți că este folosit și ca parte a programului logică. Din acest motiv, este întotdeauna o idee bună să căutați prin codul programului și să verificați utilizarea oricărui lucru pe care îl modificați atunci când efectuați întreținerea programului, chiar și valorile proprietății. Acest program încalcă regula în parte pentru a face acest punct și parțial pentru că acesta este un cod relativ simplu de cod, unde este mai ușor să vezi ce se face și să eviți problemele mai târziu.

O selecție de jucător a unui pătrat de joc este procesată apelând subrutinul GamePlay cu Index ca argument.

Procesarea mișcării

În primul rând, verificați dacă s-a dat clic pe un pătrat neocupat.

Dacă lblPlayGround (xo_Move) .Caption = "" Atunci

După ce suntem siguri că aceasta este o mutare legitimă, contorul de mișcare (iMove) este incrementat. Următoarele două rânduri sunt foarte interesante, întrucât traduc traducerile unidimensionale Dacă matricea lblPlayGround este la indexuri bidimensionale pe care le puteți folosi în iXPos sau iOPos. Diviziunea Mod și întregi („backback”) sunt operații matematice pe care nu le utilizați în fiecare zi, dar iată un exemplu excelent care arată cum pot fi foarte utile.

Dacă lblPlayGround (xo_Move) .Caption = "" Atunci
iMove = iMove + 1
x = Int (xo_Move / 3) + 1
y = (xo_Move Mod 3) + 1

Valoarea xo_Move 0 va fi tradusă în (1, 1), 1 la (1, 2)... 3 până la (2, 1)... 8 până la (3, 3).

Valoarea din sPlaySign, o variabilă cu obiectivul modulului, urmărește ce jucător a făcut mișcarea. Odată ce tablourile de mutare sunt actualizate, componentele etichetelor din grila de redare pot fi actualizate cu semnul corespunzător.

Dacă sPlaySign = "O" Atunci
iOPos (x, y) = 1
iWin = CheckWin (iOPos ())
altfel
iXPos (x, y) = 1
iWin = CheckWin (iXPos ())
End If
lblPlayGround (xo_Move) .Caption = sPlaySign

De exemplu, când playerul X face clic pe colțul din stânga sus al grilei, variabilele vor avea următoarele valori:

Ecranul utilizatorului arată doar un X în caseta din stânga sus, în timp ce iXPos are un 1 în caseta din stânga sus și 0 în toate celelalte. IOPos are 0 în fiecare cutie.

Valorile se schimbă atunci când jucătorul O face clic pe pătratul central al grilei. Acum iOPos arată un 1 în caseta centrală, în timp ce ecranul utilizatorului arată un X în stânga sus și un O în caseta centrală. IXPos arată doar 1 în colțul din stânga sus, cu 0 în toate celelalte casete.

Acum că știți unde a făcut clic un jucător și care a făcut clicul (folosind valoarea din sPlaySign), tot ce trebuie să faci este să afli dacă cineva a câștigat un joc și să-ți dai seama cum să arăți asta în afişa.

Găsirea unui câștigător

După fiecare mișcare, funcția CheckWin verifică combinația câștigătoare. CheckWin funcționează adăugând în jos fiecare rând, pe fiecare coloană și prin fiecare diagonală. Urmărirea pașilor prin CheckWin folosind funcția Debug de Visual Basic poate fi foarte educativă. Găsirea unui câștig este mai întâi o problemă, verificând dacă s-au găsit trei 1 în fiecare dintre verificările individuale din variabila iScore, apoi returnarea unei valori „semnătură” unice în Checkwin care este utilizată ca indice de matrice pentru a schimba proprietatea vizibilă a unui element din linWin tablou de componente. Dacă nu există un câștigător, CheckWin va conține valoarea -1. Dacă există un câștigător, afișajul este actualizat, tabelul de schimb este schimbat, este afișat un mesaj de felicitare și jocul este reluat.

Haideți să parcurgem în detaliu una dintre verificări pentru a vedea cum funcționează. Celelalte sunt similare.

'Verificați rândurile pentru 3
Pentru i = 1 până la 3
iScore = 0
CheckWin = CheckWin + 1
Pentru j = 1 până la 3
iScore = iScore + iPos (i, j)
Următorul j
Dacă iScore = 3 Atunci
Funcție de ieșire
End If
Apoi eu

Primul lucru de remarcat este că primul contor de indexuri contează pe rânduri, în timp ce al doilea j contează peste coloane. Bucla exterioară, apoi trece pur și simplu de la un rând la altul. Bucla internă contează 1-urile din rândul curent. Dacă sunt trei, atunci ai un câștigător.

Rețineți că, de asemenea, țineți cont de numărul total de pătrate testate în variabila CheckWin, care este valoarea transmisă înapoi atunci când această funcție se încheie. Fiecare combinație câștigătoare va ajunge cu o valoare unică în CheckWin de la 0 la 7, care este utilizată pentru a selecta unul dintre elementele din tabloul de componente linWin (). Acest lucru face ca ordinea codului în funcția CheckWin să fie importantă și! Dacă ați mutat unul dintre blocurile din cod buclă (ca cel de mai sus), atunci când cineva câștigă, linia greșită ar fi trasată pe grila de joc. Încearcă și vezi!

Detalii de finisare

Singurul cod care nu a fost încă discutat este subrutinul pentru un nou joc și subrutina care va reseta scorul. Restul logicii din sistem face ca acestea să fie destul de ușoare. Pentru a începe un joc nou, nu trebuie decât să apelați subprogramul InitPlayGround. Ca o comoditate pentru jucători, deoarece butonul poate fi făcut clic pe mijlocul unui joc, cereți confirmare înainte de a merge mai departe. De asemenea, solicitați confirmare înainte de a reporni tabloul de bord.