Bygg en Intelligent Tic

Build en Intelligent Tic-Tac-Toe spill med AS3
8
Del
Del
Del

Dette Cyber mandag Envato Tuts + kurs vil bli redusert til bare $ 3. Ikke gå glipp av.

"Tic-Tac-Toe, det er kjedelig!" du kanskje tror. I denne opplæringen vil jeg vise deg at å bygge en Tic-Tac-Toe spill er alt annet enn kjedelig. Det er det ideelle spillet for å lage når du ønsker å lære Actionscript 3.0. Mens bygge det du vil lære mye om funksjoner og event lyttere, vil du se hvor enkelt det er å tilpasse grafikken i et spill, og du vil også lære å programmere Artificial Intelligence (AI)!



endelig resultat Forhåndsvisning

La oss ta en titt på det endelige resultatet vi skal jobbe mot:



Trinn 1: Forberedelser

vil begynne med å lage en ny Flash-fil ( fil > New > Flash-fil (Actionscript 3.0)
). Sett scenen dimensjoner til 300x300 og bruke en svart bakgrunn. I egenskapene ( Vindu > Properties
), fyll inn "TicTacToe" som klassedefinisjonen. Nå lagre filen i prosjektmappen (f.eks Desktop \\ MyFirstGame \\) som "TicTacToe.fla".

Deretter vil vi sette opp AS3-filer som vi skal bruke. Vi begynner med tre .as
filer, som vi også lagre i vår prosjektmappen. Skriv inn følgende kode og lagre filene under samme navn som klassenavnet. Så TicTacToe klassen du lagre som "TicTacToe.as", osv
pakke {import flash.display.MovieClip; public class TicTacToe strekker MovieClip {offentlig funksjon TicTacToe (): void {trace ( "TicTacToe"); }}} Pakke {import flash.display.MovieClip; public class Spill strekker MovieClip {offentlig funksjon Game (num: uint): void {trace ( "Spillet"); }}} Pakke {import flash.display.MovieClip; public class Tile strekker MovieClip {offentlig funksjon Tile (): void {trace ( "Tile"); }}}

Den første klasse, TicTacToe.as, vil være vår dokument klasse. Ikke sikker på hva dette betyr? Les denne rask innføring dokumentere klasser



Trinn 2:. Litt mer bakgrunns

Vi har nå fire filer i vårt prosjekt mappe: en FLA fil og tre .as filer. Når du teste din Flash movie ( Control > Test Movie
), vil du se en scene med en svart bakgrunn og "TicTacToe" i Output-skjermen ( Vindu > Output
). Flott, men hva skal vi gjøre med det?

TicTacToe.as filen vil håndtere vår meny funksjonalitet, som vi skal skrive på slutten av denne opplæringen (det er mer moro å få en fungerende spill så fort som mulig, ikke sant?). Menyen vil ha bare to knapper, en spiller eller to spillere.

Game.as filen vil håndtere spillet vårt. Dette er også grunnen til at vi ber om et argument "num"; dette vil definere antall menneskelige spillere. Vi vil begynne med to, men senere på vi ønsker også å skrive funksjonalitet for når det bare er én spiller. I dette tilfellet, må datamaskinen spille som spiller to.

Den siste filen, Tile.as, vi skal bruke til å lage en (du gjettet det), fliser. Fliser Jeg mener en av de ni stedene hvor du kan sette en O eller X (eller et bilde av en blomst, kjæledyret, en logo, you name it)



Trinn 3:. Grafikk Grid Lines

Vi begynner med å lage linjene. Du kan være så kreativ som du vil, men pass på at linjene ikke dele scenen inn i 9 like store blokker. Her er hva jeg gjorde: Jeg gjorde en ny MovieClip ( Sett > New Symbol
) og trakk 2 horisontale linjer og 2 vertikale linjer i lengde 300px. De horisontale linjene jeg satt på x = 0
og ( y = 100
|| y = 200
). De vertikale linjene jeg satt på ( x = 100
|| x = 200
) og y = 0
.

I biblioteket (< em> Vindu > Bibliotek
), høyreklikker du den nye MovieClip, gå til Egenskaper og kontroller boksen som sier "Export for Actionscript". Fyll ut "Grid" som klassedefinisjonen



Trinn 4:. Grafikk Fliser

