Mängu AI loomine: juhend algajatele

Mängu AI loomine: juhend algajatele

Leidsin huvitava materjali tehisintellekti kohta mängudes. Lihtsate näidete abil selgitatakse tehisintellekti põhitõdesid ning sees on palju kasulikke tööriistu ja meetodeid selle mugavaks arendamiseks ja kujundamiseks. Seal on ka see, kuidas, kus ja millal neid kasutada.

Suurem osa näidetest on kirjutatud pseudokoodis, seega pole programmeerimisalaseid teadmisi vaja. Lõike all on 35 lehte teksti piltide ja gifidega, nii et ole valmis.

UPD. Vabandan, kuid olen selle artikli Habré kohta juba omaenda tõlke teinud PatsientZero. Saate lugeda tema versiooni siin, kuid millegipärast läks artikkel minust mööda (kasutasin otsingut, aga midagi läks valesti). Ja kuna kirjutan mängude arendamisele pühendatud ajaveebi, otsustasin jätta oma tõlkeversiooni tellijate jaoks (mõned punktid on erinevalt vormindatud, mõned jäeti arendajate nõuandel teadlikult välja).

Mis on AI?

Mängu tehisintellekt keskendub sellele, milliseid toiminguid objekt peaks tegema, lähtudes selle asukoha tingimustest. Seda nimetatakse tavaliselt "intelligentse agendi" juhtimiseks, kus agent on mängija tegelane, sõiduk, bot või mõnikord midagi abstraktsemat: terve üksuste rühm või isegi tsivilisatsioon. Igal juhul on see asi, mis peab nägema oma keskkonda, tegema selle põhjal otsuseid ja tegutsema vastavalt sellele. Seda nimetatakse tunne/mõtle/tegutse tsükliks:

  • Tunne: agent leiab või saab teavet oma keskkonnas olevate asjade kohta, mis võivad tema käitumist mõjutada (läheduses olevad ohud, kogutavad esemed, huvitavad kohad, mida uurida).
  • Mõelge: agent otsustab, kuidas reageerida (mõtleb, kas esemete kogumine on piisavalt ohutu või peaks ta enne võitlema/varjama).
  • Tegutsemine: agent sooritab toiminguid eelmise otsuse elluviimiseks (hakkab liikuma vaenlase või objekti poole).
  • ...nüüd on olukord tegelaste tegevuse tõttu muutunud, nii et tsükkel kordub uute andmetega.

AI kipub keskenduma ahela Sense osale. Näiteks autonoomsed autod pildistavad teed, kombineerivad neid radari ja lidari andmetega ning tõlgendavad neid. Tavaliselt teeb seda masinõpe, mis töötleb sissetulevaid andmeid ja annab neile tähenduse, eraldades semantilist teavet, näiteks „teist 20 jardi ees on teine ​​auto”. Need on nn klassifitseerimisprobleemid.

Mängud ei vaja teabe hankimiseks keerulist süsteemi, kuna suurem osa andmetest on juba selle lahutamatu osa. Ei ole vaja käivitada pildituvastusalgoritme, et teha kindlaks, kas vaenlane on ees – mäng juba teab ja suunab teabe otse otsustusprotsessi. Seetõttu on tsükli Sense osa sageli palju lihtsam kui mõtle ja tegutse osa.

Mängu AI piirangud

AI-l on mitmeid piiranguid, mida tuleb järgida:

  • AI-d ei pea eelnevalt koolitama, nagu oleks see masinõppe algoritm. Pole mõtet kirjutada arenduse käigus närvivõrku, et jälgida kümneid tuhandeid mängijaid ja õppida nende vastu parimat viisi. Miks? Sest mäng pole välja antud ja mängijaid pole.
  • Mäng peaks olema lõbus ja väljakutseid pakkuv, nii et agendid ei peaks leidma inimeste vastu parimat lähenemist.
  • Agendid peavad välja nägema realistlikud, et mängijad tunneksid, et nad mängivad päris inimeste vastu. AlphaGo programm edestas inimesi, kuid valitud sammud olid väga kaugel tavapärasest mängust. Kui mäng simuleerib inimvastast, siis seda tunnet ei tohiks olla. Algoritmi tuleb muuta nii, et see teeks pigem usutavaid kui ideaalseid otsuseid.
  • AI peab töötama reaalajas. See tähendab, et algoritm ei saa otsuste tegemiseks pikka aega CPU kasutamist monopoliseerida. Isegi 10 millisekundit on liiga pikk aeg, sest enamik mänge vajab kogu töötlemiseks ja järgmise graafikakaadri juurde liikumiseks vaid 16–33 millisekundit.
  • Ideaalis peaks vähemalt osa süsteemist olema andmepõhine, et mittekodeerijad saaksid muudatusi teha ja kohandused toimuda kiiremini.

Vaatame tehisintellekti lähenemisviise, mis hõlmavad kogu Sense/Think/Act tsüklit.

Põhiotsuste tegemine

Alustame lihtsaimast mängust - Pong. Eesmärk: liigutage mõla nii, et pall põrkaks sellelt tagasi, mitte ei lendaks sellest mööda. See on nagu tennis, kus sa kaotad, kui sa palli ei löö. Siin on AI-l suhteliselt lihtne ülesanne - otsustada, millises suunas platvormi liigutada.

Mängu AI loomine: juhend algajatele

Tingimuslikud väited

Pongi tehisintellekti jaoks on kõige ilmsem lahendus püüda alati asetada platvorm palli alla.

Selle jaoks lihtne algoritm, mis on kirjutatud pseudokoodis:

iga kaader/värskendus mängu ajal:
kui pall asub labast vasakul:
liigutage aeru vasakule
muul juhul, kui pall on aeru paremal pool:
liigutage aeru paremale

Kui platvorm liigub palli kiirusega, on see Pongi AI jaoks ideaalne algoritm. Pole vaja midagi keeruliseks ajada, kui agendi jaoks pole nii palju andmeid ja võimalikke toiminguid.

See lähenemine on nii lihtne, et kogu Sense/Think/Act tsükkel on vaevumärgatav. Aga see on olemas:

  • Sense osa koosneb kahest if-lausest. Mäng teab, kus on pall ja kus on platvorm, nii et tehisintellekt otsib seda teavet.
  • Mõtlemise osa sisaldub ka kahes if-lauses. Need hõlmavad kahte lahendust, mis antud juhul on üksteist välistavad. Selle tulemusena valitakse üks kolmest toimingust – liigutage platvormi vasakule, liigutage seda paremale või ärge tehke midagi, kui see on juba õigesti paigutatud.
  • Tegutsemise osa leiate käskudest Move Paddle Left ja Move Paddle Right. Sõltuvalt mängu kujundusest saavad nad platvormi liigutada koheselt või kindla kiirusega.

Selliseid lähenemisviise nimetatakse reaktiivseks – on olemas lihtne reeglistik (antud juhul kui laused koodis), mis reageerivad maailma hetkeseisule ja tegutsevad.

Otsuste puu

Pongi näide on tegelikult samaväärne ametliku AI kontseptsiooniga, mida nimetatakse otsustuspuuks. Algoritm läbib selle, et jõuda „leheni” – otsuseni, milliseid toiminguid teha.

Teeme oma platvormi algoritmi otsustuspuu plokkskeemi:

Mängu AI loomine: juhend algajatele

Puu iga osa nimetatakse sõlmeks – AI kasutab selliste struktuuride kirjeldamiseks graafiteooriat. Sõlme on kahte tüüpi:

  • Otsustussõlmed: mõne tingimuse testimise põhjal valitakse kahe alternatiivi vahel, kus iga alternatiiv on esindatud eraldi sõlmena.
  • Lõppsõlmed: sooritatav toiming, mis kujutab endast lõplikku otsust.

Algoritm algab esimesest sõlmest (puu "juurest"). See kas otsustab, millisele alamsõlmele minna, või täidab sõlmes salvestatud toimingu ja väljub.

