Denne opplæringen er den siste delen i prosessen med å kode et hockeyspill ved hjelp av styringsadferd og finite state maskiner. Her vil vi forbedre våre idrettsutøverees kunstige intelligens for å tillate dem å forsvare sitt mål mot sine motstandere. Vi vil også få våre idrettsutøvere til å utføre noen angrepstaktikk mens de forsvarer, slik at de kan gjenopprette pucken og si opp motstandernes offensiv.
I et konkurransedyktig spill som hockey, er forsvarsprosessen mye mer enn å rushing til lagets målområde for å hindre motstanderen i å score. Forhindre motstanderen å score er bare en av de mange oppgavene som er involvert.
Hvis et lag fokuserer på scoreforebygging taktikk alene, vil alle idrettsutøvere bli bare hindringer underveis. Motstanderen vil fortsette å skyve, forsøker å finne et sted i forsvarsformasjonen. Det vil ta tid, men til slutt vil motstanderen score.
Forsvarsprosessen er en blanding av defensive og støtende handlinger. Den beste måten å si opp motstanders angrep, som er forsvarsmålet, er å angrep mens du forsvarer. Det kan høres litt forvirrende, men det gir perfekt mening.
En idrettsutøver som forsvarer lagene hans, bør bevege seg mot hans mål, og hindrer motstanderen i å score. Underveis må han prøve å stjele pucken fra motstanderen som bærer den, eller fange pucken når den utveksles blant motstanderne. Det er akkurat hva denne opplæringen vil forsøke å implementere: en defensiv taktikk med angrepshandlinger.
For å oppnå en defensiv atferd som har noen angrepsspekter i den, legger vi til to nye stater til AI-finite-state-maskinen:
En stabelbasert, finite state machine som representerer angrepet og forsvarsprosessene ...De forsvare
Staten vil være fundamentet i forsvarsprosessen. I den tilstanden vil idrettsutøvere bevege seg mot sin side av rinken, og prøver alltid å gjenopprette pucken for å si opp motstandernes offensiv.
De patrulje
staten vil supplere forsvarsprosessen. Det forhindrer at idrettsutøvere står stille når de når sin forsvarsposisjon i rinken. Denne tilstanden vil holde atleter beveger og patruljerer området, noe som vil gi et mer overbevisende resultat.
De forsvare
Staten er basert på en veldig enkel idé. Når den er aktiv, vil hver idrettsutøver bevege seg mot sin opprinnelige posisjon i rinken. Vi har allerede brukt denne stillingen, beskrevet av mInitialPosition
eiendom i Atlet
klasse, for å implementere prepareForMatch
angi i den første opplæringen i denne serien.
Mens han beveger seg mot sin opprinnelige posisjon, vil en idrettsutøver prøve å utføre noen angrepshandlinger mot motstanderen hvis han er nær nok og bærer pucken. For eksempel, hvis atleten beveger seg og motstanderens leder (den med pucken) blir nabo, blir den forsvare
staten vil bli erstattet med noe mer passende, for eksempel stealPuck
stat.
Siden idrettsutøvere pleier å være spredt gjennom hele rinken mens de angriper, når de bytter til forsvare
og begynner å gå tilbake til sin opprinnelige posisjon, de vil dekke et betydelig område, noe som sikrer et overbevisende forsvarsmønster:
Noen idrettsutøvere vil ikke møte motstandere underveis, så de vil bare bevege seg mot sin opprinnelige posisjon. Andre idrettsutøvere kan imidlertid komme nærmere noen interessante motstandere, som lederen (den som bærer pucken).
De forsvare
staten vil ha fire overganger:
Tre av dem, laget har pucken
, nær motstanderens leder
, og Puck har ingen eier
, er relatert til angrep handlinger. De vil være ansvarlige for at utøvere ser ut som de angriper motstandere mens de beveger seg for å forsvare lagets mål. De i posisjon
Overgang vil bli utløst når idrettsutøveren endelig kommer til sin opprinnelige posisjon i rinken.
Det første trinnet i implementeringen av forsvare
tilstand er å gjøre atleten bevege seg mot sin opprinnelige posisjon. Siden han må tregere seg når han kommer nærmere destinasjonen, er ankommerstyringsadferansen perfekt tilpasning:
klasse idrettsutøver // (...) privat funksjon forsvare (): void var aPuckOwner: Athlete = getPuckOwner (); // Flytt mot startposisjonen, ankommer det jevnt. mBoid.steering = mBoid.steering + mBoid.arrive (mInitialPosition); // Har pucken en eier? hvis (aPuckOwner! = null) // Ja, den har. Hvem har det? hvis (doesMyTeamHasThePuck ()) // Mitt lag har pucken, tiden til å slutte å forsvare og begynne å angripe! mBrain.popState (); mBrain.pushState (angrep); annet hvis (Utils.distance (aPuckOwner, dette) < 150) // An opponent has the puck and he is close to us! // Let's try to steal the puck from him. mBrain.popState(); mBrain.pushState(stealPuck); else // No, the puck has no owner, it is running in the rink. // There is no point to keep defending the goal, because nobody has the puck. // Let's switch to 'pursuePuck' and try to get the puck to our team. mBrain.popState(); mBrain.pushState(pursuePuck); // (… )
Angrepets oppførsel vil skape en kraft som vil presse utøveren mot sin opprinnelige posisjon (mInitialPosition
) mens forsvare
tilstanden er aktiv. Etter ankommet kraftberegning, i denne koden, kjører vi en rekke tester som kontrollerer puckens eierskap og nærhet til motstandere, popper på forsvare
Stat fra hjernen og trykk på en ny i henhold til situasjonen.
Hvis pucken ikke har noen eier, går det nok fritt i rinken. I så fall er det pursuePuck
Stat vil bli skjøvet inn i hjernen (linje 29). Hvis pucken har en lagseier, betyr det at forsvarsprosessen er over, og det er på tide å angripe (linje 16). Endelig hvis puckens eier tilhører motstanderslaget og han er nær nok, stealPuck
vil bli skjøvet inn i hjernen (linje 22).
Resultatet er et lag som kan forsvare sitt mål, forfølge og forsøke å stjele pucken fra motstanderen som bærer den. Nedenfor er en demonstrasjon av dagens forsvare implementering:
Den nåværende forsvarsadfærden er akseptabel, men den kan bli tweaked litt for å være mer overbevisende. Hvis du analyserer tidligere demonstrasjon, kan du til slutt merke til at idrettsutøvere vil stoppe og stå stille etter at de når sin opprinnelige posisjon mens de forsvarer.
Hvis en idrettsutøver returnerer til sin opprinnelige posisjon uten å møte noen motstandere underveis, vil han forbli stille til en motstander med pucken går forbi eller laget gjenoppretter pucken.
Vi kan forbedre denne oppførselen ved å legge til en patrulje
stat, som blir presset inn i hjernen av forsvare
angi når idrettsutøveren når sin opprinnelige posisjon:
De patrulje
staten er ekstremt enkel. Når det er aktivt, vil det gjøre atleter flyttet tilfeldig i en kort stund, som visuelt etterligner forventet oppførsel fra en idrettsutøver som forsøker å forsvare et sted i rinken.
Når avstanden mellom utøveren og hans opprinnelige posisjon er grater enn 10
, for eksempel, patrulje
popper seg fra hjernen og presser forsvare
. Hvis idrettsutøveren kommer til sin første posisjon igjen mens han forsvarer, patrulje
blir presset en gang til i hjernen og prosessen gjentar:
Det tilfeldige bevegelsesmønsteret som kreves av patrulje
tilstanden kan lett oppnås med vandringsstyreadferansen. Gjennomføringen av patrulje
tilstand er:
klasse idrettsutøver // (...) privat funksjon patrulje (): void mBoid.steering = mBoid.steering + mBoid.wander (); // Er jeg for langt unna min første posisjon? hvis (Utils.distance (mInitialPosition, this)> 10) // Ja, jeg er. Det er på tide å stoppe patruljering og gå tilbake til // min første posisjon. mBrain.popState (); mBrain.pushState (forsvare); // (...)
Avstandskontrollen (linje 8) sikrer at utøveren skal patruljere et lite område rundt sin opprinnelige posisjon i stedet for å forlate sin opprinnelige forsvarsposisjon helt uten tilsyn.
Resultatene av bruk av patrulje
staten er en mer overbevisende atferd:
Under gjennomføringen av stealPuck
tilstand i den forrige opplæringen, var det en situasjon der idrettsutøvere skulle bytte til forsvare
stat. Men den staten ble ikke implementert da.
Mens du prøver å stjele pucken ( stealPuck
tilstand), hvis motstanderen er for langt borte fra utøveren, er det meningsløst å fortsette å prøve å stjele pucken. Det beste alternativet i den situasjonen er å poppe stealPuck
stat og trykk forsvare
, håper at en lagkamerat vil være nærmere motstanderens leder for å stjele pucken.
De stealPuck
Staten må endres (linjer 28 og 29) for å tillate idrettsutøvere å presse forsvare
stat i den situasjonen:
klasse idrettsutøver // (...) privat funksjon stealPuck (): void // Har pucken noen eier? hvis (getPuckOwner ()! = null) // Ja, den har, men hvem har den? hvis (doesMyTeamHasThePuck ()) // Mitt team har pucken, så det er på tide å slutte å prøve å stjele // pucken og begynne å angripe. mBrain.popState (); mBrain.pushState (angrep); else // En motstander har pucken. var aOpponentLeader: Atlet = getPuckOwner (); // Er motstanderen med pucken nær meg? hvis (Utils.distance (aOpponentLeader, dette) < 150) // Yeah, he is close! Let's pursue him while mantaining a certain // separation from the others to avoid that everybody will ocuppy the same // position in the pursuit. mBoid.steering = mBoid.steering + mBoid.pursuit(aOpponentLeader.boid); mBoid.steering = mBoid.steering + mBoid.separation(50); else // No, he is too far away. Let's switch to 'defend' and hope // someone closer to the puck can steal it for us. mBrain.popState(); mBrain.pushState(defend); else // The puck has no owner, it is probably running freely in the rink. // There is no point to keep trying to steal it, so let's finish the 'stealPuck' state // and switch to 'pursuePuck'. mBrain.popState(); mBrain.pushState(pursuePuck); // (… )
Etter oppdatering av stealPuck
staten, er idrettsutøvere nå i stand til å organisere angrep og forsvar taktikk, slik at to AI-kontrollerte lag kan spille mot hverandre.
Resultatet er vist nedenfor:
I denne opplæringen implementerte vi en forsvarsstrategi som brukes av idrettsutøvere til å forsvare sine mål fra motstandere. Vi forbedret da forsvare
stat ved å legge til noen angrep handlinger, for eksempel å forsøke å stjele motstanderens puck, noe som gjorde forsvaret taktikken føles mer naturlig og overbevisende.
Vi forbedret også følelsen av forsvarsadferdelsen ved å legge til en ekstremt enkel, men kraftig tilstand, den patrulje
. Tanken er å forhindre atleter fra å stå stille mens de forsvarer lagets mål.
Og med det har vi opprettet et fullt AI-system for vårt hockey-spill!