A Tic Tac Toe játék programozása

A Tic Tac Toe játék programozása

A számítógépes játékok programozása lehet a technikailag legigényesebb (és talán a legjobban fizető) munka, amely a programozók számára lehetséges. A legmagasabb szintű játékokhoz mind a programozóktól, mind a számítógépektől szükség van a legjobbakra.

A Visual Basic 6-ot most már alaposan megkerülik a játékprogramozás platformjaként. (Soha nem volt ilyen. Még a "jó időkben" a komoly játékprogramozók soha nem használnának olyan magas szintű nyelvet, mint a VB 6, mert nem sikerült elérni azt a csúcsteljesítményt, amelyet a legtöbb játék megkövetel.) De a Az egyszerű "Tic Tac Toe" játék egy nagyszerű bevezetés a programozáshoz, amely egy kicsit fejlettebb, mint a "Hello World!"

Ez nagyszerű bevezetés a programozás sok alapvető fogalmához, mivel egyesíti a következő technikákat:

  • Tömbök használata. Az X és O jelölőket külön tömbökben tartják, és a teljes tömböket átviszik a funkciók között, hogy nyomon követhessék a játék előrehaladását.
  • VB 6 szintű grafika használata: A VB 6 nem kínál nagyszerű grafikai képességeket, de a játék jó bevezetést nyújt a rendelkezésre álló lehetőségekhez. A sorozat fennmaradó része annak feltárása, hogyan helyettesíti a GDI +, a Microsoft grafika következő generációja a VB 6 szintű grafikát.
  • Matematikai számítások használata a programvezérléshez: A program okos modulo (Mod) és egész szám-eloszlási számításokat használ a kétjátékos jelölő tömbök segítségével annak meghatározására, hogy mikor történt három elem "győzelem".

Ebben a cikkben a programozási osztály talán csak egy kicsit meghaladja a kezdő szintet, de jó lehet az „közbenső” programozók számára. De kezdjük az elemi szinttel, hogy szemléltessük néhány fogalmat, és kezdjük el a Visual Basic játék-programozási karrierjével. Még az ennél fejlettebb hallgatók is azt tapasztalhatják, hogy kissé nehéz feladat a tárgyak megfelelő formájában történő előállítása.

Hogyan kell játszani a Tic Tac Toe játékot

Ha még soha nem játszottál a Tic Tac Toe játéknál, akkor itt találja meg a szabályokat. Két játékos felváltva helyezi el az Xs és az Os 3 x 3 játékteret.

A játék megkezdése előtt mindkét játékosnak megállapodnia kell arról, hogy ki megy először, és ki jelöli a mozgását. Az első mozdulat után a játékosok felváltva helyezik jelöléseiket bármely üres cellába. A játék célja az, hogy az első játékos legyen három jelöléssel vízszintes, átlós vagy függőleges vonalban. Ha nincsenek üres cellák, és egyik játékos sem rendelkezik nyerő kombinációval, akkor a játék döntetlen.

A program indítása

A tényleges kódolás megkezdése előtt mindig érdemes megváltoztatni a használt összetevők nevét. A kódolás megkezdése után a név automatikusan felhasználja a Visual Basic, így azt akarja, hogy a helyes név legyen. Az űrlap nevét fogjuk használni frmTicTacToe és a feliratot "A Tic Tac Toe névjegye" -re változtatjuk.

A létrehozott űrlap segítségével a vonal eszköztár vezérlőjével rajzoljon 3 x 3 rácsot. Kattintson a vonal eszközre, majd húzzon egy vonalat a kívánt helyre. Ilyen módon négy sort kell létrehoznia, és beállítania kell azok hosszát és helyzetét, hogy azok megfelelőnek látszanak. A Visual Basic a Format menü alatt rendelkezik néhány kényelmes eszközzel, amelyek segítenek. Ez nagyszerű esély arra, hogy velük gyakoroljanak.

A játékrácson kívül szükségünk lesz néhány objektumra az X és O szimbólumokhoz is, amelyeket a rácsra kell helyezni. Mivel kilenc szóköz található a rácsban, létrehozunk egy objektummátrixot kilenc szóközzel, amelyeket Visual Basicben elemeknek nevezünk.

Számos módja van a Visual Basic fejlesztési környezetben szinte mindent megtenni, és a vezérlő tömbök létrehozása sem kivétel. Valószínűleg a legegyszerűbb módszer az első címke létrehozása (kattintson és rajzoláshoz hasonlóan a vonalhoz), elnevezése, az összes attribútum beállítása (például a Betűkészlet és a ForeColor), majd másolat készítése. A VB 6 megkérdezi, hogy kíván-e vezérlő tömböt létrehozni. Az első címkéhez használja az lblPlayGround nevet.