Mis kasu on sellest, kui otsustuspuu teeb sama tööd kui eelmises jaotises olevad if-laused? Siin on üldine süsteem, kus igal otsusel on ainult üks tingimus ja kaks võimalikku tulemust. See võimaldab arendajal luua tehisintellekti andmetest, mis esindavad puus olevaid otsuseid, ilma et peaks neid kõvasti kodeerima. Esitame selle tabeli kujul:

Mängu AI loomine: juhend algajatele

Koodi poolelt saate süsteemi stringide lugemiseks. Looge igaühe jaoks sõlm, ühendage teise veeru põhjal otsustusloogika ning kolmanda ja neljanda veeru alusel alamsõlmed. Tingimused ja tegevused tuleb veel programmeerida, kuid nüüd on mängu ülesehitus keerulisem. Siin saate lisada täiendavaid otsuseid ja toiminguid ning seejärel kohandada kogu AI-d, muutes lihtsalt puu definitsiooni tekstifaili. Järgmisena edastate faili mängukujundajale, kes saab käitumist muuta ilma mängu uuesti kompileerimata või koodi muutmata.

Otsustuspuud on väga kasulikud, kui need luuakse automaatselt suure hulga näidete põhjal (näiteks kasutades ID3 algoritmi). See muudab need tõhusaks ja suure jõudlusega tööriistaks olukordade klassifitseerimiseks saadud andmete põhjal. Kuid me läheme kaugemale lihtsast süsteemist, mille abil agenti saab toiminguid valida.

Stsenaariumid

Analüüsisime otsustuspuu süsteemi, mis kasutas eelnevalt loodud tingimusi ja toiminguid. Tehisintellekti kujundaja saab puu korraldada nii, nagu ta soovib, kuid ta peab siiski lootma kodeerijale, kes selle kõik programmeeris. Mis oleks, kui saaksime anda disainerile tööriistad oma tingimuste või tegevuste loomiseks?

Et programmeerija ei peaks kirjutama koodi tingimuste Is Ball Left Of Paddle ja Is Ball Right Of Paddle jaoks, saab ta luua süsteemi, milles disainer kirjutab nende väärtuste kontrollimiseks tingimused. Seejärel näevad otsustuspuu andmed välja järgmised:

Mängu AI loomine: juhend algajatele

See on sisuliselt sama, mis esimeses tabelis, kuid lahendustel endas on oma kood, natuke nagu if-lause tingimuslik osa. Koodi poolel loetakse see otsustussõlmede teises veerus, kuid selle asemel, et otsida konkreetset täidetavat tingimust (Is Ball Left Of Paddle), hindab see tingimusavaldist ja tagastab vastavalt tõese või väära. Seda tehakse Lua või Angelscripti skriptikeele abil. Neid kasutades saab arendaja võtta oma mängus objekte (pall ja aer) ning luua muutujaid, mis on skriptis saadaval (ball.position). Samuti on skriptikeel lihtsam kui C++. See ei nõua täielikku kompileerimisetappi, seega sobib see ideaalselt mänguloogika kiireks kohandamiseks ja võimaldab “mittekodeerijatel” ise vajalikke funktsioone luua.

Ülaltoodud näites kasutatakse skriptikeelt ainult tingimusavaldise hindamiseks, kuid seda saab kasutada ka toimingute jaoks. Näiteks võib andmetest Move Paddle Right saada skriptilause (ball.position.x += 10). Et toiming oleks ka skriptis määratletud, ilma et oleks vaja programmeerida Move Paddle Right.

Võite minna veelgi kaugemale ja kirjutada kogu otsustuspuu skriptikeeles. See on kood kõvakodeeritud tingimuslausete kujul, kuid need asuvad välistes skriptifailides, see tähendab, et neid saab muuta ilma kogu programmi uuesti kompileerimata. Sageli saate skriptifaili mängu ajal redigeerida, et kiiresti testida erinevaid tehisintellekti reaktsioone.

Sündmuse vastus

Ülaltoodud näited sobivad suurepäraselt Pongi jaoks. Nad juhivad pidevalt Sense/Think/Act tsüklit ja tegutsevad maailma uusima olukorra põhjal. Kuid keerukamates mängudes peate reageerima üksikutele sündmustele ja mitte hindama kõike korraga. Pong on antud juhul juba halb näide. Valime teise.

Kujutage ette tulistajat, kus vaenlased on liikumatud, kuni nad mängija avastavad, misjärel nad tegutsevad sõltuvalt oma "spetsialiseerumisest": keegi jookseb "tormama", keegi ründab kaugelt. See on ikkagi põhiline reaktiivne süsteem - "kui mängijat märgatakse, tehke midagi" -, kuid selle saab loogiliselt jagada sündmuseks Player Seen ja reaktsiooniks (valige vastus ja käivitage see).

See toob meid tagasi mõtte/mõtlemise/tegutsemise tsükli juurde. Saame kodeerida Sense'i osa, mis kontrollib iga kaadrit, kas tehisintellekt näeb mängijat. Kui ei, siis ei juhtu midagi, aga kui näeb, siis luuakse sündmus Player Seen. Koodil on eraldi jaotis, mis ütleb: "Kui sündmus Player Seen toimub, tehke", kus on vastus, mida vajate osade Mõtle ja tegutse käsitlemiseks. Seega seadistate sündmusele Player Seen reaktsioonid: "tormavale" tegelasele - ChargeAndAttack ja snaiprile - HideAndSnipe. Neid seoseid saab andmefailis luua kiireks redigeerimiseks ilma uuesti kompileerimata. Siin saab kasutada ka skriptikeelt.

Raskete otsuste tegemine

Kuigi lihtsad reaktsioonisüsteemid on väga võimsad, on palju olukordi, kus neist ei piisa. Mõnikord peate tegema erinevaid otsuseid selle põhjal, mida agent praegu teeb, kuid seda on raske ette kujutada tingimusena. Mõnikord on liiga palju tingimusi, et neid otsustuspuus või skriptis tõhusalt esindada. Mõnikord peate enne järgmise sammu otsustamist eelnevalt hindama, kuidas olukord muutub. Nende probleemide lahendamiseks on vaja keerukamaid lähenemisviise.

Lõpliku oleku masin

Lõpliku oleku masin või FSM (lõpliku oleku masin) on viis öelda, et meie agent on praegu ühes mitmest võimalikust olekust ja et see võib liikuda ühest olekust teise. Selliseid olekuid on teatud arv – sellest ka nimi. Parim näide elust on valgusfoor. Erinevates kohtades on erinevad tulede jadad, kuid põhimõte on sama – iga olek esindab midagi (peatus, kõnni jne). Valgusfoor on igal ajahetkel ainult ühes olekus ja liigub ühest teisest lihtsate reeglite alusel.

Sarnane lugu on ka mängude NPC-dega. Näiteks võtame valvuri järgmiste olekutega:

  • Patrullimine.
  • Ründamine.
  • Põgenemine.

Ja need tingimused selle oleku muutmiseks:

  • Kui valvur näeb vaenlast, ründab ta.
  • Kui valvur ründab, kuid vaenlast enam ei näe, naaseb ta patrullima.
  • Kui valvur ründab, kuid saab raskelt haavata, jookseb ta minema.

Samuti saab kirjutada if-avaldusi koos eestkostja oleku muutujaga ja erinevate kontrollidega: kas läheduses on vaenlane, milline on NPC tervislik seisund jne. Lisame veel paar olekut:

  • Jõudeolek – patrullide vahel.
  • Otsimine – kui märgatud vaenlane on kadunud.
  • Abi leidmine – kui vaenlane on märgatud, kuid ta on liiga tugev, et üksi võidelda.

Valik igaühe jaoks on piiratud - näiteks ei lähe valvur varjatud vaenlast otsima, kui tal on nõrk tervis.