Det neste vi skal gjøre O og X fliser. Du kan bruke hvilket som helst bilde du vil, men du bør holde en ting i tankene: vår grid deler scenen vår i 9 kvadratiske fliser av 100x100px, slik at hver flis bør ikke være større enn 100x100. Her er hva jeg gjorde: Jeg opprettet en ny MovieClip og gjorde en form med rektangelverktøyet på 100x100. Denne formen jeg justert slik at venstre toppen er registreringspunktet for MovieClip. Fyllfargen kan være noe, men setter den til alfa 0%. På denne måten fliser MovieClip er alltid 100x100 og du kan tegne det bildet du ønsker over 100x100 form.

Du kan slette 100x100 bakgrunnen etter at du trekke X og O form, men det burde egentlig ikke saken. Det er et lite spill, så det er ikke nødvendig å slette figurer med ytelse i tankene. Jeg synes det er lett å la dem være slik at jeg kan endre grafikken senere uten å miste retningen på hvor jeg kan plassere alt. Du må bare velge både grafikk (100x100 form og din egen grafikk) og justere dem til sentrum (sørg for Juster å iscenesette
er av), og du er ferdig.

Disse er de to movieclips jeg gjort. De to små egg på høyre er de endelige resultatene. Jeg vil ikke gå i detalj på hvordan å lage kule egg tall, er denne opplæringen om å skape spillet. Eksperimenter med din egen grafikk, og prøve ut nye ting som å bruke tidslinjen din MovieClip.

Eksport både movieclips for Actionscript på samme måte som du gjorde med Grid. Sørg for at du leverer førsteklasses HD navnene TileO Hotell og Tilex
. Vi har nå tre elementer i vårt bibliotek: Grid
, TileO Hotell og Tilex
. Vi trenger bare to mer før vi kan gjøre noen scripting



Trinn 5: Grafikk Highlighter

Som jeg sa, er vi nesten satt til å gjøre noen scripting, men vi trenger to mer grafikk. Når noen vinner spillet, ønsker vi ikke å starte et nytt spill med en gang, men heller se den vinnende linjen først. Til dette trenger vi en form for å plassere på toppen av flisen når flisen er en del av gevinstlinje. Jeg rett og slett skapt en hvit 100x100 form med alfa satt til 50%, men jeg vet at du kan gjøre bedre. Du kan lage en fin grønn v-tegn, et lykkelig smil, you name it. Eksportere MovieClip for Action med klassen definisjonen TileE plakater (E for "END", jeg har en ting om korte navn, og i et enkelt spill som dette vil du huske hva det står for) <. br>

det siste bildet du trenger for å lage er "knapp: fliser, som vi bruker alle hendelseslyttere i en flis igjen, skape en 100x100 form med alfa satt til 0% Sørg, som alle fliser grafikk.. vi skapt, at registreringen punktet er konfigurert til venstre kryss. Eksportere MovieClip for Action med klassen definisjonen TileB plakater (B for "knapp").

Vi har nå fem movieclips i vårt bibliotek som vi skal bruke til å bygge Tic-Tac-Toe spill



Trinn 6:.. nytt spill