A rács többi nyolc elemének létrehozásához válassza ki az első címkeobjektumot, állítsa az Index tulajdonságot nullára, és nyomja meg a CTRL + C (másolás) gombot. Most megnyomhatja a CTRL + V (beillesztés) gombot egy másik címkeobjektum létrehozásához. Ha ilyen objektumokat másol, akkor minden másolat az összes tulajdonságot örökli, kivéve az elsőt, az Indexet. Az index mindegyik példányonként egynel növekszik. Ez egy vezérlő tömb, mert mindegyiknek azonos neve, de eltérő index értékei vannak.

Ha így hozza létre a tömböt, akkor az összes példány egymásra lesz helyezve az űrlap bal felső sarkában. Húzza az egyes címkéket a játszórács egyik helyére. Ellenőrizze, hogy az index értékek egymás után vannak-e a rácsban. A program logikája attól függ. A 0 indexértékű címké objektumnak a bal felső sarokban kell lennie, a jobb alsó címkének pedig 8. indexének kell lennie. Ha a címkék lefedik a játékrácsot, jelölje ki az egyes címkéket, kattintson a jobb gombbal, és válassza a Küldés vissza lehetőséget.

Mivel nyolc lehetséges módszer nyerheti a játékot, nyolc különböző vonalra van szükségünk a győzelem megmutatásához a játékrácson. Ugyanezt a technikát fogja használni egy másik vezérlő tömb létrehozásához. Először húzza ki a vonalat, nevezze el linWin-nek, és állítsa az Index tulajdonságot nullára. Ezután használjon copy-paste technikát további hét sor előállításához. Az alábbi ábra bemutatja, hogyan kell helyesen beállítani az indexszámokat.

A címke és a sor objektumok mellett szükség van néhány parancsgombra a játék lejátszásához, és további címkékre a pontszám megtartásához. Ezek létrehozásának lépései itt nem részletezettek, de ezek az objektumok, amelyekre szüksége van.

Két gombobjektum:

  • cmdNewGame
  • cmdResetScore

A fraPlayFirst keret objektuma, amely két opciógombot tartalmaz:

  • optXPlayer
  • optOPlayer

Hat címkét tartalmazó fraScoreBoard objektumkeret. Csak az lblXScore és az lblOScore változnak a programkódban.

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

Végül szükség van az lblStartMsg címkeobjektumra, hogy 'elrejtse' a cmdNewGame gombot, amikor nem kellene rákattintani. Ez nem látható az alábbi ábrán, mert ugyanolyan helyet foglal el az űrlapon, mint a parancs gomb. Lehet, hogy ideiglenesen el kell mozgatnia a parancsgombot, hogy felhívja ezt a címkét az űrlapra.

Eddig VB kódolást nem végeztek, de végre készen állunk erre.

Inicializálás

Most végre meg kell kezdenie a program kódolását. Ha még nem tette meg, akkor érdemes letölteni a forráskódot, amely követi a program működésének magyarázatát.

Az egyik első tervezési döntés az, hogy miként lehet nyomon követni a játék jelenlegi „állapotát”. Más szavakkal: mik a jelenlegi Xs és Os a rácson, és ki mozog tovább. Az 'állam' fogalma kritikus jelentőségű a sok programozás során, különös tekintettel az ASP és az ASP.NET programozására az interneten.

Számos módon lehet ezt megtenni, tehát kritikus lépés az elemzésben. Ha ezt a problémát egyedül oldja meg, akkor esetleg érdemes rajzolnia egy folyamatábrát, és a kódolás megkezdése elõtt kipróbálhatja a „papírkaparóval” különféle lehetõségeket.

Változók

Megoldásunk két "kétdimenziós tömböt" használ, mert ez segíti az "állapot" nyomon követését azáltal, hogy egyszerűen megváltoztatja a tömbindexeket a program hurkokban. A bal felső sarok állapota a tömb elemben (1, 1) van, a jobb felső sarokban (1, 3), a jobb alsóban (3,3) és így tovább . A következő két tömb:

iXPos (x, y)

és

iOPos (x, y)

Sokféle módon lehet ezt megtenni, és a sorozat végleges VB.NET megoldása megmutatja, hogyan kell ezt csinálni egyetlen egydimenziós tömb segítségével.

A következő oldalon találhatók azok a programozások, amelyek segítségével ezeket a tömböket játékos nyerési döntésekké alakíthatják le, és az űrlap látható kijelzői.