Lõppude lõpuks on olemas tohutu nimekiri "kui" , See " võib muutuda liiga tülikaks, seega peame vormistama meetodi, mis võimaldab olekuid ja olekutevahelisi üleminekuid meeles pidada. Selleks võtame arvesse kõiki olekuid ja iga oleku alla kirjutame loendisse üles kõik üleminekud teistesse olekutesse koos nende jaoks vajalike tingimustega.

Mängu AI loomine: juhend algajatele

See on oleku ülemineku tabel – kõikehõlmav viis FSM-i esindamiseks. Joonistame diagrammi ja saame täieliku ülevaate sellest, kuidas NPC käitumine muutub.

Mängu AI loomine: juhend algajatele

Diagramm kajastab selle agendi otsuste tegemise olemust hetkeolukorra põhjal. Lisaks näitab iga nool olekute vahelist üleminekut, kui selle kõrval olev tingimus on tõene.

Iga värskenduse korral kontrollime agendi hetkeseisu, vaatame üle üleminekute loendi ja kui ülemineku tingimused on täidetud, võtab see uue oleku vastu. Näiteks kontrollib iga kaader, kas 10-sekundiline taimer on aegunud, ja kui jah, siis läheb valvur tühikäiguolekust patrullimisse. Samamoodi kontrollib Ründaja olek agendi tervist – kui see on madal, siis läheb see Põgenemisolekusse.

See on olekutevaheliste üleminekute käsitlemine, aga kuidas on lood olekutega seotud käitumisega? Konkreetse osariigi tegeliku käitumise rakendamisel on tavaliselt kahte tüüpi konksu, mille puhul me FSM-ile toimingud määrame:

  • Toimingud, mida me jooksva oleku jaoks perioodiliselt teostame.
  • Toimingud, mida me ühest olekust teise üleminekul teeme.

Esimese tüübi näited. Patrullimise olek liigutab agenti iga kaadri patrullmarsruuti mööda. Rünnaku olek üritab algatada rünnaku iga kaadri või ülemineku olekusse, kus see on võimalik.

Teise tüübi puhul kaaluge üleminekut "kui vaenlane on nähtav ja vaenlane on liiga tugev, minge abi leidmise olekusse. Agent peab valima, kuhu abi saamiseks pöörduda, ja salvestama selle teabe, et abi leidmise olek teaks, kuhu pöörduda. Kui abi on leitud, läheb agent tagasi ründava olekusse. Sel hetkel soovib ta liitlasele ohust rääkida, nii et võib toimuda toiming NotifyFriendOfThreat.

Taaskord saame vaadata seda süsteemi läbi tsükli Sense/Think/Act objektiivi. Mõistus sisaldub andmetes, mida kasutab üleminekuloogika. Mõtle – üleminekud on saadaval igas olekus. Ja tegu viiakse läbi toimingutega, mida tehakse perioodiliselt oleku sees või olekute vahel.

Mõnikord võivad pideva küsitluse ülemineku tingimused olla kulukad. Näiteks kui iga agent teeb igas kaadris keerulisi arvutusi, et teha kindlaks, kas ta näeb vaenlasi ja mõistab, kas ta suudab patrullimise olekust ründavasse olekusse üle minna, võtab see protsessori jaoks palju aega.

Olulisi muutusi maailma olukorras võib käsitleda sündmustena, mida töödeldakse nende toimumise ajal. Selle asemel, et FSM kontrolliks üleminekutingimust "kas mu agent näeb mängijat?" iga kaadri järel, saab eraldi süsteemi konfigureerida kontrollima harvemini (nt 5 korda sekundis). Tulemuseks on Player Seen väljastamine, kui kontroll läbib.

See edastatakse FSM-ile, mis peaks nüüd minema mängija nähtud sündmuse vastuvõtmise tingimusele ja reageerima sellele vastavalt. Sellest tulenev käitumine on sama, välja arvatud peaaegu märkamatu viivitus enne reageerimist. Kuid jõudlus on paranenud tänu Sense'i osa eraldamisele programmi eraldi osaks.

Hierarhiline lõplik olekumasin

Suurte FSM-idega töötamine ei ole aga alati mugav. Kui tahame ründeolekut laiendada, et eraldada olekud MeleeAttacking ja RangedAttacking, peame muutma üleminekuid kõikidest teistest olekutest, mis viivad ründeolekusse (praegune ja tulevane).

Tõenäoliselt märkasite, et meie näites on palju dubleerivaid üleminekuid. Enamik tühikäiguoleku üleminekuid on identsed patrullimise oleku üleminekutega. Oleks tore end mitte korrata, eriti kui lisada veel sarnaseid olekuid. Tühikäik ja patrullimine on mõttekas rühmitada üldise sildi "mittelahing" alla, kus on ainult üks ühine üleminekute komplekt võitlusseisunditesse. Kui mõelda sellele märgisele kui olekule, muutuvad tühikäigust ja patrullimisest alamolekud. Näide eraldi üleminekutabeli kasutamisest uue mittelahingulise alamoleku jaoks:

Peamised olekud:
Mängu AI loomine: juhend algajatele

Lahingust väljas olek:
Mängu AI loomine: juhend algajatele

Ja diagrammi kujul:

Mängu AI loomine: juhend algajatele

See on sama süsteem, kuid uue mittelahingulise olekuga, mis hõlmab tühikäiku ja patrullimist. Iga olekuga, mis sisaldab FSM-i koos alamolekutega (ja need alamolekud omakorda sisaldavad oma FSM-e – ja nii kaua, kuni vajate), saame hierarhilise lõpliku oleku masina või HFSM-i (hierarhiline lõpliku oleku masin). Rühmitades võitluseta oleku, lõikasime välja hulga üleliigseid üleminekuid. Sama saame teha kõigi uute ühiste üleminekutega olekute puhul. Näiteks kui tulevikus laiendame Rünnaku olekut lähiründe ja raketiründe olekutele, on need alamolekud, mis lähevad üksteise vahel üleminekuks vastavalt kaugusele vaenlasest ja laskemoona saadavusest. Selle tulemusena saab keerulisi käitumisi ja alamkäitumisi esitada minimaalsete dubleerivate üleminekutega.

Käitumise puu

HFSM-iga luuakse lihtsal viisil keerukaid käitumiskombinatsioone. Siiski on väike raskus, et üleminekureeglite vormis otsuste tegemine on hetkeseisuga tihedalt seotud. Ja paljudes mängudes on see just see, mida vaja on. Ja olekuhierarhia hoolikas kasutamine võib üleminekukorduste arvu vähendada. Kuid mõnikord vajate reegleid, mis töötavad olenemata sellest, millises osariigis olete, või mis kehtivad peaaegu igas osariigis. Näiteks kui agendi tervis langeb 25% -ni, tahate, et ta jookseks minema olenemata sellest, kas ta oli lahingus, jõude või rääkis – peate selle tingimuse igale olekule lisama. Ja kui teie disainer soovib hiljem madalat terviseläve 25%-lt 10%-le muuta, tuleb seda uuesti teha.

Ideaalis nõuab selline olukord süsteemi, kus otsused selle kohta, millises olekus olla, on väljaspool olekuid endid, et teha muudatusi ainult ühes kohas ja mitte puudutada üleminekutingimusi. Siia ilmuvad käitumispuud.

Nende rakendamiseks on mitu võimalust, kuid olemus on kõigi jaoks ligikaudu sama ja sarnane otsustuspuuga: algoritm algab juursõlmest ja puu sisaldab sõlmi, mis esindavad kas otsuseid või toiminguid. Siiski on mõned peamised erinevused:

  • Sõlmed tagastavad nüüd ühe kolmest väärtusest: Succeeded (kui töö on lõpetatud), Failed (kui seda ei saa käivitada) või Running (kui see töötab endiselt ja lõpptulemust pole).
  • Kahe alternatiivi vahel valimiseks pole enam otsustussõlme. Selle asemel on need dekoraatori sõlmed, millel on üks alamsõlm. Kui neil õnnestub, teostavad nad oma ainsa alamsõlme.
  • Toiminguid sooritavad sõlmed tagastavad teostatavate toimingute tähistamiseks väärtuse Running.