Vi begynner sakte Gå til dokumentet klassen (TicTacToe.as) og gjelder følgende endringer:
pakke {import flash.display.MovieClip; public class TicTacToe strekker MovieClip {offentlig funksjon TicTacToe (): void {var spillet: spillet = new game (2); //Legg et nytt spill addChild (spill); //Legg spillet til visningslisten}}}

det er alt. Når vi nå teste Flash Movie, vil Output vinduet viser Spill
. Vi leverer to som et argument for Game () konstruktør fordi vi ønsker å begynne med å bygge spill for to spillere. Vi legger også spillet til visningslisten, men vil ikke se noe fordi spillet klassen bare inneholder spor uttalelse i øyeblikket



Trinn 7:.! Fliser

Vil være morsomt hvis dette var trinn 9, ville det ikke?

...

Uansett! Vi kommer til å legge flisene til spillet. Jeg vil legge til mye kode på en gang, og resultatet vil være at vi ikke vil se noe annet enn 9 spor med ordet "tile", men det er verdt det. Jeg vil forklare all kode, men prøv å lese og forstå det selv først
pakke {import flash.display.MovieClip.; import flash.events.Event; public class Spill strekker MovieClip {offentlig Var numPlayers: UINT; offentlig Var tur: UINT; privat Var _grid: Grid = new Grid (); private Var _tiles: Array = new Array (); offentlig funksjon Game (num: uint): void {numPlayers = num; slår = 0; addVisuals (); addTileListeners (); nextTurn (); } Private funksjon addVisuals (): void {var flis1: Fliser = new Tile (); Var tile2: Tile = new Tile (); Var tile3: Tile = new Tile (); Var tile4: Tile = new Tile (); Var tile5: Tile = new Tile (); Var tile6: Tile = new Tile (); Var tile7: Tile = new Tile (); Var tile8: Tile = new Tile (); Var tile9: Tile = new Tile (); tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0; tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100; tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200; addChild (flis1); addChild (tile2); addChild (tile3); addChild (tile4); addChild (tile5); addChild (tile6); addChild (tile7); addChild (tile8); addChild (tile9); addChild (_grid); _tiles.push (flis1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); } Private funksjon addTileListeners (): void {for (var i: int = 0; i < _tiles.length, jeg ++) {_tiles [i] .addEventListener ( "TILE_ACTIVE", nextTurn); }} Offentlig funksjon nextTurn (e: Handling = null): void {trace ( "! Neste turn"); slår + = 1; }}}

Som du kan se, først jeg lage noen variabler. numPlayers
variabel holder rede på hvor mange spillere det er å spille. Vi trenger dette senere når vi legger til AI. Samme gjelder for slå
variabel, som holder orden på hvem sin tur det er. Vi skaper også et _grid
, en forekomst av Grid symbol, som vi vil vise. Til slutt, _tiles
array vil holde orden på alle fliser.

Funksjoner er din venn, så jeg skrev en ny funksjon for å legge fliser, addVisuals () plakater ( du kan skrive all kode i konstruktør, men dette er ryddigere). I denne funksjonen, må vi først opprette ni nye fliser. x Hotell og y
posisjoner av flisene er satt på en slik måte at flisen vil bli plassert som en mobiltelefon tastaturet:
x = 0 x = 100 x = 200y = 0 flis1 tile2 tile3y = 100 tile4 tile5 tile6y = 200 tile7 tile8 tile9

Vi legger hver flis til visningslisten (som vi ikke vil se, fordi flisene ikke har grafikk ennå), og også presse den til _tiles
listen (i riktig rekkefølge, er dette svært viktig for AI /vinn sjekke senere). Den endelige addChild () kall er for nettet, som vi ønsker å bli plassert på toppen av alle fliser. Sist men ikke minst, legger vi hendelsen lyttere til alle fliser med funksjonen addTileListeners ()
. Arrangementet vi lytter til ikke finnes ennå, men vi vil sende den fra flisen klassen senere. Når hendelsen utløses, branner det funksjonen nextTurn
som vil håndtere svingene og se etter vinnende linjer. Selvfølgelig kaller vi nextTurn ()
funksjon i konstruktøren slik at vi kan begynne spillet



Trinn 8:. AI The Begin

Det er mulig å lage en svært kompleks AI system, men siden Tic-Tac-Toe er et ganske lite spill med begrensede muligheter, er det bedre å ta den enkle veien ut. Vi har lagt alle brikkene til _tiles
Array. Den første flisen ( flis1
) settes først, så det har index = 0
. Den andre fliser har index = 1
, etc. Hvis vi visualisere dette på skjermen, vil det se slik ut:
0 1 23 4 56 7 8

Her er hvordan vi skal sjekke om noen har tre på rad: vi lager en matrise av alle mulige kombinasjoner som du kan vinne. For eksempel 0 1 2
er en vinnende kombinasjon, og så er 1 4 7 Hotell og 2 4 6 plakater (diagonalt). Legg til følgende variable til Game.as
script:
private Var _combos: Array = new Array (new Array (0, 1, 2), ny Array (3, 4, 5), ny array (6, 7, 8), ny array (0, 3, 6), new Array (1, 4, 7), new Array (2, 5, 8), ny array (0, 4, 8), new Array (2, 4, 6));

senere vil vi se oversikt over alle O og X fliser i _tiles
Array. Når indeksene av, for eksempel de fire X-flisene er 0 4 5 Hotell og 8
, vi kan sjekke om en vinnende kombinasjon matcher disse indeksene. For eksempel er det en 0
, men ingen 1 Hotell og 2
, så X flisene ikke samsvarte med 0 1 2
vinnende kombinasjon. Vi vil gjøre dette for alle kombinasjoner, og til slutt se at kombinasjonen 0 4 8
har blitt gjort. Manuset til dette vil bli gitt noen få skritt senere



Trinn 9:. .. Fliser på Screen

Fikk å gjøre spøk tross alt!. Jeg kan skremme deg med følgende kode for Tile.as, men jeg skal spørre deg igjen: prøv å finne ut av det selv, og etter å lese mine kommentarer på koden. Det kan virke mye, men hvis du går gjennom den og lese kommentarene du vil forstå hvordan dette fungerer
pakke {import flash.display.MovieClip.; import flash.events.Event; import flash.events.EventDispatcher; import flash.events.MouseEvent; public class Tile strekker MovieClip {public Var ISSET: String; //Variabel å holde som spilleren klikket denne brikken privat Var tileB: TileB = new TileB (); privat Var tileE: TileE = new TileE (); privat Var tileO: TileO = new TileO (); privat Var tilex: tilex = new tilex (); offentlig funksjon Tile (): void {ISSET = "ikke satt"; //Flisen er fortsatt gratis for spillere å bruke tileO.visible = false; //Sett flisen synlighet for falsk tileX.visible = false; tileE.visible = false; addChild (tileO); //Legg grafikken i denne rekkefølgen! addChild (Tilex); addChild (tileE); addChild (tileB); //Button må være på topp addButtonListeners (); //Funksjon for å legge lytte} offentlig funksjon addButtonListeners (): void //Public, som vi ønsker å bruke den fra spillet klassen senere {this.buttonMode = true; tileB.addEventListener (MouseEvent.MOUSE_OVER, showGraphic); tileB.addEventListener (MouseEvent.MOUSE_OUT, hideGraphic); tileB.addEventListener (MouseEvent.CLICK, chooseGraphic); } offentlig funksjon removeButtonListeners (): void //Public, som vi ønsker å bruke den fra spillet klassen senere {this.buttonMode = false; tileB.removeEventListener (MouseEvent.MOUSE_OVER, showGraphic); tileB.removeEventListener (MouseEvent.MOUSE_OUT, hideGraphic); tileB.removeEventListener (MouseEvent.CLICK, chooseGraphic); } Private funksjon showGraphic (e: Mouseevent): void {if (Game (this.parent) Drei% 2 == 0) {//slår% 2 er alltid enten 0 eller 1: 0% 2 = 0, 1% 2 = 1, 2% 2 = 0, 3% 2 = 1 osv tileO.visible = true; //Det er O tur, vise O grafisk} else {tileX.visible = true; //Det er X sin tur viser X grafisk}} private funksjon hideGraphic (e: Mouseevent): void {tileO.visible = false; //Hide grafikken tileX.visible = false; //For både O og X} private funksjon chooseGraphic (e: Mouseevent): void {removeButtonListeners (); //Fjern lytterne (denne brikken er nå deaktivert) ISSET = (Game (this.parent) .Vri% 2 == 0)? "OKSE"; //Sett ISSET variabelen til O eller X trace (isset); dispatchEvent (ny hendelse ( "TILE_ACTIVE")); //Dispatch tilfelle}}}

Har du allerede teste den? Fordi hvis alt gikk bra, vil du se en fungerende spill nå! La oss diskutere manus til litt.

Vi starter med å lage all grafikken. Hver og en av de ni flisene har TileB, TileE, tilex og TileO grafisk. I konstruktøren ( offentlig funksjon Tile ()
) vi legger disse grafikk til visningslisten og sette synligheten til false. Bare TileB grafisk forblir på synlig = true
, fordi vi ønsker å legge til våre hendelsen lyttere til denne grafikken. Ikke noe problem; det er derfor vi setter alfa til 0%.

Både addButtonListeners () og removeButtonListeners () funksjoner taler for seg. Når vi plasserer musen over en flis, ønsker vi den riktige grafikken skal vises. Når vi beveger musen ut av en flis, ønsker vi å skjule grafikken. Når vi klikker, ønsker vi å vise grafikk og holde det synlig slik at den neste spilleren kan spille. Vi gjør dette med modulo operatør

I databehandling, finner modulo drift resten av delingen av ett nummer av en annen -.. Wikipedia

Når vi klikker flisen, chooseGraphic (e: Mouseevent)
funksjon utløser. I denne funksjonen fjerner vi alle lyttere, sett ISSET
variabel (spore den) og fyre av TILE_ACTIVE
hendelsen. Neste trinn: Sjekk hvem som vant



Trinn 10:! Good Game

La oss begynne enkelt: legge følgende skript til Tile.as fil for å håndtere en vinnende situasjon:
offentlig funksjon showEnd (): void {//lagt vise den tileE tileE.visible = true;}

Easy riktig? Det er en offentlig funksjon, slik at vi kan kalle det fra Spill
klasse, og alt den gjør er satt synligheten av tileE
til sann. Nå åpner opp Game.as
igjen og gjør deg klar for noen alvorlige scripting. Vi vil legge til en variabel, redigere nextTurn ()
funksjon og legge til to nye funksjoner:
pakke {import flash.display.MovieClip; import flash.events.Event; public class Spill strekker MovieClip {offentlig Var numPlayers: UINT; offentlig Var tur: UINT; offentlig Var venstre: uint = 10; //Lagt å holde styr på gratis fliser; 10 fordi vi gjør -1 en gang uten å merke en flis privat Var _grid: Grid = new Grid (); private Var _tiles: Array = new Array (); private Var _combos: Array = new Array (new Array (0, 1, 2), ny Array (3, 4, 5), ny Array (6, 7, 8), ny Array (0, 3, 6), ny array (1, 4, 7), new Array (2, 5, 8), ny array (0, 4, 8), new Array (2, 4, 6)); offentlig funksjon Game (num: uint): void {numPlayers = num; slår = 0; addVisuals (); addTileListeners (); nextTurn (); } Private funksjon addVisuals (): void {var flis1: Fliser = new Tile (); Var tile2: Tile = new Tile (); Var tile3: Tile = new Tile (); Var tile4: Tile = new Tile (); Var tile5: Tile = new Tile (); Var tile6: Tile = new Tile (); Var tile7: Tile = new Tile (); Var tile8: Tile = new Tile (); Var tile9: Tile = new Tile (); tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0; tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100; tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200; addChild (flis1); addChild (tile2); addChild (tile3); addChild (tile4); addChild (tile5); addChild (tile6); addChild (tile7); addChild (tile8); addChild (tile9); addChild (_grid); _tiles.push (flis1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); } Private funksjon addTileListeners (): void {for (var i: int = 0; i < _tiles.length, jeg ++) {_tiles [i] .addEventListener ( "TILE_ACTIVE", nextTurn); }} Offentlig funksjon nextTurn (e: Handling = null): (! CheckWin ()) void {if {//Bare hvis checkWin funksjonen returnerer false, fortsetter venstre - = 1; //Noen valgte en flis så det er en mindre igjen å velge mellom hvis (venstre > 0) {//mens det er fliser igjen ... slå + = 1; //Legg en til turn (neste spiller er opp)} else {Endgame (); //Else avslutte spillet (det er uavgjort)}}} private funksjon checkWin (): Boolean {var vunnet: Boolean = false; //Først satt en boolsk til false for hver (var kombi: Array i _combos) {//For hver combi (array) i vår _combos rekke Var xwin = true; //Anta x vant Var owin = true; //Anta o vunnet for hver (var flis: int i kombi) {//For hver flis indeks (antall) i vår kombi rekke xwin = xwin & & _tiles [flis] .isSet == "X"; //Sett xwin og owin å true, men bare når det er en X eller O owin = owin & & _tiles [flis] .isSet == "O"; //Med samme indeks som antall i kombi matrise} if (xwin || owin) {//Hvis enten xwin eller owin er sant Endgame (kombi); //Avslutte spillet (levere kombi) vant = true; //Set vant til sann break; //Bryt ut av loopen} else {vunnet = false (viktig det er en vinnende kombinasjon, så ingen flere sjekker nødvendig!); //Else sett vant til false (ingen kombinasjon ennå)}} avkastning vunnet; //Return vant} private funksjon Endgame (kombi: Array = null): void {for (var i: int = 0; i < _tiles.length; i ++) {//For hver flis i flisene Array _tiles [i] .removeButtonListeners (); //Fjern lytterne if (kombi) {//Hvis det er en kombi følger med (noen vunnet) for hver (var j: int i kombi) {//Sjekk hvert nummer i at kombi ... if (i == j ) _tiles [i] .showEnd (); //Og markere tilsvarende flis med showEnd ()}}}}}}

Vi begynner med forlot
variabel. Når dette går i null, betyr det at det ikke er flere brikker igjen og spillet er over. Vanligvis betyr dette en uavgjort

Neste er opp nextTurn (e: Handling = null).
Funksjon, som først hadde bare slå + = 1
i den. Som du kan se, har det nå flere forhold. Hver gang funksjonen kalles, sjekker vi om noen har vunnet. Hvis ikke, vet vi at det er en flis mindre å velge mellom, så vi gjør igjen - = 1
. Så lenge det er fliser igjen, kan vi la den andre spilleren gjøre hans /hennes trekk. Ingen flere fliser igjen betyr slutten av spillet (uavgjort, siden vi bare nå denne delen av skriptet hvis det ikke var en vinnende situasjon ennå).

checkWin ()
funksjon forklares best med et eksempel. La oss ta følgende situasjon:
flis1 = X flis 4 = Otile2 = X flis 5 = Otile3 = X

flis1 har hovedside 0
i _tiles
Array. Den første for hver
uttalelse sjekker alle Arrays nestet inne i _combos
Array. Den første inneholder "0 1 2". Den andre for hver
utsagn håndterer disse tallene (som representerer indeksene på flisene). Dette er hva som skjer i den andre for hver
utsagn:
første kombinasjons = 0 1 2 første pass _tiles [0] .isSet = Xvar flis = 0xwin (true) = xwin (true) & & _tiles [0] .isSet == X (true) owin (flase) = owin (true) & & _tiles [0] .isSet == O (falsk) - andre pass _tiles [1] .isSet = Xvar flis = 1xwin (true) = xwin (true) & & _tiles [1] .isSet == X (true) owin (flase) = owin (falsk) & & _tiles [1] .isSet == O (falsk) - tredje passet _tiles [2] .isSet = Xvar flis = 2xwin (true) = xwin (true) & & _tiles [2] .isSet == X (true) owin (flase) = owin (falsk) & & _tiles [2] .isSet == O (false)

Som du ser, når den andre for hver
uttalelsen er fullført, xwin vil være sanne og owin vil være falsk. Dette utløser hvis
statement og oppfordrer til Endgame (kombi: Array = null)
funksjon. Med den leverer det den vinnende kombinasjon som vi skal bruke i funksjonen. checkWin ()
funksjonen returnerer en sann eller falsk, som jeg forklarte tidligere.

Endgame ()
funksjon er lett å forstå. Først, for hver flis i _tiles
Array, deaktiverer vi hendelsen lyttere. Vi sjekker også om det er en kombinasjon som følger med (som betyr noen vunnet i stedet for uavgjort). Hvis dette er tilfelle, kan vi sjekke hvilke fliser var en del av kombinasjonen og ringe showEnd ()
funksjon på de brikkene. Dette vil vise 'TileE' grafisk.



Milestone 1

Vi har nå et fungerende spill. For kilden til alt vi gjorde så langt, sjekk _milestone1.zip
. Resultater



Trinn 11:! AI Funksjoner

Jeg håper du ikke forvirret av all scripting vi gjorde så langt. vi vil gå videre med AI delen av spillet, noe som krever enkelte funksjoner. Først, la oss gjøre noen endringer og legge til funksjonen for å legge til AI. I TicTacToe.as
, endre følgende linje:
Var spillet: spillet = new Game (1); //Endret antall menneskelige spillere til en

Neste, i Game.as
, legge til følgende variabler:
privat Var _xlist: Array = new Array (); //Holde styr på alt x tilesprivate Var _olist: Array = new Array (); //Holde styr på alle o tilesprivate Var _flist: Array = new Array (); //Holde styr på alle gratis fliser

i addVisuals ()
funksjon, legge til følgende linje (etter at du skyver flisene til _tiles
Array):
_flist .push (flis1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); //Lagt alle brikkene til frilisten

Deretter endrer nextTurn (e: Handling = null)
funksjon i følgende:
offentlig funksjon nextTurn (e: Handling = null): void { if (! checkWin ()) {if (e) {//lagt sjekk for en hendelse (vi kaller funksjonen en gang uten å merke en flis) if (e.currentTarget.isSet == "X") {//hvis flisen er innstilt på X _xlist.push (e.currentTarget); //Legge den til X liste} if (e.currentTarget.isSet == "O") {//hvis flisen er satt til O _olist.push (e.currentTarget); //Legge det til O-liste} _flist.splice (_flist.indexOf (e.currentTarget), 1); //Fjerne flis fra frilisten} venstre - = 1; if (venstre > 0) {slå + = 1; if (slår% 2 == 0 & & numPlayers == 1) handleAI (); //Sjekke om PC-en skal velge en flis} else {Endgame (); }}}

Selvfølgelig også legge til handleAI ()
funksjonen til Game.as
klasse:
privat funksjon handleAI (): void {trace (_xlist); trace (_olist); trace (_flist);}

Når vi nå teste Flash-film, etter vår første tur ser vi de tre listene i vår Output-vinduet. _xlist
vil være ett element lang (du plukket en flis for å markere). _olist
er tom (spiller to ikke plukke en flis ennå) og _flist
er åtte elementer lang (det er åtte fliser igjen å velge mellom). Vi vil bruke disse listene i neste trinn å la AIen velge en flis



Trinn 12:.? AI Hvordan Smart

Det er mange måter å script oppførselen til computer. Som du sikkert vet, hvis begge spillerne oppmerksomme og kjenner reglene, et spill av Tic-Tac-Toe alltid ender i uavgjort. Vi kan rett og slett script alle situasjoner, slik at resultatet alltid er uavgjort eller seier for datamaskinen. Men hva er moroa i det? Jeg velger å lage en AI som ikke er smart, men er ikke dum heller. Dette er reglene vi skal skrive:

for hver gratis flis, velge det hvis denne brikken pluss alle allerede valgt O-brikker vinner spillet

for hver gratis fliser, velge det hvis denne brikken pluss alle allerede valgt X-brikker vinner spillet

ellers plukke en tilfeldig gratis flis

Så datamaskinen først bør du sjekke om det kan vinne spillet. Hvis datamaskinen ikke kan vinne med denne gratis fliser, bør det sjekke om menneskelig spiller kan vinne med denne brikken. Når verken datamaskin eller menneskelig spiller kan vinne, det bør velge en tilfeldig flis. Vi kan gjøre det tenke fremover, og i stedet for å plukke en tilfeldig brikke la den velge mellom flisene som det gjør det mulig å vinne neste runde. Men igjen, vi vil ikke gjøre det fordi det ville gjøre spillet ganske kjedelig



Trinn 13:. AI Aktivere Fliser

Det blir ikke noe enklere enn dette trinnet . Vi må aktivere flisene slik at maskinen kan merke dem. Normalt, når vi spiller med to spillere, blir musen brukes til å utløse swap i grafikk og sende hendelsen som setter sin tur til pluss én. Fordi datamaskinen ikke bruker MouseEvents, må vi endre to funksjoner i Tile.as
slik at de kan brukes fra Game.as
fil. Disse er disse funksjonene:
offentlig funksjon showGraphic (e: Mouseevent = null): void //Endret til offentlig og sette Mouseevent å nullpublic funksjon chooseGraphic (e: Mouseevent = null): void //Endret til offentlig og sette Mouseevent til null

på denne måten kan vi kalle funksjonene showGraphic () Hotell og chooseGraphic () plakater (fordi de er offentlige) uten tilførsel av en Mouseevent (fordi hvis det ikke er levert, vi leverer null)



Trinn 14:. AI script

La oss skrive manuset for AI nå. Dette er hva du Game.as
filen skal se ut. Jeg har skrevet kommentarer ved siden av hver linje jeg endret
pakke {import flash.display.MovieClip.; import flash.events.Event; import flash.events.TimerEvent; //Vi bruker nå en timer event import flash.utils.Timer; //Og også en tidtaker public class Spill strekker MovieClip {offentlige Var numPlayers: UINT; offentlig Var tur: UINT; offentlig Var venstre: uint = 10; privat Var _grid: Grid = new Grid (); private Var _tiles: Array = new Array (); private Var _combos: Array = new Array (new Array (0, 1, 2), ny Array (3, 4, 5), ny Array (6, 7, 8), ny Array (0, 3, 6), ny array (1, 4, 7), new Array (2, 5, 8), ny array (0, 4, 8), new Array (2, 4, 6)); privat Var _xlist: Array = new Array (); privat Var _olist: Array = new Array (); privat Var _flist: Array = new Array (); privat Var _choose: Boolean = false; //Lagt variabel for å kontrollere om maskinen har gjort et valg offentlig funksjon Game (num: uint): void {numPlayers = num; slår = 0; addVisuals (); addTileListeners (); nextTurn (); } Private funksjon addVisuals (): void {var flis1: Fliser = new Tile (); Var tile2: Tile = new Tile (); Var tile3: Tile = new Tile (); Var tile4: Tile = new Tile (); Var tile5: Tile = new Tile (); Var tile6: Tile = new Tile (); Var tile7: Tile = new Tile (); Var tile8: Tile = new Tile (); Var tile9: Tile = new Tile (); tile1.x = tile4.x = tile7.x = tile1.y = tile2.y = tile3.y = 0; tile2.x = tile5.x = tile8.x = tile4.y = tile5.y = tile6.y = 100; tile3.x = tile6.x = tile9.x = tile7.y = tile8.y = tile9.y = 200; addChild (flis1); addChild (tile2); addChild (tile3); addChild (tile4); addChild (tile5); addChild (tile6); addChild (tile7); addChild (tile8); addChild (tile9); addChild (_grid); _tiles.push (flis1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); _flist.push (flis1, tile2, tile3, tile4, tile5, tile6, tile7, tile8, tile9); } Private funksjon addTileListeners (): void {for (var i: int = 0; i < _tiles.length, jeg ++) {_tiles [i] .addEventListener ( "TILE_ACTIVE", nextTurn); }} Offentlig funksjon nextTurn (e: Handling = null): (! CheckWin ()) void {if {if (e) {if (e.currentTarget.isSet == "X") {_xlist.push (e.currentTarget); } If (e.currentTarget.isSet == "O") {_olist.push (e.currentTarget); } _flist.splice (_flist.indexOf (E.currentTarget), 1); } Venstre - = 1; if (venstre > 0) {slå + = 1; if (slår% 2 == 0 & & numPlayers == 1) handleAI (); } Else {Endgame (); }}} Private funksjon handleAI (): void {_choose = false; //Datamaskinen klarte ikke velge en flis ennå for (var i: int = 0; i < _flist.length; i ++) {_flist [i] .removeButtonListeners (); //Fjern alle lyttere på gratis flisene slik menneske ikke kan spille} Var timer: Timer = new Timer (500, 1); //Sett en timer (gjør det ser ut som datamaskinens tenker "for et halvt sekund) timer.addEventListener (TimerEvent.TIMER_COMPLETE, handleAIChoice); //Legg en lytter til timeren timer.start (); //Start tidtakeren} private funksjon handleAIChoice (e: Timerevent): void {var i: int; for (i = 0; i < _flist.length; i ++) {if (_choose!) {//Hvis datamaskinen ikke gjøre et valg ennå Var ocheck: Array = _olist.concat (); //Lag en kopi av den _olist Var xcheck: Array = _xlist.concat (); //Lag en kopi av den _xlist ocheck.push (_flist [i]); //Legg til en gratis flis til ocheck rekke xcheck.push (_flist [i]); //Legg til en gratis flis til xcheck rekke if (checkAIWin (ocheck)) break; //Sjekk om med gratis flis, o vinner (denne funksjonen legger også flisen, i så fall) if (checkAIWin (xcheck)) break; //Sjekk om med gratis flis, vinner x}} if (_choose!) {//Hvis datamaskinen ikke plukke en flis ennå (ingen seier mulig for x eller o) trace ( "Pick tilfeldig spot"); Var flis: int = Math.floor (Math.random () * _flist.length); //Plukk en tilfeldig indeks _flist [flis] .showGraphic (); //Sett flisen med tilfeldig indeks som viser grafisk _flist [flis] .chooseGraphic (); gå i stykker; import flash.events.Event; import flash.events.MouseEvent; addChild (spill);