Szüksége van néhány globális változóra is, az alábbiak szerint. Vegye figyelembe, hogy ezek szerepelnek az űrlap Általános és Nyilatkozatok kódjában. Ez "modulszintű" változókká teszi őket, amelyekre az űrlap kódjában bárhol hivatkozhatunk. Erről bővebben a Változók körének megértése című részben olvashat a Visual Basic súgóban.

Két olyan terület van, ahol a változók inicializálva vannak programunkban. Először néhány változót inicializálunk, amíg az frmTicTacToe űrlap betöltődik.

Privát alform_terhelés ()

Másodszor, minden új játék előtt minden olyan változót, amelyet vissza kell állítani a kezdő értékekre, hozzá kell rendelni egy inicializálási alprogramban.

Sub InitPlayGround ()

Vegye figyelembe, hogy az űrlapterhelés inicializálása a játszótér inicializálását is hívja.

A programozók egyik kritikus képessége a hibakeresési lehetőségek felhasználása annak megértéséhez, hogy mit csinál a kód. A program segítségével kipróbálhatja:

  • A kód átvitele az F8 billentyűvel
  • Órák beállítása a fő változókra, például az sPlaySign vagy az iMove
    Töréspont beállítása és a változók értékének lekérdezése. Például az inicializálás belső hurkában:
lblPlayGround ((i - 1) * 3 + j - 1) .Caption = ""

Vegye figyelembe, hogy ez a program egyértelműen megmutatja, miért jó a programozási gyakorlat, ha az adatok tömbökben vannak tárolva, amikor csak lehetséges. Ha nem volt tömbje ebben a programban, akkor ehhez hasonló kódot kell írnia:

0 sor.Visible = Hamis
1. sor.Visible = Hamis
Line2.Visible = Hamis
3. sor: Vizuális = Hamis
4. sor: Vizible = Hamis
5. vonalVisible = Hamis
6. sor.Visible = Hamis
7. sor .Visible = Hamis

ehelyett:

I = 0-tól 7-ig
linWin (i) .Visible = Hamis
Következő i

Mozgás

Ha a rendszer bármely részét „szívnek” lehet tekinteni, akkor az lblPlayGround_Click szubrutin. Ezt az alprogramot minden alkalommal meghívják, amikor egy játékos rákattint a játékra. (A kattintásoknak a kilenc lblPlayGround elem egyikében kell lennie.) Vegye figyelembe, hogy ennek az alprogramnak van egy argumentuma: (Index As Integer). A legtöbb „esemény alprogram”, mint például a cmdNewGame_Click (), nem. Az index azt jelzi, hogy melyik címke-objektumra kattintottak. Például az index tartalmazza a rács bal felső sarkának nulla értékét, a jobb alsó sarok nyolc értékét.

Miután egy játékos rákattint egy négyzetre a játék rácsában, egy másik játék elindításához szükséges parancsgomb, a cmdNewGame, "bekapcsolódik" azáltal, hogy láthatóvá válik. Ennek a parancsgombnak az állapota kettős feladatot jelent, mivel később logikai döntési változóként is használja. Egy tulajdonságérték mint döntési változó használata általában nem javasolt, mert ha valaha is szükségessé válik a program megváltoztatása (mondjuk például, hogy a cmdNewGame parancsgombot folyamatosan láthatóvá tegyük), akkor a program váratlanul kudarcot vall, mert lehet, hogy nem emlékszik arra, hogy a program logikájának részeként is használják. Ezért mindig jó ötlet keresni a programkódon, és ellenőrizni, hogy bármit megváltoztatott-e a program karbantartása során, akár tulajdonságértékeket is. Ez a program sérti a részben azért dönt, hogy ezt észrevegyük, részben azért, mert ez egy viszonylag egyszerű kóddarab, ahol könnyebben láthatjuk, hogy mit csinálunk, és elkerüljük a problémákat később.

A játékterület egy játékos általi kiválasztását úgy dolgozzák fel, hogy a GamePlay szubrutinot az Indexvel jelölik meg.

A Move feldolgozása

Először ellenőrizze, hogy nem volt-e üres négyzet kattintva.

Ha lblPlayGround (xo_Move) .Caption = "" Akkor

Ha biztosak vagyunk benne, hogy ez egy törvényes lépés, a mozgószámlálót (iMove) növelik. A következő két sor nagyon érdekes, mivel lefordítják a koordinátákat az egydimenziós If lblPlayGround komponens tömbből kétdimenziós indexekbe, amelyeket akár iXPos, akár iOPos esetén használhat. A Mod és az egész osztás (a 'visszajelzés') olyan matematikai műveletek, amelyeket nem használ minden nap, de itt egy nagyszerű példa látható, hogyan lehetnek nagyon hasznosak.

Ha lblPlayGround (xo_Move) .Caption = "" Akkor
iMove = iMove + 1
x = Int (xo_Move / 3) + 1
y = (xo_Move Mod 3) + 1