Seda väikest sõlmede komplekti saab kombineerida suure hulga keerukate käitumisviiside loomiseks. Kujutagem ette eelmise näite HFSM-i valvurit käitumispuuna:

Mängu AI loomine: juhend algajatele

Selle struktuuri puhul ei tohiks ilmneda üleminek tühikäigul/patrullimisel olekust ründavale või muudele olekutele. Kui vaenlane on nähtav ja tegelase tervis on madal, peatub hukkamine Põgenemissõlme juures, olenemata sellest, millist sõlme see varem täitis – patrullis, jõudeolekus, ründamises või mõnes muus.

Mängu AI loomine: juhend algajatele

Käitumispuud on keerulised – nende koostamiseks on palju võimalusi ning dekoraatorite ja liitsõlmede õige kombinatsiooni leidmine võib olla keeruline. Samuti tekib küsimusi, kui tihti puud kontrollida – kas tahame läbida selle iga osa või alles siis, kui mõni tingimus on muutunud? Kuidas me salvestame sõlmedega seotud olekut – kuidas me teame, millal oleme 10 sekundit tühikäigul olnud või kuidas teame, millised sõlmed viimati täitsid, et saaksime jada õigesti töödelda?

Seetõttu on rakendusi palju. Näiteks on mõned süsteemid asendanud dekoraatorisõlmed sisekujundusega. Nad hindavad puu ümber, kui dekoraatori tingimused muutuvad, aitavad liituda sõlmedega ja pakuvad perioodilisi värskendusi.

Kommunaalteenustepõhine süsteem

Mõnel mängul on palju erinevat mehhanismi. On soovitav, et nad saaksid kätte kõik lihtsate ja üldiste üleminekureeglite eelised, kuid mitte tingimata täieliku käitumispuu kujul. Selge valikute komplekti või võimalike toimingute puu asemel on lihtsam kõik tegevused läbi vaadata ja valida hetkel sobivaim.

Utiliidipõhine süsteem aitab just selles. See on süsteem, kus agendil on mitmesuguseid toiminguid ja ta valib, milliseid toiminguid teha, lähtudes igaühe suhtelisest kasulikkusest. Kasulikkus on meelevaldne mõõt selle kohta, kui oluline või soovitav on agendi jaoks selle toimingu sooritamine.

Toimingu arvutatud kasulikkus, mis põhineb hetkeolekul ja keskkonnal, saab agent igal ajal kontrollida ja valida kõige sobivama muu oleku. See sarnaneb FSM-iga, välja arvatud juhul, kui üleminekud määratakse iga potentsiaalse oleku, sealhulgas praeguse, hinnanguga. Pange tähele, et valime edasi liikumiseks (või jääme, kui oleme selle juba lõpetanud), kõige kasulikuma toimingu. Suurema mitmekesisuse huvides võiks see olla tasakaalustatud, kuid juhuslik valik väikesest loendist.

Süsteem määrab suvalise kasuliku väärtuste vahemiku – näiteks 0 (täiesti ebasoovitav) kuni 100 (täiesti soovitav). Igal toimingul on hulk parameetreid, mis mõjutavad selle väärtuse arvutamist. Tulles tagasi meie eestkostja näite juurde:

Mängu AI loomine: juhend algajatele

Toimingutevahelised üleminekud on mitmetähenduslikud – iga seisund võib järgneda teistele. Tegevuse prioriteedid leiate tagastatud kasuliku väärtustest. Kui vaenlane on nähtav ja see vaenlane on tugev ning tegelase tervis on madal, tagastavad nii Fleeing kui ka FindingHelp kõrged nullist erinevad väärtused. Sel juhul on FindingHelp alati kõrgem. Samuti ei anna lahinguvälised tegevused kunagi rohkem kui 50, seega on need alati madalamad kui lahingutegevused. Tegevuste loomisel ja nende kasulikkuse arvutamisel peate seda arvesse võtma.

Meie näites tagastavad toimingud kas fikseeritud konstantse väärtuse või ühe kahest fikseeritud väärtusest. Realistlikum süsteem annaks hinnangu pidevast väärtusvahemikust. Näiteks toiming Põgenemine tagastab kõrgemad kasulikud väärtused, kui agendi tervis on madal, ja toiming Rünnak tagastab madalamad kasulikud väärtused, kui vaenlane on liiga tugev. Seetõttu on tegu Põgenemisega ülimuslik Ründamise ees igas olukorras, kus agent tunneb, et tal pole vaenlase alistamiseks piisavalt tervist. See võimaldab tegevusi prioriseerida mis tahes arvu kriteeriumide alusel, muutes selle lähenemisviisi paindlikumaks ja muutlikumaks kui käitumispuu või Mikroneesia.

Igal toimingul on programmi arvutamiseks palju tingimusi. Neid saab kirjutada skriptikeeles või matemaatiliste valemite seeriana. Sims, mis simuleerib tegelase igapäevast rutiini, lisab täiendava arvutuskihi – agent saab rea "motivatsioone", mis mõjutavad kasulikkuse hinnanguid. Kui tegelane on näljane, muutub ta aja jooksul veelgi näljasemaks ja Söötoidu toimingu kasulikkus suureneb seni, kuni tegelane selle sooritab, vähendades nälja taset ja tagastades EatFoodi väärtuse nullile.

Hindamissüsteemil põhinevate toimingute valimise idee on üsna lihtne, nii et utiliidipõhist süsteemi saab kasutada tehisintellekti otsustusprotsesside osana, mitte nende täieliku asendajana. Otsustuspuu võib küsida kahe alamsõlme kasulikkuse reitingut ja valida neist kõrgema. Samamoodi võib käitumispuul olla liitsõlm Utility, mis hindab toimingute kasulikkust, et otsustada, millist last täita.

Liikumine ja navigeerimine

Eelmistes näidetes oli meil platvorm, mida liigutasime vasakule või paremale, ja valvur, mis patrullis või ründas. Kuidas aga täpselt käsitleme agentide liikumist teatud aja jooksul? Kuidas määrame kiirust, väldime takistusi ja kuidas planeerime marsruuti, kui sihtkohta jõudmine on keerulisem kui lihtsalt sirgjooneline liikumine? Vaatame seda.

Juhtimine

Algstaadiumis eeldame, et igal agendil on kiiruse väärtus, mis hõlmab, kui kiiresti see liigub ja mis suunas. Seda saab mõõta meetrites sekundis, kilomeetrites tunnis, pikslites sekundis jne. Meenutades tsüklit Sense/Think/Act, võime ette kujutada, et osa Think valib kiiruse ja osa Tegutseb selle kiiruse agendile. Tavaliselt on mängudel füüsikasüsteem, mis täidab selle ülesande teie eest, õpib iga objekti kiiruse väärtuse ja kohandab seda. Seetõttu võite jätta AI-le ühe ülesande - otsustada, milline kiirus peaks agendil olema. Kui teate, kus agent peaks olema, peate seda määratud kiirusega õiges suunas liigutama. Väga triviaalne võrrand:

soovitud_reis = sihtkoha_positsioon – agendi_positsioon

Kujutage ette 2D-maailma. Agent on punktis (-2,-2), sihtkoht on kuskil kirdes punktis (30, 20) ja agendile vajalik tee sinna jõudmiseks on (32, 22). Oletame, et neid asukohti mõõdetakse meetrites – kui võtame agendi kiiruseks 5 meetrit sekundis, siis skaleerime oma nihkevektorit ja saame kiiruseks ligikaudu (4.12, 2.83). Nende parameetritega jõuaks agent sihtkohta peaaegu 8 sekundiga.

Saate väärtused igal ajal ümber arvutada. Kui agent oleks poolel teel sihtmärgini, oleks liikumine poole lühem, aga kuna agendi maksimaalne kiirus on 5 m/s (seda otsustasime eespool), jääb kiirus samaks. See toimib ka liikuvate sihtmärkide puhul, võimaldades agendil nende liikumisel väikseid muudatusi teha.

Kuid me tahame rohkem vaheldust – näiteks tõsta aeglaselt kiirust, et simuleerida tegelast, kes liigub seismisest jooksmisele. Sama saab teha lõpus enne peatumist. Neid funktsioone nimetatakse juhtimiskäitumiseks, millest igaühel on spetsiifilised nimed: otsimine, põgenemine, saabumine jne. Idee seisneb selles, et agendi kiirusele saab rakendada kiirendusjõude, mis põhinevad agendi asukoha ja hetkekiiruse võrdlemisel sihtkohaga. selleks, et kasutada eesmärgi poole liikumiseks erinevaid meetodeid.

Igal käitumisel on veidi erinev eesmärk. Otsimine ja saabumine on viisid agendi viimiseks sihtkohta. Takistuste vältimine ja eraldamine kohandavad agendi liikumist, et vältida takistusi teel eesmärgi poole. Joondamine ja ühtekuuluvus hoiavad agente koos liikumas. Kõiki tegureid arvesse võttes saab ühe teevektori saamiseks summeerida mis tahes arvu erinevaid juhtimiskäitumisi. Agent, mis kasutab saabumise, eraldamise ja takistuste vältimise käitumist, et hoida end seintest ja muudest agentidest eemal. See lähenemisviis töötab hästi avatud kohtades ilma tarbetute üksikasjadeta.

Raskemates tingimustes toimib erinevate käitumisviiside lisamine halvemini – näiteks võib agent saabumise ja takistuste vältimise konflikti tõttu seina vahele jääda. Seetõttu peate kaaluma valikuid, mis on keerulisemad kui lihtsalt kõigi väärtuste lisamine. See on järgmine: iga käitumise tulemuste liitmise asemel võite kaaluda liikumist erinevates suundades ja valida parima võimaluse.

Kuid keerulises keskkonnas, kus on ummikud ja valikud, mis suunas liikuda, vajame midagi veelgi arenenumat.

Tee leidmine

Juhtimiskäitumine sobib suurepäraselt lihtsaks liikumiseks lagedal alal (jalgpalliväljakul või areenil), kus punktist A punkti B jõudmine on sirge tee, millel on vaid väikesed ümbersõidud takistustest. Keeruliste marsruutide jaoks vajame teeleidmist, mis on viis maailma avastamiseks ja seda läbiva marsruudi üle otsustamiseks.

Lihtsaim on kanda igale agendi kõrval olevale ruudule ruudustik ja hinnata, millisel neist on lubatud liikuda. Kui üks neist on sihtkoht, siis järgi marsruuti igast ruudust eelmisele, kuni jõuad algusesse. See on marsruut. Vastasel juhul korrake protsessi lähedal asuvate teiste ruutudega, kuni leiate oma sihtkoha või ruudud saavad otsa (see tähendab, et marsruuti pole võimalik). See on ametlikult tuntud kui Breadth-First Search või BFS (laiuse esiotsingu algoritm). Igal sammul vaatab ta igas suunas (seega laius, "laius"). Otsinguruum on nagu lainefront, mis liigub, kuni jõuab soovitud asukohta – otsinguruum laieneb igal sammul kuni lõpp-punkti kaasamiseni, misjärel saab selle alguseni tagasi jälgida.

Mängu AI loomine: juhend algajatele

Selle tulemusena saate nimekirja ruutudest, mida mööda soovitud marsruut koostatakse. See on tee (seega teeotsing) – nimekiri kohtadest, mida agent sihtkohta jälgides külastab.

Arvestades, et me teame iga ruudu asukohta maailmas, saame kasutada tüürimiskäitumist, et liikuda mööda teed – sõlmest 1 sõlme 2, siis sõlmest 2 sõlme 3 ja nii edasi. Lihtsaim variant on suunduda järgmise ruudu keskpunkti poole, kuid veelgi parem variant on peatuda praeguse ja järgmise ruudu vahelise ääre keskel. Seetõttu saab agent teravatel pööretel nurki lõigata.

BFS-algoritmil on ka puudusi – see uurib nii palju ruute “vales” kui “õiges” suunas. Siin tuleb mängu keerulisem algoritm nimega A* (A täht). See toimib samamoodi, kuid selle asemel, et pimesi uurida naaberruutusid (siis naabrite naabrid, siis naabrite naabrid jne), kogub see sõlmed loendisse ja sorteerib need nii, et järgmine uuritav sõlm on alati selline, mis viib lühima teeni. Sõlmed sorteeritakse heuristika alusel, mis võtab arvesse kahte asja – hüpoteetilise marsruudi maksumust soovitud ruuduni (kaasa arvatud reisikulud) ja hinnangut selle kohta, kui kaugel see ruut sihtkohast on (kallutab otsingut õiges suunas).

Mängu AI loomine: juhend algajatele

See näide näitab, et agent uurib korraga ühte ruutu, valides iga kord kõrvaloleva ruudu, mis on kõige lootustandvam. Saadud tee on sama, mis BFS, kuid protsessis võeti arvesse vähem ruute - mis mõjutab mängu jõudlust suuresti.

Liikumine ilma võrguta

Kuid enamik mänge ei ole ruudustikule paigutatud ja sageli on seda võimatu teha realistlikkust ohverdamata. Vaja on kompromisse. Mis suurusega ruudud peaksid olema? Liiga suured ja need ei suuda väikseid koridore ega pöördeid õigesti kujutada, liiga väikesed ja otsimiseks on liiga palju ruute, mis võtab lõpuks palju aega.

Esimene asi, mida tuleb mõista, on see, et võrk annab meile ühendatud sõlmede graafiku. Algoritmid A* ja BFS töötavad tegelikult graafikutel ega hooli meie võrgust üldse. Võiksime sõlmed paigutada ükskõik kuhu mängumaailma: seni, kuni on ühendus mis tahes kahe ühendatud sõlme, samuti algus- ja lõpp-punkti ning vähemalt ühe sõlme vahel, töötab algoritm sama hästi kui varem. Seda nimetatakse sageli teekonnapunktide süsteemiks, kuna iga sõlm esindab olulist positsiooni maailmas, mis võib olla osa mis tahes arvust hüpoteetilistest teedest.

Mängu AI loomine: juhend algajatele
Näide 1: sõlm igas ruudus. Otsing algab sõlmest, kus agent asub, ja lõpeb soovitud ruudu sõlmega.

Mängu AI loomine: juhend algajatele
Näide 2: väiksem sõlmede komplekt (teekonnapunktid). Otsing algab agendi ruudust, läbib vajaliku arvu sõlme ja jätkab seejärel sihtkohta.

See on täiesti paindlik ja võimas süsteem. Kuid otsustamisel, kuhu ja kuidas teekonnapunkt paigutada, on vaja veidi ettevaatust, vastasel juhul ei pruugi agendid lähimat punkti lihtsalt näha ega saa teekonda alustada. Oleks lihtsam, kui saaksime automaatselt paigutada teekonnapunktid maailma geomeetria alusel.

Siin kuvatakse navigeerimisvõrk või navmesh (navigatsioonivõrk). Tavaliselt on see kolmnurkade 2D-võrk, mis on kaetud maailma geomeetriaga – kõikjal, kus agentil on lubatud kõndida. Igast võrgusilma kolmnurgast saab graafiku sõlm ja sellel on kuni kolm külgnevat kolmnurka, millest saab graafikul külgnevad sõlmed.

See pilt on näide Unity mootorist - see analüüsis maailma geomeetriat ja lõi navmeshi (ekraanipildil helesinisega). Navseshi iga hulknurk on ala, kus agent saab seista või liikuda ühelt hulknurgalt teisele. Selles näites on hulknurgad väiksemad kui põrandad, millel need asuvad – seda tehakse selleks, et võtta arvesse agendi suurust, mis ulatub väljapoole selle nimiasendit.