A xo_Move 0 értéke lefordul (1, 1), 1 - (1, 2) ... 3 - (2, 1) ... 8 - (3, 3) értékre.

Az sPlaySign-ban szereplő érték, amely modul hatókörrel rendelkezik, nyomon követi, hogy melyik játékos haladt. Miután a mozgó tömbök frissítésre kerültek, a játékrács címkekomponensei a megfelelő jelzéssel frissíthetők.

Ha sPlaySign = "O", akkor
iOPos (x, y) = 1
iWin = CheckWin (iOPos ())
Más
iXPos (x, y) = 1
iWin = CheckWin (iXPos ())
Vége If
lblPlayGround (xo_Move) .Caption = sPlaySign

Például, amikor az X-lejátszó rákattint a rács bal felső sarkára, a változók a következő értékekkel rendelkeznek:

A felhasználói képernyő csak az X-et jeleníti meg a bal felső mezőben, míg az iXPos-nak 1 van a bal felső mezőben, és 0 az összes többiben. Az iOPos-nak minden dobozában 0 van.

Az értékek megváltoznak, amikor az O játékos rákattint a rács középső négyzetére. Most az iOPos az 1-et jeleníti meg a középső mezőben, míg a felhasználói képernyő az X-et jeleníti meg a bal felső sarokban és egy O-t a középső mezőben. Az iXPos csak az 1-et jeleníti meg a bal felső sarokban, a 0 az összes többi mezőben.

Most, hogy tudja, hová kattintott egy játékos, és melyik játékos kattintott (az sPlaySign értékét használva), csak annyit kell tennie, hogy kiderítse, valakit nyert-e valami játék, és kitalálja, hogyan tudja ezt megmutatni a kijelzőn.

Győztes keresése

Minden egyes lépés után a CheckWin funkció ellenőrzi a nyertes kombinációt. A CheckWin úgy működik, hogy lebontja az egyes sorokat, az oszlopokat és az átlókat. A Visual Basic Debug szolgáltatásának segítségével a CheckWin-en keresztül végrehajtott lépések nyomon követése nagyon oktató lehet. A győzelem megkeresése első kérdés: ellenőrizni, hogy az iScore változó egyes ellenőrzéseinél megtaláltak-e három 1-t, majd visszatérni egy egyedi "aláírási" értéket Checkwin-ben, amelyet tömbindexként használnak a Visual tulajdonságának megváltoztatására. az egyik elem a linWin komponens tömbben. Ha nincs nyertes, akkor a CheckWin -1 értéket fog tartalmazni. Ha nyertes van, akkor a kijelző frissül, az eredménytáblát megváltoztatja, egy gratulációs üzenetet jelenít meg, és a játékot újraindítja.

Vizsgáljuk meg részletesen az egyik ellenőrzést, hogy megtudjuk, hogyan működik. A többi hasonló.

'Ellenőrizze a sorokat 3-ban
I = 1-től 3-ig
iScore = 0
CheckWin = CheckWin + 1
J = 1-től 3-ig
iScore = iScore + iPos (i, j)
Következő j
Ha iScore = 3, akkor
Kilépés a funkcióból
Vége If
Következő i

Az első dolog, amit észre kell venni, az első i indexszámláló visszaszámolja a sorokat, míg a második j számol az oszlopokon. A külső hurok ezután egyszerűen mozog az egyik sorról a másikra. A belső hurok számolja az 1-et az aktuális sorban. Ha három, akkor van nyertese.

Vegye figyelembe, hogy nyomon követheti a CheckWin változóban tesztelt négyzetek teljes számát is, amely az az érték, amelyet ez a funkció megszüntetésekor ad vissza. Minden nyerő kombináció egyedi értéke lesz a CheckWin-ben 0-tól 7-ig, amelyet a linWin () komponens tömb egyik elemének kiválasztására használnak. Ezért a CheckWin függvényben a kód sorrendje is fontos! Ha az egyik hurokkód blokkját elmozgatta (mint például a fenti), akkor hibás vonal húzódik a játékra, amikor valaki nyer. Próbáld ki és nézd meg!

Befejező részletek

Az egyetlen olyan kód, amelyet még nem tárgyaltak, az új játék szubrutinja és a szubrutin, amely visszaállítja a pontszámot. A rendszer többi logikája megkönnyíti ezek létrehozását. Új játék elindításához csak az InitPlayGround alprogramot kell felhívnia. A játékosok kényelme érdekében, mivel a gombra kattinthattak a játék közepén, kérjen megerősítést, mielőtt továbbmenne. Az eredménytábla újraindítása előtt megerősítést is kér.