Mängu AI loomine: juhend algajatele

Saame otsida marsruuti läbi selle võrgu, kasutades jällegi A* algoritmi. See annab meile maailmas peaaegu täiusliku marsruudi, mis võtab arvesse kogu geomeetriat ja ei nõua tarbetuid sõlmi ja teekonnapunktide loomist.

Rajaleidmine on liiga lai teema, mille jaoks ühest artikliosast ei piisa. Kui soovite seda üksikasjalikumalt uurida, siis see aitab Amit Pateli veebisait.

Планирование

Oleme rajaotsinguga õppinud, et mõnikord ei piisa ainult suuna valimisest ja liikumisest – soovitud sihtkohta jõudmiseks tuleb valida marsruut ja teha paar pööret. Võime seda mõtet üldistada: eesmärgi saavutamine ei ole ainult järgmine samm, vaid terve jada, kus mõnikord tuleb vaadata mitu sammu ette, et teada saada, milline peaks olema esimene. Seda nimetatakse planeerimiseks. Rajaleidmist võib pidada üheks mitmest planeerimise laiendusest. Arvestades meie mõtte/mõtlemise/tegutsemise tsüklit, plaanib osa Mõtle tulevikuks mitut toimingut.

Vaatame näitena lauamängu Magic: The Gathering. Kõigepealt läheme järgmise kaardikomplektiga käes:

  • Soo – annab 1 musta mana (maakaart).
  • Mets - annab 1 rohelise mana (maakaart).
  • Fugitive Wizard – väljakutsumiseks on vaja 1 sinist manat.
  • Elvish Mystic – väljakutsumiseks on vaja 1 rohelist manat.

Ülejäänud kolme kaarti ignoreerime, et see oleks lihtsam. Reeglite kohaselt on mängijal lubatud mängida 1 maakaarti käigu kohta, ta saab seda kaarti “koputada”, et sealt mana välja tõmmata ja seejärel vastavalt mana kogusele loitse (sh olendi välja kutsuda). Selles olukorras teab inimmängija mängida Foresti, koputada 1 rohelist manat ja seejärel kutsuda Elvish Mystic. Aga kuidas saab mäng AI sellest aru saada?

Lihtne planeerimine

Triviaalne lähenemine on proovida iga tegevust kordamööda, kuni sobivaid enam ei jää. Kaarte vaadates näeb tehisintellekt, mida Swamp mängida suudab. Ja ta mängib seda. Kas sellel pöördel on veel mingeid toiminguid jäänud? See ei saa välja kutsuda ei Elvish Mysticut ega Põgenevat võlurit, kuna nende väljakutsumiseks on vaja vastavalt rohelist ja sinist manat, samas kui Swamp pakub ainult musta manat. Ja Metsa ta enam mängida ei saa, sest ta on juba mänginud Swampi. Seega järgis mäng AI reegleid, kuid tegi seda halvasti. Saab parandada.

Planeerimine võib leida tegevuste loendi, mis viivad mängu soovitud olekusse. Nii nagu igal rajal oleval ruudul olid naabrid (raja leidmisel), on igal plaani toimingul ka naabrid või järglased. Me saame otsida neid toiminguid ja järgnevaid toiminguid, kuni jõuame soovitud olekusse.

Meie näites on soovitud tulemus "kui võimalik, kutsuge olend välja". Pöörde alguses näeme ainult kahte võimalikku mängureeglitega lubatud tegevust:

1. Mängige Swampi (tulemus: Swamp mängus)
2. Mängi Metsa (tulemus: Mets mängus)

Iga tehtud tegevus võib viia edasiste tegudeni ja teisi sulgeda, jällegi olenevalt mängureeglitest. Kujutage ette, et mängisime Swampi - see eemaldab järgmise sammuna Swamp (oleme seda juba mänginud) ja see eemaldab ka Foresti (kuna vastavalt reeglitele saate mängida ühe maakaardi käigu kohta). Pärast seda lisab AI järgmise sammuna 1 musta mana hankimise, kuna muid võimalusi pole. Kui ta läheb edasi ja valib Tap the Swamp, saab ta 1 ühiku musta manat ja ei saa sellega midagi peale hakata.

1. Mängige Swampi (tulemus: Swamp mängus)
1.1 "Tap" soo (tulemus: raba "koputatud", +1 ühik musta manat)
Toiminguid pole saadaval – END
2. Mängi Metsa (tulemus: Mets mängus)

Tegevuste nimekiri oli lühike, jõudsime ummikusse. Kordame protsessi järgmise sammu jaoks. Mängime Foresti, avame toimingu “saa 1 roheline mana”, mis omakorda avab kolmanda toimingu – kutsume välja Elvish Mysticu.

1. Mängige Swampi (tulemus: Swamp mängus)
1.1 "Tap" soo (tulemus: raba "koputatud", +1 ühik musta manat)
Toiminguid pole saadaval – END
2. Mängi Metsa (tulemus: Mets mängus)
2.1 „Tap“ mets (tulemus: mets on „koputatud“, +1 ühik rohelist manat)
2.1.1 Kutsu Elvish Mystic (tulemus: Elvish Mystic mängus, -1 roheline mana)
Toiminguid pole saadaval – END

Lõpuks uurisime kõiki võimalikke tegevusi ja leidsime plaani, mis olendi välja kutsub.

See on väga lihtsustatud näide. Soovitatav on valida parim võimalik plaan, mitte lihtsalt mis tahes plaan, mis vastab mõnele kriteeriumile. Üldiselt on võimalik potentsiaalseid plaane hinnata nende elluviimise tulemuse või üldise kasu põhjal. Maakaardi mängimise eest saad endale 1 punkti ja olendi väljakutsumise eest 3 punkti. Raba mängimine oleks 1 punkti plaan. Ja mängides Metsa → Puuduta metsa → kutsudes välja Elvish Mystic, annab kohe 4 punkti.

Planeerimine käib Magic: The Gatheringis nii, kuid sama loogika kehtib ka muudes olukordades. Näiteks etturi liigutamine, et teha ruumi piiskopile males liikumiseks. Või varjuda seina taha, et XCOM-is niimoodi turvaliselt pildistada. Üldiselt saate ideest aru.

Täiustatud planeerimine

Mõnikord on potentsiaalseid toiminguid liiga palju, et kõiki võimalikke valikuid kaaluda. Tulles tagasi näite juurde Magic: The Gathering: oletame, et mängus ja sinu käes on mitu maa- ja olendikaarti – võimalike käikude kombinatsioonide arv võib ulatuda kümnetesse. Probleemile on mitu lahendust.

Esimene meetod on tagurpidi aheldamine. Selle asemel, et proovida kõiki kombinatsioone, on parem alustada lõpptulemusest ja proovida leida otsene tee. Selle asemel, et minna puu juurest konkreetsele lehele, liigume vastupidises suunas – lehelt juure poole. See meetod on lihtsam ja kiirem.

Kui vaenlasel on 1 tervis, võite leida plaani "tehke 1 või enam kahju". Selle saavutamiseks peavad olema täidetud mitmed tingimused:

1. Kahju võib tekitada loits – see peab olema käes.
2. Loitsu tegemiseks on vaja manat.
3. Mana saamiseks tuleb mängida maakaarti.
4. Maakaardi mängimiseks peab see käes olema.

Teine võimalus on parim esimene otsing. Selle asemel, et kõiki teid läbi proovida, valime välja sobivaima. Enamasti annab see meetod optimaalse plaani ilma tarbetute otsingukuludeta. A* on parima esimese otsingu vorm – kõige lootustandvamaid marsruute algusest peale uurides võib see juba leida parima tee, ilma et peaks teisi valikuid kontrollima.

Huvitav ja üha populaarsemaks muutuv parim esimene otsinguvõimalus on Monte Carlo puuotsing. Selle asemel, et iga järgneva toimingu valimisel arvata, millised plaanid on teistest paremad, valib algoritm igal sammul juhuslikud järglased, kuni see jõuab lõpuni (kui plaan lõppes võidu või lüüasaamisega). Seejärel kasutatakse lõpptulemust eelmiste valikute kaalu suurendamiseks või vähendamiseks. Korrates seda protsessi mitu korda järjest, annab algoritm hea hinnangu, milline on parim järgmine käik, isegi kui olukord muutub (kui vaenlane võtab midagi ette, et mängijat segada).

Ükski mängude planeerimise lugu poleks täielik ilma eesmärgipõhise tegevusplaneerimise või GOAP-i (eesmärgile orienteeritud tegevuste planeerimiseta). See on laialdaselt kasutatav ja arutatud meetod, kuid peale mõne eristava detaili on see sisuliselt tagurpidi aheldamise meetod, millest me varem rääkisime. Kui eesmärk oli "mängija hävitada" ja mängija on katte taga, võiks plaan olla järgmine: hävita granaadiga → võta kätte → viska.

Tavaliselt on mitu eesmärki, millest igaühel on oma prioriteet. Kui kõrgeima prioriteediga eesmärki ei saa täita (ükski tegevuste kombinatsioon ei loo "tappa mängija", kuna mängija pole nähtav), naaseb AI madalama prioriteediga eesmärkide juurde.

Koolitus ja kohanemine

Oleme juba öelnud, et mängu tehisintellekt tavaliselt masinõpet ei kasuta, kuna see ei sobi agentide reaalajas haldamiseks. Kuid see ei tähenda, et te ei saaks sellelt alalt midagi laenata. Tahame laskurisse vastast, kellelt oleks midagi õppida. Näiteks saate teada parimate positsioonide kohta kaardil. Või kaklusmängus vastane, kes blokeeriks mängija sageli kasutatavad kombineeritud käigud, motiveerides teda teisi kasutama. Nii et masinõpe võib sellistes olukordades olla üsna kasulik.

Statistika ja tõenäosused

Enne kui asume keeruliste näidete juurde, vaatame, kui kaugele saame minna, tehes mõned lihtsad mõõtmised ja kasutades neid otsuste tegemisel. Näiteks reaalajas strateegia – kuidas teha kindlaks, kas mängija suudab mängu esimestel minutitel rünnakut alustada ja millist kaitset selle vastu ette valmistada? Saame uurida mängija varasemaid kogemusi, et mõista, millised võivad olla tulevased reaktsioonid. Alustuseks pole meil selliseid algandmeid, kuid me saame neid koguda – iga kord, kui tehisintellekt inimese vastu mängib, suudab see salvestada esimese rünnaku aja. Mõne sessiooni järel saame keskmise aja, mis kulub mängijal tulevikus ründamiseks.

Probleem on ka keskmiste väärtustega: kui mängija kiirustas 20 korda ja mängis aeglaselt 20 korda, siis on nõutavad väärtused kuskil keskel ja see ei anna meile midagi kasulikku. Üks lahendus on sisendandmete piiramine – viimased 20 tükki saab arvesse võtta.

Sarnast lähenemist kasutatakse teatud toimingute tõenäosuse hindamisel, eeldades, et mängija varasemad eelistused on tulevikus samad. Kui mängija ründab meid viis korda tulekeraga, kaks korda välguga ja üks kord lähivõitlusega, on ilmne, et ta eelistab tulekera. Ekstrapoleerime ja vaatame erinevate relvade kasutamise tõenäosust: tulekera=62,5%, välk=25% ja lähivõitlus=12,5%. Meie mängu tehisintellekt peab valmistuma, et end tule eest kaitsta.

Veel üks huvitav meetod on kasutada Naive Bayesi klassifikaatorit suure hulga sisendandmete uurimiseks ja olukorra klassifitseerimiseks nii, et tehisintellekt reageerib soovitud viisil. Bayesi klassifikaatorid on kõige tuntumad e-posti rämpspostifiltrites kasutamise poolest. Seal uurivad nad sõnu, võrdlevad neid sellega, kus need sõnad on varem ilmunud (rämpspostis või mitte) ja teevad järeldused sissetulevate e-kirjade kohta. Saame teha sama asja ka vähemate sisenditega. Põhineb kogu kasulikul teabel, mida AI näeb (nt millised vaenlase üksused on loodud või milliseid loitsusid nad kasutavad või milliseid tehnoloogiaid nad uurisid) ja lõpptulemusele (sõda või rahu, kiirustamine või kaitsmine jne) - valime soovitud tehisintellekti käitumise.

Kõik need koolitusmeetodid on piisavad, kuid neid on soovitatav kasutada testimisandmete põhjal. AI õpib kohanema erinevate strateegiatega, mida teie mängutestijad on kasutanud. AI, mis kohandub mängijaga pärast vabastamist, võib muutuda liiga etteaimatavaks või liiga raskeks lüüa.

Väärtuspõhine kohanemine

Arvestades meie mängumaailma sisu ja reegleid, saame muuta väärtuste komplekti, mis mõjutavad otsuste tegemist, selle asemel, et kasutada lihtsalt sisendandmeid. Teeme seda:

  • Laske tehisintellektil koguda mängu ajal andmeid maailma olukorra ja peamiste sündmuste kohta (nagu ülalpool).
  • Muudame nende andmete põhjal mõnda olulist väärtust.
  • Viime oma otsused ellu nende väärtuste töötlemise või hindamise põhjal.

Näiteks on agendil esimese isiku tulistamiskaardil valida mitme ruumi vahel. Igal toal on oma väärtus, mis määrab, kui soovitav on seda külastada. AI valib väärtuse põhjal juhuslikult, millisesse ruumi minna. Seejärel jätab agent meelde, millises ruumis ta tapeti, ja vähendab selle väärtust (tõenäosust, et ta sinna naaseb). Samamoodi ka vastupidise olukorra puhul – kui agent hävitab palju vastaseid, siis ruumi väärtus tõuseb.

Markovi mudel

Mis siis, kui kasutaksime kogutud andmeid ennustuste tegemiseks? Kui mäletame iga ruumi, kus mängijat teatud aja jooksul näeme, ennustame, millisesse ruumi mängija võib minna. Jälgides ja salvestades mängija liikumist ruumides (väärtused), saame neid ennustada.

Võtame kolm tuba: punane, roheline ja sinine. Ja ka tähelepanekud, mille jäädvustasime mängusessiooni jälgides:

Mängu AI loomine: juhend algajatele

Vaatluste arv igas ruumis on peaaegu võrdne – me ei tea siiani, kust varitsuspaika teha. Statistika kogumise teeb keeruliseks ka mängijate taassünnitamine, mis ilmuvad ühtlaselt kogu kaardil. Kuid andmed järgmise ruumi kohta, kuhu nad pärast kaardil ilmumist sisenevad, on juba kasulikud.

Näha on, et green room mängijatele sobib - sinna liigub punasest ruumist enamus inimesi, kellest 50% jääb sinna edasi. Sinine tuba, vastupidi, pole populaarne, sinna ei lähe peaaegu keegi ja kui läheb, siis ei jää kauaks.

Kuid andmed räägivad meile midagi olulisemat – kui mängija on sinises ruumis, on järgmine ruum, kus teda näeme, punane, mitte roheline. Kuigi roheline tuba on populaarsem kui punane tuba, muutub olukord, kui mängija on sinises toas. Järgmine olek (st ruum, kuhu mängija läheb) sõltub eelmisest olekust (st ruumist, kus mängija parasjagu viibib). Kuna me uurime sõltuvusi, teeme täpsemaid ennustusi kui siis, kui loeksime vaatlusi lihtsalt iseseisvalt.

Tuleviku oleku ennustamist mineviku oleku andmete põhjal nimetatakse Markovi mudeliks ja selliseid (ruumidega) näiteid Markovi ahelateks. Kuna mustrid tähistavad järjestikuste olekute vaheliste muutuste tõenäosust, kuvatakse need visuaalselt FSM-idena tõenäosusega iga ülemineku ümber. Varem kasutasime FSM-i agendi käitumusliku seisundi tähistamiseks, kuid see mõiste laieneb igale olekule, olenemata sellest, kas see on agendiga seotud või mitte. Sel juhul tähistavad olekud ruumi, kus agent hõivab:

Mängu AI loomine: juhend algajatele

See on lihtne viis olekumuutuste suhtelise tõenäosuse esitamiseks, andes AI-le võimaluse ennustada järgmist olekut. Võite ette näha mitu sammu ette.

Kui mängija on green roomis, on 50% tõenäosus, et ta jääb sinna ka järgmisel korral, kui teda jälgitakse. Aga kui suur on tõenäosus, et ta on seal ka pärast seda? Pole mitte ainult võimalus, et mängija jäi pärast kahte vaatlust green roomi, vaid on ka võimalus, et ta lahkus ja naasis. Siin on uus tabel, mis võtab arvesse uusi andmeid:

Mängu AI loomine: juhend algajatele

See näitab, et võimalus näha mängijat rohelises ruumis pärast kahte vaatlust võrdub 51% - 21%, et ta on punasest ruumist, 5% neist, et mängija külastab nende vahel asuvat sinist tuba, ja 25%, et mängija ei lahku green roomist.

Tabel on lihtsalt visuaalne tööriist – protseduur nõuab ainult tõenäosuste korrutamist igal etapil. See tähendab, et saate vaadata kaugele tulevikku ühe hoiatusega: eeldame, et ruumi sisenemise võimalus sõltub täielikult praegusest ruumist. Seda nimetatakse Markovi kinnisvaraks – tuleviku olek sõltub ainult olevikust. Kuid see pole XNUMX% täpne. Mängijad saavad otsuseid muuta sõltuvalt muudest teguritest: tervislikust tasemest või laskemoona kogusest. Kuna me neid väärtusi ei salvesta, on meie prognoosid vähem täpsed.

N-grammid

Aga võitlusmängu näide ja mängija kombineeritud käikude ennustamine? Sama! Kuid ühe oleku või sündmuse asemel uurime kõiki järjestusi, mis moodustavad kombineeritud streiki.

Üks võimalus seda teha on salvestada iga sisend (nt Kick, Punch või Block) puhvrisse ja kirjutada kogu puhver sündmusena. Nii et mängija vajutab korduvalt Kick, Kick, Punch, et kasutada SuperDeathFist rünnakut, AI-süsteem salvestab kõik sisendid puhvrisse ja jätab meelde igas etapis kasutatud kolm viimast.

Mängu AI loomine: juhend algajatele
(Pakspaksus kirjas on siis, kui mängija käivitab SuperDeathFisti rünnaku.)

Tehisintellekt näeb kõiki valikuid, kui mängija valib Kick, millele järgneb teine ​​Kick, ja märkab siis, et järgmine sisend on alati Punch. See võimaldab agendil ennustada SuperDeathFisti kombineeritud liikumist ja võimaluse korral selle blokeerida.

Neid sündmuste jadasid nimetatakse N-grammideks, kus N on salvestatud elementide arv. Eelmises näites oli see 3-grammine (trigramm), mis tähendab: kahte esimest kirjet kasutatakse kolmanda ennustamiseks. Seega ennustavad 5-grammises neli esimest kirjet viiendat ja nii edasi.

Disainer peab hoolikalt valima N-grammi suuruse. Väiksem N nõuab vähem mälu, kuid salvestab ka vähem ajalugu. Näiteks 2-grammine (bigramm) salvestab Kick, Kick või Kick, Punch, kuid ei saa salvestada Kick, Kick, Punch, nii et tehisintellekt ei reageeri SuperDeathFisti kombinatsioonile.

Teisest küljest nõuavad suuremad numbrid rohkem mälu ja tehisintellekti on raskem treenida, kuna võimalikke valikuid on palju rohkem. Kui teil oleks kolm võimalikku Kick, Punch või Block sisendit ja me kasutaksime 10-grammist, oleks see umbes 60 tuhat erinevat valikut.

Bigrammmudel on lihtne Markovi ahel – iga mineviku oleku/praeguse oleku paar on bigramm ja esimese põhjal saab ennustada teist olekut. 3-grammisi ja suuremaid N-gramme võib pidada ka Markovi ahelateks, kus kõik elemendid (v.a viimane N-grammis) moodustavad koos esimese oleku ja viimane element teise. Võitlusmängu näide näitab võimalust minna üle löömise ja löömise olekust olekusse Kick and Punch. Käsitledes mitut sisestusajaloo kirjet ühe üksusena, muudame sisuliselt sisendjada kogu oleku osaks. See annab meile Markovi omaduse, mis võimaldab Markovi ahelate abil ennustada järgmist sisendit ja arvata, milline kombineeritud käik on järgmine.

Järeldus

Rääkisime enamlevinud vahenditest ja lähenemistest tehisintellekti arendamisel. Vaatasime ka, millistes olukordades neid kasutada on vaja ja kus need on eriti kasulikud.

Sellest peaks piisama, et mõista mängu tehisintellekti põhitõdesid. Kuid loomulikult pole need kõik meetodid. Vähem populaarsed, kuid mitte vähem tõhusad on järgmised:

  • optimeerimisalgoritmid, sealhulgas mäkketõusu, gradiendi laskumise ja geneetilised algoritmid
  • võistlevad otsingu-/ajastamisalgoritmid (minimax ja alfa-beeta kärpimine)
  • klassifitseerimismeetodid (pertseptronid, närvivõrgud ja tugivektorimasinad)
  • süsteemid agentide taju ja mälu töötlemiseks
  • arhitektuursed lähenemisviisid AI-le (hübriidsüsteemid, alamhulgaarhitektuurid ja muud viisid AI-süsteemide katmiseks)
  • animatsioonitööriistad (planeerimine ja liikumise koordineerimine)
  • jõudlustegurid (detailsuse tase, igal ajal ja ajalõike algoritmid)

Veebiressursid teemal:

1. GameDev.net on jaotis AI-teemaliste artiklite ja õpetustega ning foorum.
2. AiGameDev.com sisaldab palju esitlusi ja artikleid mitmesugustel mängude tehisintellekti arendamisega seotud teemadel.
3. GDC Vault sisaldab GDC AI tippkohtumise teemasid, millest paljud on tasuta saadaval.
4. Kasulikud materjalid leiate ka kodulehelt AI mängude programmeerijate gild.
5. Tommy Thompson, AI-uurija ja mängude arendaja, teeb YouTube'is videoid AI ja mängud koos selgituse ja uurimisega AI kohta kommertsmängudes.

Raamatud sellel teemal:

1. Game AI Pro raamatusari on lühikeste artiklite kogumik, mis selgitab, kuidas konkreetseid funktsioone rakendada või konkreetseid probleeme lahendada.

Game AI Pro: Mängu AI professionaalide kogutud tarkused
Game AI Pro 2: Mängu AI-professionaalide kogutud tarkused
Game AI Pro 3: Mängu AI-professionaalide kogutud tarkused

2. AI Game Programming Wisdom seeria on Game AI Pro seeria eelkäija. See sisaldab vanemaid meetodeid, kuid peaaegu kõik on asjakohased ka tänapäeval.

AI mängude programmeerimise tarkus 1
AI mängude programmeerimise tarkus 2
AI mängude programmeerimise tarkus 3
AI mängude programmeerimise tarkus 4

3. Tehisintellekt: kaasaegne lähenemine on üks alustekste kõigile, kes tahavad mõista tehisintellekti üldist valdkonda. See ei ole raamat mängude arendamisest – see õpetab tehisintellekti põhitõdesid.

Allikas: www.habr.com

Lisa kommentaar