{"id":52118,"date":"2019-11-01T00:00:00","date_gmt":"2019-10-31T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih"},"modified":"2020-02-18T13:59:47","modified_gmt":"2020-02-18T10:59:47","slug":"kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","status":"publish","type":"post","link":"https:\/\/prohoster.info\/sv\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","title":{"rendered":"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/9e57175b233a104e0df98383b374eded.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJag snubblade \u00f6ver ett intressant material om artificiell intelligens i spel. Med en f\u00f6rklaring av grundl\u00e4ggande saker om AI genom enkla exempel, och dessutom m\u00e5nga anv\u00e4ndbara verktyg och metoder f\u00f6r dess smidiga utveckling och design. Hur, var och n\u00e4r de ska anv\u00e4ndas - det finns ocks\u00e5.<\/p>\n<p>De flesta exemplen \u00e4r skrivna i pseudokod, s\u00e5 djupa programmeringskunskaper beh\u00f6vs inte. Under l\u00e4nken finns 35 sidor text med bilder och GIF:ar, s\u00e5 var beredd.<\/p>\n<p>UPD. Jag ber om urs\u00e4kt, men jag har redan gjort min egen \u00f6vers\u00e4ttning av denna artikel p\u00e5 Habr\u00e9. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/PatientZero\/\">PatientZero<\/a><\/noindex>. Du kan l\u00e4sa hans version <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/420219\/\">h\u00e4r<\/a><\/noindex>, men av n\u00e5gon anledning har artikeln g\u00e5tt mig f\u00f6rbi (jag anv\u00e4nde s\u00f6kfunktionen, men n\u00e5got gick fel). Eftersom jag skriver i en blogg som \u00e4r dedikerad till spelutveckling, beslutade jag mig f\u00f6r att l\u00e4mna min egen \u00f6vers\u00e4ttning f\u00f6r prenumeranterna (vissa moment har jag formulerat p\u00e5 ett annat s\u00e4tt, andra har jag medvetet utel\u00e4mnat p\u00e5 r\u00e5d fr\u00e5n utvecklarna).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Vad \u00e4r AI?<\/h2>\n<p>\nSpel-AI fokuserar p\u00e5 vilka \u00e5tg\u00e4rder ett objekt ska vidta baserat p\u00e5 de f\u00f6rh\u00e5llanden det befinner sig i. Detta kallas vanligtvis f\u00f6r att hantera 'intelligenta agenter', d\u00e4r agenten \u00e4r en spelkarakt\u00e4r, ett fordon, en bot, och ibland n\u00e5got mer abstrakt: en hel grupp av entiteter eller till och med en civilisation. I varje fall \u00e4r det n\u00e5got som ska kunna se sin omgivning, fatta beslut baserat p\u00e5 den och agera i enlighet med detta. Detta kallas Sense\/Think\/Act-cykeln (K\u00e4nna\/T\u00e4nka\/Agera):<\/p>\n<ul>\n<li>K\u00e4nna: agenten hittar eller f\u00e5r information om saker i sin milj\u00f6 som kan p\u00e5verka dess beteende (hot i n\u00e4rheten, f\u00f6rem\u00e5l att samla, intressanta platser att utforska).<\/li>\n<li>T\u00e4nka: agenten beslutar hur den ska reagera (\u00f6verv\u00e4ger om det \u00e4r tillr\u00e4ckligt s\u00e4kert att samla f\u00f6rem\u00e5l eller om den f\u00f6rst m\u00e5ste sl\u00e5ss\/g\u00f6mma sig).<\/li>\n<li>Agera: agenten utf\u00f6r \u00e5tg\u00e4rder f\u00f6r att genomf\u00f6ra det f\u00f6reg\u00e5ende beslutet (b\u00f6rjar r\u00f6ra sig mot motst\u00e5ndaren eller objektet).<\/li>\n<li>\u2026situationen har nu f\u00f6r\u00e4ndrats p\u00e5 grund av karakt\u00e4rernas handlingar, s\u00e5 cykeln b\u00f6rjar om med nya uppgifter.<\/li>\n<\/ul>\n<p>\nAI fokuserar vanligtvis p\u00e5 Sense-delen av cykeln. Till exempel g\u00f6r sj\u00e4lvk\u00f6rande bilar bilder av v\u00e4gen, kombinerar dem med radar- och lidar-data samt tolkar dem. Vanligtvis g\u00f6rs detta av maskininl\u00e4rning, som bearbetar indata och ger dem mening, genom att extrahera semantisk information som \"det finns en annan bil 20 meter framf\u00f6r dig\". Detta kallas f\u00f6r klassificeringsproblem.<\/p>\n<p>Spel beh\u00f6ver inte ett komplext system f\u00f6r att extrahera information, eftersom st\u00f6rsta delen av datan redan \u00e4r en integrerad del av det. Det \u00e4r inte n\u00f6dv\u00e4ndigt att k\u00f6ra algoritmer f\u00f6r bildigenk\u00e4nning f\u00f6r att avg\u00f6ra om det finns en fiende framf\u00f6r \u2014 spelet vet redan och \u00f6verf\u00f6r informationen direkt under beslutsprocessen. D\u00e4rf\u00f6r \u00e4r Sense-delen av cykeln ofta mycket enklare \u00e4n Think och Act.<\/p>\n<h2>Begr\u00e4nsningar f\u00f6r spel-AI<\/h2>\n<p>\nAI har flera begr\u00e4nsningar som m\u00e5ste f\u00f6ljas:<\/p>\n<ul>\n<li>AI beh\u00f6ver inte tr\u00e4nas i f\u00f6rv\u00e4g, som en maskininl\u00e4rningsalgoritm. Det \u00e4r meningsl\u00f6st att skriva ett neuralt n\u00e4tverk under utvecklingen f\u00f6r att observera tiotusentals spelare och l\u00e4ra sig det b\u00e4sta s\u00e4ttet att spela mot dem. Varf\u00f6r? F\u00f6r att spelet inte har sl\u00e4ppts \u00e4nnu och det inte finns n\u00e5gra spelare.<\/li>\n<li>Spelet ska underh\u00e5lla och utmana, s\u00e5 agenterna f\u00e5r inte hitta det b\u00e4sta tillv\u00e4gag\u00e5ngss\u00e4ttet mot m\u00e4nniskor.<\/li>\n<li>Agenterna m\u00e5ste se realistiska ut, s\u00e5 att spelarna k\u00e4nner att de spelar mot riktiga m\u00e4nniskor. AlphaGo \u00f6vertr\u00e4ffade m\u00e4nniskor, men de valda dragen var l\u00e5ngt ifr\u00e5n traditionell f\u00f6rst\u00e5else av spelet. Om spelet imiterar en m\u00e4nsklig motst\u00e5ndare ska det inte finnas den k\u00e4nslan. Algoritmen m\u00e5ste f\u00f6r\u00e4ndras f\u00f6r att ta rimliga beslut snarare \u00e4n perfekta id\u00e9er.<\/li>\n<li>AI m\u00e5ste fungera i realtid. Det betyder att algoritmen inte kan monopoliserar CPU-anv\u00e4ndningen under l\u00e5ng tid f\u00f6r att ta beslut. \u00c4ven 10 millisekunder f\u00f6r detta \u00e4r f\u00f6r l\u00e4nge, eftersom de flesta spel beh\u00f6ver mellan 16 och 33 millisekunder f\u00f6r att slutf\u00f6ra all bearbetning och g\u00e5 vidare till n\u00e4sta grafikram.<\/li>\n<li>Det \u00e4r idealiskt om \u00e5tminstone en del av systemet styrs av data, s\u00e5 att \"icke-kodare\" kan g\u00f6ra \u00e4ndringar, och s\u00e5 att justeringar sker snabbare.<\/li>\n<\/ul>\n<p>\nL\u00e5t oss \u00f6verv\u00e4ga AI-ansatser som t\u00e4cker hela cykeln Sense\/Think\/Act.<\/p>\n<h3>Beslut om grundl\u00e4ggande beslut<\/h3>\n<p>\nL\u00e5t oss b\u00f6rja med det enklaste spelet \u2013 Pong. M\u00e5let \u00e4r att flytta plattan (paddle) s\u00e5 att bollen studsar mot den ist\u00e4llet f\u00f6r att passera f\u00f6rbi. Det \u00e4r som tennis d\u00e4r du f\u00f6rlorar om du inte sl\u00e5r tillbaka bollen. H\u00e4r har AI en relativt enkel uppgift \u2013 att avg\u00f6ra i vilken riktning plattan ska flyttas.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/e1935d657b9f090bf60c365c21e8f92b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Villkorssatser<\/h3>\n<p>\nF\u00f6r AI i Pong finns det en uppenbar l\u00f6sning \u2013 alltid f\u00f6rs\u00f6ka placera plattan under bollen.<\/p>\n<p>Ett enkelt algoritm f\u00f6r detta, skrivet i pseudokod:<\/p>\n<p><i>varje bilduppdatering medan spelet p\u00e5g\u00e5r:<br \/>\nom bollen \u00e4r till v\u00e4nster om plattan:<br \/>\n flytta plattan v\u00e4nster<br \/>\nannars om bollen \u00e4r till h\u00f6ger om plattan:<br \/>\n flytta plattan h\u00f6ger<\/i><\/p>\n<p>Om plattan r\u00f6r sig med bollens hastighet \u00e4r det en perfekt algoritm f\u00f6r AI i Pong. Det \u00e4r inget som beh\u00f6ver kompliceras, om det inte finns s\u00e5 m\u00e5nga data och m\u00f6jliga handlingar f\u00f6r agenten.<\/p>\n<p>Denna metod \u00e4r s\u00e5 enkel att hela cykeln Sense\/Think\/Act knappt m\u00e4rks. Men den finns d\u00e4r:<\/p>\n<ul>\n<li>Delen Sense finns i de tv\u00e5 if-satserna. Spelet vet var bollen och plattan \u00e4r, s\u00e5 AI v\u00e4nder sig till den f\u00f6r denna information. <\/li>\n<li>Delen Think ing\u00e5r ocks\u00e5 i de tv\u00e5 if-satserna. De representerar tv\u00e5 beslut som i detta fall \u00e4r \u00f6msesidigt uteslutande. Som ett resultat v\u00e4ljs en av tre \u00e5tg\u00e4rder \u2013 flytta plattan \u00e5t v\u00e4nster, flytta \u00e5t h\u00f6ger, eller inte g\u00f6ra n\u00e5got om den redan \u00e4r korrekt placerad.<\/li>\n<li>Delen Act finns i satserna Flytta Plattan V\u00e4nster och Flytta Plattan H\u00f6ger. Beroende p\u00e5 spelets design kan de flytta plattan omedelbart eller med en viss hastighet. <\/li>\n<\/ul>\n<p>\nS\u00e5dana metoder kallas reaktiva \u2013 det finns en enkel upps\u00e4ttning regler (i det h\u00e4r fallet if-satserna i koden) som reagerar p\u00e5 den aktuella v\u00e4rldens tillst\u00e5nd och agerar.<\/p>\n<h3>Besluts tr\u00e4d<\/h3>\n<p>\nExemplet med spelet Pong \u00e4r i princip likv\u00e4rdigt med den formella AI-konceptet som kallas besluts tr\u00e4d. Algoritmen g\u00e5r igenom det f\u00f6r att n\u00e5 ett \"blad\" \u2013 beslutet om vilken \u00e5tg\u00e4rd som ska vidtas.<\/p>\n<p>L\u00e5t oss skapa ett fl\u00f6desschema f\u00f6r besluts tr\u00e4det f\u00f6r v\u00e5r plattforms algoritm:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/d3b7290ba93144967cd849416cd5eef3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVarje del av tr\u00e4det kallas node (nod) \u2013 AI anv\u00e4nder grafteori f\u00f6r att beskriva s\u00e5dana strukturer. Det finns tv\u00e5 typer av noder:<\/p>\n<ul>\n<li>Besluts noder: val mellan tv\u00e5 alternativ baserat p\u00e5 kontroll av ett visst villkor, d\u00e4r varje alternativ representeras som en separat nod.<\/li>\n<li>Slutnoder: \u00e5tg\u00e4rder att utf\u00f6ra, vilket representerar det slutgiltiga beslutet.<\/li>\n<\/ul>\n<p>\nAlgoritmen b\u00f6rjar med den f\u00f6rsta noden (\"rotnoden\" av tr\u00e4det). Den antingen fattar ett beslut om vilken undernod att g\u00e5 till, eller s\u00e5 utf\u00f6r den en \u00e5tg\u00e4rd som \u00e4r lagrad i noden och avslutas.<\/p>\n<p>Vad \u00e4r d\u00e5 f\u00f6rdelen om ett beslutstr\u00e4d g\u00f6r samma jobb som if-satserna i avsnittet ovan? H\u00e4r finns ett gemensamt system d\u00e4r varje beslut har endast ett villkor och tv\u00e5 m\u00f6jliga resultat. Detta g\u00f6r det m\u00f6jligt f\u00f6r utvecklaren att skapa AI utifr\u00e5n data som representerar beslut i tr\u00e4det, utan att h\u00e5rdkoda det. L\u00e5t oss f\u00f6rest\u00e4lla oss det i en tabell:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/6875293a60ff9d0efa26fb5e1aa4b21c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nP\u00e5 kodsidan f\u00e5r du ett system f\u00f6r att l\u00e4sa str\u00e4ngar. Skapa en nod f\u00f6r var och en av dem, koppla logik f\u00f6r beslutsfattande baserat p\u00e5 den andra kolumnen och undernoder baserat p\u00e5 den tredje och fj\u00e4rde kolumnen. Du beh\u00f6ver fortfarande programmera villkor och \u00e5tg\u00e4rder, men nu blir spelstrukturen mer komplex. Du l\u00e4gger till fler beslut och \u00e5tg\u00e4rder och konfigurerar hela AI:n genom att helt enkelt redigera en textfil med definitionen av tr\u00e4det. D\u00e4refter \u00f6verl\u00e4mnar du filen till speldesignern, som kan \u00e4ndra beteendet utan att beh\u00f6va rekonstruera spelet eller \u00e4ndra koden.<\/p>\n<p>Beslutstr\u00e4d \u00e4r mycket anv\u00e4ndbara n\u00e4r de byggs automatiskt baserat p\u00e5 en stor m\u00e4ngd exempel (t.ex. med hj\u00e4lp av ID3-algoritmen). Detta g\u00f6r dem till ett effektivt och h\u00f6gpresterande verktyg f\u00f6r att klassificera situationer baserat p\u00e5 insamlade data. Men vi g\u00e5r bortom ett enkelt system f\u00f6r att v\u00e4lja \u00e5tg\u00e4rder f\u00f6r agenter.<\/p>\n<h3>Scenarier<\/h3>\n<p>\nVi har g\u00e5tt igenom systemet f\u00f6r beslutstr\u00e4d som anv\u00e4nde f\u00f6rdefinierade villkor och \u00e5tg\u00e4rder. M\u00e4nniskor som designar AI kan organisera tr\u00e4det som de vill, men de m\u00e5ste fortfarande f\u00f6rlita sig p\u00e5 en programmerare som har kodar det hela. Vad om vi kunde ge designern verktyg f\u00f6r att skapa egna villkor eller \u00e5tg\u00e4rder?<\/p>\n<p>F\u00f6r att programmet inte ska beh\u00f6va skriva kod f\u00f6r villkoren Is Ball Left Of Paddle och Is Ball Right Of Paddle, kan det skapa ett system d\u00e4r designern skriver villkoren f\u00f6r att kontrollera dessa v\u00e4rden. D\u00e5 skulle data i beslutstr\u00e4det se ut s\u00e5 h\u00e4r:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/8e77f7c3410d097e8b7d8e1209355cc6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI grunden \u00e4r detta detsamma som i den f\u00f6rsta tabellen, men l\u00f6sningarna inom sig har egen kod, som liknar den villkorliga delen av en if-sats. I koden skulle detta l\u00e4sas i den andra kolumnen f\u00f6r beslutsknutar, men ist\u00e4llet f\u00f6r att s\u00f6ka efter ett specifikt villkor att utf\u00f6ra (\u00c4r bollen till v\u00e4nster om paddeln), utv\u00e4rderar det det villkorliga uttrycket och returnerar true eller false d\u00e4refter. Detta g\u00f6rs med hj\u00e4lp av skriptspr\u00e5ket Lua eller Angelscript. Genom dessa kan utvecklaren ta objekt i sitt spel (boll och paddel) och skapa variabler som kommer att vara tillg\u00e4ngliga i skriptet (boll.position). Dessutom \u00e4r skriptspr\u00e5ket enklare \u00e4n C++. Det kr\u00e4ver inte en fullst\u00e4ndig kompilering, vilket g\u00f6r det perfekt f\u00f6r snabb justering av spel logik och l\u00e5ter \"icke-kodare\" sj\u00e4lva skapa n\u00f6dv\u00e4ndiga funktioner.<\/p>\n<p>I det givna exemplet anv\u00e4nds skriptspr\u00e5ket endast f\u00f6r att utv\u00e4rdera det villkorliga uttrycket men kan ocks\u00e5 anv\u00e4ndas f\u00f6r \u00e5tg\u00e4rder. Till exempel kan data Move Paddle Right bli en skriptoperator (boll.position.x += 10). S\u00e5ledes kan \u00e5tg\u00e4rden ocks\u00e5 definieras i skriptet, utan behov av att programmera Move Paddle Right.<\/p>\n<p>Man kan g\u00e5 l\u00e4ngre och helt skriva besluts tr\u00e4det i skriptspr\u00e5ket. Detta skulle vara kod i form av h\u00e5rdkodade villkorssatser, men de skulle finnas i externa skriptfiler, vilket betyder att de kan \u00e4ndras utan att beh\u00f6va kompilera om hela programmet. Ofta kan man \u00e4ndra skriptfilen mitt under spelet f\u00f6r att snabbt testa olika AI-reaktioner.<\/p>\n<h3>Reagera p\u00e5 h\u00e4ndelser<\/h3>\n<p>\nExemplen ovan passar perfekt i Pong. De k\u00f6r kontinuerligt cykeln Sense\/Think\/Act och agerar baserat p\u00e5 v\u00e4rldens senaste tillst\u00e5nd. Men i mer komplicerade spel beh\u00f6ver man reagera p\u00e5 specifika h\u00e4ndelser, ist\u00e4llet f\u00f6r att utv\u00e4rdera allt p\u00e5 en g\u00e5ng. Pong \u00e4r i s\u00e5 fall redan ett d\u00e5ligt exempel. L\u00e5t oss v\u00e4lja ett annat. <\/p>\n<p>F\u00f6rest\u00e4ll dig en shooter d\u00e4r fienderna st\u00e5r stilla tills de uppt\u00e4cker spelaren, varefter de agerar beroende p\u00e5 sin \"specialisering\": vissa kommer att rush'a, andra kommer att attackera p\u00e5 avst\u00e5nd. Detta \u00e4r fortfarande ett grundl\u00e4ggande reaktionssystem \u2014 \"om spelaren uppt\u00e4cktes, g\u00f6r n\u00e5got\" \u2014 men det kan logiskt delas upp i h\u00e4ndelsen Player Seen (spelare uppt\u00e4ckt) och reaktionen (v\u00e4lj ett svar och utf\u00f6r det).<\/p>\n<p>Det h\u00e4r tar oss tillbaka till cykeln Sense\/T\u00e4nk\/Utf\u00f6r. Vi kan programmera Sense-delen som varje ram kontrollerar om AI:n ser spelaren. Om inte h\u00e4nder ingenting, men om den g\u00f6r det skapas en h\u00e4ndelse kallad Player Seen. Koden kommer att ha en separat sektion som s\u00e4ger: \"n\u00e4r h\u00e4ndelsen Player Seen intr\u00e4ffar, g\u00f6r \", d\u00e4r  \u00e4r svaret du beh\u00f6ver f\u00f6r att anropa delarna T\u00e4nk och Utf\u00f6r. P\u00e5 s\u00e5 s\u00e4tt st\u00e4ller du in reaktioner p\u00e5 h\u00e4ndelsen Player Seen: f\u00f6r en \"rushande\" karakt\u00e4r \u2013 ChargeAndAttack, och f\u00f6r en snipervapen \u2013 HideAndSnipe. Dessa samband kan skapas i en databas f\u00f6r snabb redigering utan att beh\u00f6va kompilera om. Och h\u00e4r kan vi ocks\u00e5 anv\u00e4nda skriptspr\u00e5k.<\/p>\n<h2>Att fatta komplexa beslut<\/h2>\n<p>\n\u00c4ven om enkla reaktionssystem \u00e4r mycket effektiva finns det m\u00e5nga situationer d\u00e4r de inte r\u00e4cker. Ibland m\u00e5ste olika beslut fattas beroende p\u00e5 vad agenten g\u00f6r f\u00f6r tillf\u00e4llet, men att representera detta som ett villkor \u00e4r sv\u00e5rt. Ibland finns det f\u00f6r m\u00e5nga villkor f\u00f6r att effektivt representera dem i ett beslutstr\u00e4d eller skript. Ibland m\u00e5ste man f\u00f6rutse hur situationen kommer att f\u00f6r\u00e4ndras innan man fattar beslut om n\u00e4sta steg. F\u00f6r att l\u00f6sa dessa problem beh\u00f6vs mer komplexa metoder.<\/p>\n<h3>\u00c4ndlig tillst\u00e5ndsmaskin<\/h3>\n<p>\n\u00c4ndlig tillst\u00e5ndsmaskin eller FSM (Finita tillst\u00e5ndsmaskin) \u00e4r ett s\u00e4tt att s\u00e4ga att v\u00e5r agent f\u00f6r n\u00e4rvarande befinner sig i ett av flera m\u00f6jliga tillst\u00e5nd och att han kan \u00f6verg\u00e5 fr\u00e5n ett tillst\u00e5nd till ett annat. Det finns ett best\u00e4mt antal s\u00e5dana tillst\u00e5nd \u2013 d\u00e4rav namnet. Det b\u00e4sta exemplet fr\u00e5n verkligheten \u00e4r trafikljuset. P\u00e5 olika platser finns det olika sekvenser av ljus, men principen \u00e4r densamma \u2013 varje tillst\u00e5nd representerar n\u00e5got (stanna, g\u00e5, etc.). Trafikljuset befinner sig bara i ett tillst\u00e5nd vid varje given tidpunkt och g\u00e5r fr\u00e5n ett tillst\u00e5nd till ett annat baserat p\u00e5 enkla regler.<\/p>\n<p>Med NPC:er i spel \u00e4r det en liknande historia. L\u00e5t oss ta en vakthavande med dessa tillst\u00e5nd:<\/p>\n<ul>\n<li>Patrullerande (Patrolling).<\/li>\n<li>Angripande (Attacking).<\/li>\n<li>Flyende (Fleeing).<\/li>\n<\/ul>\n<p>\nOch med dessa villkor f\u00f6r att f\u00f6r\u00e4ndra hans tillst\u00e5nd:<\/p>\n<ul>\n<li>Om vakten ser en fiende, attackerar han.<\/li>\n<li>Om vakten attackerar, men inte l\u00e4ngre ser fienden, \u00e5terg\u00e5r han till att patrullera.<\/li>\n<li>Om vakten attackerar, men \u00e4r sv\u00e5rt skadad, flyr han.<\/li>\n<\/ul>\n<p>\nMan kan ocks\u00e5 skriva if-operatorer med en tillst\u00e5ndsvariabel f\u00f6r vakten och olika kontroller: finns det en fiende i n\u00e4rheten, vad \u00e4r NPC:ns h\u00e4lsotillst\u00e5nd osv. L\u00e5t oss l\u00e4gga till n\u00e5gra fler tillst\u00e5nd:<\/p>\n<ul>\n<li>Inaktivitet (Idling) \u2014 mellan patruller.<\/li>\n<li>S\u00f6kning (Searching) \u2014 n\u00e4r en fiende har setts men har g\u00f6mt sig.<\/li>\n<li>Be om hj\u00e4lp (Finding Help) \u2014 n\u00e4r en fiende har setts, men \u00e4r f\u00f6r stark f\u00f6r att sl\u00e5ss ensam.<\/li>\n<\/ul>\n<p>\nValet f\u00f6r var och en \u00e4r begr\u00e4nsat \u2014 till exempel kommer en vakt inte att s\u00f6ka efter en g\u00f6md fiende om han har l\u00e5g h\u00e4lsa.<\/p>\n<p>Till slut kan en l&aring;ng lista med &quot;om och&quot; bli f&ouml;r otymplig, s&aring; vi b&ouml;r formaliserar en metod som g&ouml;r det m&ouml;jligt f&ouml;r oss att h&aring;lla reda p&aring; tillst&aring;nd och &ouml;verg&aring;ngar mellan tillst&aring;nd. &lt;x \u0438 y, \u043d\u043e \u043d\u0435 z&gt;, s&aring; &lt;p&gt;F&ouml;r att g&ouml;ra detta kommer vi att ta h&auml;nsyn till alla tillst&aring;nd och under varje tillst&aring;nd skriva upp alla &ouml;verg&aring;ngar till andra tillst&aring;nd, tillsammans med de n&ouml;dv&auml;ndiga villkoren f&ouml;r dem.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/ba4c401aa20de3d22d2478cba5a4b1ec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDetta \u00e4r en \u00f6verg\u00e5ngstabell f\u00f6r tillst\u00e5nd \u2014 ett omfattande s\u00e4tt att representera FSM. Vi ritar ett diagram och f\u00e5r en fullst\u00e4ndig \u00f6versikt \u00f6ver hur NPC:ns beteende f\u00f6r\u00e4ndras.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/b4182359983cf573872dacc575af13dc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDiagrammet visar k\u00e4rnan i beslutsfattande f\u00f6r denna agent baserat p\u00e5 den aktuella situationen. Varje pil visar en \u00f6verg\u00e5ng mellan tillst\u00e5nd, om villkoret bredvid \u00e4r sant.<\/p>\n<p>Vid varje uppdatering kontrollerar vi agentens aktuella tillst\u00e5nd, g\u00e5r igenom listan \u00f6ver \u00f6verg\u00e5ngar, och om villkoren f\u00f6r \u00f6verg\u00e5ngen \u00e4r uppfyllda, antar han ett nytt tillst\u00e5nd. Till exempel kontrolleras det varje bild om den 10-sekunders timer har l\u00f6pt ut, och om ja, \u00f6verg\u00e5r vakten fr\u00e5n Inaktivitet till Patrullering. P\u00e5 samma s\u00e4tt kontrollerar tillst\u00e5ndet Angripande agentens h\u00e4lsa \u2014 om den \u00e4r l\u00e5g, \u00f6verg\u00e5r han till tillst\u00e5ndet Fly.<\/p>\n<p>Detta \u00e4r bearbetning av \u00f6verg\u00e5ngar mellan tillst\u00e5nd, men hur \u00e4r det med beteendet kopplat till sj\u00e4lva tillst\u00e5nden? N\u00e4r det g\u00e4ller att implementera det faktiska beteendet f\u00f6r ett specifikt tillst\u00e5nd finns det vanligtvis tv\u00e5 typer av \"hooks\", d\u00e4r vi tilldelar \u00e5tg\u00e4rder till FSM:<\/p>\n<ul>\n<li>\u00c5tg\u00e4rder som vi utf\u00f6r regelbundet f\u00f6r det aktuella tillst\u00e5ndet.<\/li>\n<li>\u00c5tg\u00e4rder som vi vidtar n\u00e4r vi \u00f6verg\u00e5r fr\u00e5n ett tillst\u00e5nd till ett annat.<\/li>\n<\/ul>\n<p>\nExempel f\u00f6r den f\u00f6rsta typen. I tillst\u00e5ndet Patrullering kommer agenten varje bild att r\u00f6ra sig l\u00e4ngs patrullv\u00e4gen. I tillst\u00e5ndet Angripande kommer agenten varje bild att f\u00f6rs\u00f6ka p\u00e5b\u00f6rja en attack eller \u00f6verg\u00e5 till ett tillst\u00e5nd n\u00e4r det \u00e4r m\u00f6jligt.<\/p>\n<p>F\u00f6r den andra typen kan vi \u00f6verv\u00e4ga \u00f6verg\u00e5ngen \"om fienden \u00e4r synlig och fienden \u00e4r f\u00f6r stark, s\u00e5 g\u00e5 in i tillst\u00e5ndet Finding Help. Agenten m\u00e5ste v\u00e4lja vart de ska g\u00e5 f\u00f6r hj\u00e4lp och spara denna information s\u00e5 att tillst\u00e5ndet Finding Help vet vart de ska v\u00e4nda sig. S\u00e5 snart hj\u00e4lpen har hittats, g\u00e5r agenten tillbaka till tillst\u00e5ndet Attacking. Vid det tillf\u00e4llet kanske de vill ber\u00e4tta f\u00f6r en allierad om hotet, s\u00e5 en \u00e5tg\u00e4rd kan intr\u00e4ffa: NotifyFriendOfThreat.<\/p>\n<p>Och \u00e5terigen kan vi se p\u00e5 detta system genom linsen av cykeln Sense\/Think\/Act. Sense uttrycks i de data som anv\u00e4nds av \u00f6verg\u00e5ngslogiken. Think \u2014 \u00e4r de \u00f6verg\u00e5ngar som \u00e4r tillg\u00e4ngliga i varje tillst\u00e5nd. Och Act sker genom \u00e5tg\u00e4rder som utf\u00f6rs periodiskt inom tillst\u00e5ndet eller vid \u00f6verg\u00e5ngar mellan tillst\u00e5nden.<\/p>\n<p>Ibland kan kontinuerlig \u00f6vervakning av \u00f6verg\u00e5ngsvillkor vara kostsam. Till exempel, om varje agent skulle utf\u00f6ra komplexa ber\u00e4kningar varje bildrute f\u00f6r att avg\u00f6ra om de ser fiender och om de borde g\u00e5 fr\u00e5n tillst\u00e5ndet Patrolling till Attacking \u2014 skulle det ta mycket processortid. <\/p>\n<p>Viktiga f\u00f6r\u00e4ndringar i v\u00e4rldens tillst\u00e5nd kan ses som h\u00e4ndelser som kommer att hanteras n\u00e4r de intr\u00e4ffar. Ist\u00e4llet f\u00f6r att FSM varje bildrute kontrollerar \u00f6verg\u00e5ngsvillkoret \"kan min agent se spelaren?\", kan vi konfigurera ett separat system f\u00f6r att utf\u00f6ra kontrollerna mer s\u00e4llan (till exempel 5 g\u00e5nger per sekund). Som resultat ges Player Seen n\u00e4r kontrollen godk\u00e4nns. <\/p>\n<p>Detta skickas vidare till FSM, som nu m\u00e5ste g\u00e5 in i tillst\u00e5ndet Player Seen event received och reaktionsm\u00e4ssigt agera. Det slutgiltiga beteendet \u00e4r detsamma, f\u00f6rutom en n\u00e4stan om\u00e4rkbar f\u00f6rdr\u00f6jning innan svaret ges. Resultatet \u00e4r att prestandan har f\u00f6rb\u00e4ttrats genom att separera en del av Sense till en separat del av programmet.<\/p>\n<h3>Hierarkisk \u00e4ndlig tillst\u00e5ndsmaskin<\/h3>\n<p>\nAtt arbeta med stora FSM \u00e4r dock inte alltid bekv\u00e4mt. Om vi vill expandera angreppstillst\u00e5ndet genom att ers\u00e4tta det med separata MeleeAttacking (n\u00e4rstrid) och RangedAttacking (distansangrepp), m\u00e5ste vi justera \u00f6verg\u00e5ngarna fr\u00e5n alla andra tillst\u00e5nd som leder till tillst\u00e5ndet Attacking (b\u00e5de nuvarande och framtida).<\/p>\n<p>Du har s\u00e4kert lagt m\u00e4rke till att v\u00e5rt exempel har m\u00e5nga dubblerade \u00f6verg\u00e5ngar. De flesta \u00f6verg\u00e5ngar i tillst\u00e5ndet Idling \u00e4r identiska med \u00f6verg\u00e5ngarna i tillst\u00e5ndet Patrolling. Det vore bra att undvika upprepningar, s\u00e4rskilt om vi l\u00e4gger till fler liknande tillst\u00e5nd. Det \u00e4r meningsfullt att gruppera Idling och Patrolling under en gemensam etikett \"icke-strid\", d\u00e4r det bara finns ett gemensamt upps\u00e4ttning \u00f6verg\u00e5ngar till stridstillst\u00e5nd. Om vi f\u00f6rest\u00e4ller oss denna etikett som ett tillst\u00e5nd, skulle Idling och Patrolling bli del-tillst\u00e5nd. Ett exempel p\u00e5 anv\u00e4ndning av en separat \u00f6verg\u00e5ngstabell f\u00f6r det nya icke-stridstillst\u00e5ndet:<\/p>\n<p><i>Huvudtillst\u00e5nd:<\/i><br \/>\n<img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/d86dd918acbe81b9bf22c2fb34aecee3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<i>Icke-stridstillst\u00e5nd:<\/i><br \/>\n<img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/9d5bc2053010a32c5f68d7f0192c04ed.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOch i form av ett diagram:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/0ccf95ecafa9ce2a6ea5b5b9833ddc4f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDet \u00e4r samma system, men med ett nytt icke-stridstillst\u00e5nd som inkluderar Idling och Patrolling. Med varje tillst\u00e5nd som inneh\u00e5ller FSM med del-tillst\u00e5nd (och dessa del-tillst\u00e5nd i sin tur inneh\u00e5ller sina egna FSM \u2014 och s\u00e5 vidare, s\u00e5 m\u00e5nga du beh\u00f6ver), f\u00e5r vi ett Hierarchical Finite State Machine eller HFSM (hierarkisk \u00e4ndlig automat). Genom att gruppera det icke-stridstillst\u00e5ndet har vi skapat en hel del on\u00f6diga \u00f6verg\u00e5ngar. Detsamma kan vi g\u00f6ra f\u00f6r eventuella nya tillst\u00e5nd med gemensamma \u00f6verg\u00e5ngar. Till exempel, om vi i framtiden ut\u00f6kar tillst\u00e5ndet Attacking till tillst\u00e5nden MeleeAttacking och MissileAttacking, kommer dessa vara del-tillst\u00e5nd som \u00f6verg\u00e5r mellan varandra baserat p\u00e5 avst\u00e5ndet till fienden och tillg\u00e5ngen p\u00e5 ammunition. Som ett resultat kan komplexa beteendemodeller och delmodeller representeras med minimalt av dubblerade \u00f6verg\u00e5ngar.<\/p>\n<h3>Beteendetr\u00e4d<\/h3>\n<p>\nMed HFSM skapas komplexa kombinationer av beteenden p\u00e5 ett enkelt s\u00e4tt. Det finns dock en liten sv\u00e5righet, att beslutsfattande i form av \u00f6verg\u00e5ngsregler \u00e4r n\u00e4ra kopplat till det aktuella tillst\u00e5ndet. Och i m\u00e5nga spel \u00e4r detta just vad som beh\u00f6vs. En noggrann anv\u00e4ndning av tillst\u00e5ndshierarkier kan minska antalet upprepningar vid \u00f6verg\u00e5ngar. Men ibland beh\u00f6vs regler som fungerar oberoende av vilket tillst\u00e5nd du \u00e4r i, eller som till\u00e4mpas i n\u00e4stan alla tillst\u00e5nd. Till exempel, om agentens h\u00e4lsa faller under 25%, vill du att den ska fly oavsett om den har varit i strid, slappnat av eller pratat \u2014 du m\u00e5ste l\u00e4gga till detta villkor i varje tillst\u00e5nd. Och om din designer senare vill \u00e4ndra tr\u00f6skeln f\u00f6r l\u00e5g h\u00e4lsa fr\u00e5n 25% till 10%, m\u00e5ste detta \u00e5tg\u00e4rdas igen.<\/p>\n<p>I idealfall beh\u00f6vs ett system d\u00e4r besluten om \"vilket tillst\u00e5nd man ska vara i\" ligger utanf\u00f6r sj\u00e4lva tillst\u00e5nden, s\u00e5 att f\u00f6r\u00e4ndringar endast beh\u00f6ver g\u00f6ras p\u00e5 ett st\u00e4lle utan att p\u00e5verka \u00f6verg\u00e5ngsvillkoren. H\u00e4r kommer beteendetr\u00e4d in i bilden.<\/p>\n<p>Det finns flera s\u00e4tt att implementera detta, men k\u00e4rnan \u00e4r ungef\u00e4r densamma och liknar ett beslutstr\u00e4d: algoritmen b\u00f6rjar med en \"rot\"-nod, och i tr\u00e4det finns noder som representerar antingen beslut eller handlingar. Det finns dock n\u00e5gra viktiga skillnader:<\/p>\n<ul>\n<li>Nu returnerar noderna ett av tre v\u00e4rden: Succeeded (om arbetet har slutf\u00f6rts), Failed (om det inte g\u00e5r att starta) eller Running (om det fortfarande k\u00f6rs och inget slutresultat har n\u00e5tts).<\/li>\n<li>Det finns inte l\u00e4ngre beslutsnoder f\u00f6r att v\u00e4lja mellan tv\u00e5 alternativ. Ist\u00e4llet finns det Decorator-noder, som har en enda undernod. Om de lyckas s\u00e5 utf\u00f6r de sin enda undernod.<\/li>\n<li>Noder som utf\u00f6r handlingar returnerar v\u00e4rdet Running f\u00f6r att representera de p\u00e5g\u00e5ende handlingarna.<\/li>\n<\/ul>\n<p>\nDenna lilla upps\u00e4ttning noder kan kombineras f\u00f6r att skapa m\u00e5nga komplexa beteendemodeller. L\u00e5t oss f\u00f6rest\u00e4lla oss HFSM:n fr\u00e5n det tidigare exemplet som ett beteendetr\u00e4d:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/5eaa5c725e4ada8285f16f95bb206d53.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMed denna struktur b\u00f6r det inte finnas n\u00e5gon tydlig \u00f6verg\u00e5ng fr\u00e5n tillst\u00e5nden Idling\/Patrolling till tillst\u00e5ndet Attacking eller n\u00e5got annat. Om fienden \u00e4r synlig och karakt\u00e4rens h\u00e4lsa \u00e4r l\u00e5g, kommer exekveringen att stanna p\u00e5 noden Fleeing, oavsett vilken nod den tidigare exekverade \u2014 Patrolling, Idling, Attacking eller n\u00e5gon annan.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/e1c1dcc2055174aa7cfa846364b1709a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nBeteendetr\u00e4d \u00e4r komplexa \u2014 det finns m\u00e5nga s\u00e4tt att konstruera dem, och att hitta r\u00e4tt kombination av dekorat\u00f6rer och kompositnoder kan vara utmanande. Det finns ocks\u00e5 fr\u00e5gor om hur ofta man ska kontrollera tr\u00e4det \u2014 vill vi g\u00e5 igenom varje del eller bara n\u00e4r ett av villkoren har f\u00f6r\u00e4ndrats? Hur ska man lagra tillst\u00e5ndet som relaterar till noderna \u2014 hur vet vi n\u00e4r vi har varit i tillst\u00e5ndet Idling i tio sekunder, eller hur vet vi vilka noder som exekverades senast f\u00f6r att korrekt hantera sekvensen?<\/p>\n<p>Det \u00e4r just d\u00e4rf\u00f6r det finns m\u00e5nga olika implementeringar. Till exempel har i vissa system decorator-noder ersatts med inbyggda dekoratorer. Dessa omv\u00e4rderar tr\u00e4det n\u00e4r dekoratorns villkor \u00e4ndras, hj\u00e4lper till att koppla ihop noder och erbjuder periodiska uppdateringar.<\/p>\n<h3>Utility-baserat system<\/h3>\n<p>\nVissa spel har m\u00e5nga olika mekaniker. Det \u00e4r \u00f6nskv\u00e4rt att de f\u00e5r alla f\u00f6rdelar av enkla och allm\u00e4nna regler f\u00f6r \u00f6verg\u00e5ngar, men inte n\u00f6dv\u00e4ndigtvis i form av ett fullt beteendetr\u00e4d. Ist\u00e4llet f\u00f6r att ha en tydlig upps\u00e4ttning val eller ett tr\u00e4d av m\u00f6jliga handlingar \u00e4r det enklare att l\u00e4ra sig alla handlingar och v\u00e4lja den mest l\u00e4mpliga i stunden.<\/p>\n<p>Ett system baserat p\u00e5 nytta hj\u00e4lper just i det h\u00e4r. Det \u00e4r ett system d\u00e4r agenten har m\u00e5nga olika handlingar och sj\u00e4lv v\u00e4ljer vilken han ska utf\u00f6ra, baserat p\u00e5 den relativa nyttan av varje av dem. H\u00e4r \u00e4r nyttan ett godtyckligt m\u00e5tt p\u00e5 hur viktigt eller \u00f6nskv\u00e4rt det \u00e4r f\u00f6r agenten att utf\u00f6ra denna handling. <\/p>\n<p>Den ber\u00e4knade nyttan av en handling baserat p\u00e5 det aktuella tillst\u00e5ndet och milj\u00f6n kan agenten kontrollera och v\u00e4lja den mest l\u00e4mpliga andra tillst\u00e5ndet n\u00e4r som helst. Detta liknar en FSM, f\u00f6rutom att \u00f6verg\u00e5ngarna definieras av bed\u00f6mningen f\u00f6r varje potentiellt tillst\u00e5nd, inklusive det aktuella. Observera att vi v\u00e4ljer den mest anv\u00e4ndbara handlingen f\u00f6r att g\u00e5 vidare (eller stanna kvar om vi redan har genomf\u00f6rt den). F\u00f6r mer variation kan detta vara ett viktat, men slumpm\u00e4ssigt val fr\u00e5n en liten lista.<\/p>\n<p>Systemet tilldelar ett godtyckligt intervall av nyttov\u00e4rden \u2014 till exempel fr\u00e5n 0 (helt o\u00f6nskat) till 100 (fullt \u00f6nskv\u00e4rt). Varje handling har en rad parametrar som p\u00e5verkar ber\u00e4kningen av detta v\u00e4rde. \u00c5terigen med v\u00e5rt exempel med vakten:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/085fb2c197bde93d78455d18e63c9c25.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n\u00d6verg\u00e5ngar mellan handlingar \u00e4r oklara \u2014 vilket tillst\u00e5nd som helst kan f\u00f6lja efter n\u00e5got annat. Prioriteringarna av handlingar ligger i de \u00e5terkommande nytta v\u00e4rdena. Om fienden \u00e4r synlig, och fienden \u00e4r stark, medan karakt\u00e4rens h\u00e4lsa \u00e4r l\u00e5g, kommer b\u00e5de Fleeing och FindingHelp att ge h\u00f6ga, icke-noll v\u00e4rden. Samtidigt kommer FindingHelp alltid att vara h\u00f6gre. P\u00e5 samma s\u00e4tt ger icke-stridshandlingar aldrig mer \u00e4n 50, s\u00e5 de kommer alltid att vara l\u00e4gre \u00e4n stridshandlingar. Detta m\u00e5ste beaktas n\u00e4r man skapar handlingar och ber\u00e4knar deras nytta.<\/p>\n<p>I v\u00e5rt exempel returnerar \u00e5tg\u00e4rder antingen ett fast konstant v\u00e4rde eller ett av tv\u00e5 fasta v\u00e4rden. Ett mer realistiskt system skulle f\u00f6resl\u00e5 att man returnerar en bed\u00f6mning fr\u00e5n ett kontinuerligt intervall av v\u00e4rden. Till exempel returnerar \u00e5tg\u00e4rden Fleeing h\u00f6gre nytta v\u00e4rden om agentens h\u00e4lsa \u00e4r l\u00e5g, medan \u00e5tg\u00e4rden Attacking returnerar l\u00e4gre v\u00e4rden om fienden \u00e4r f\u00f6r stark. P\u00e5 grund av detta har \u00e5tg\u00e4rden Fleeing prioritet \u00f6ver Attacking i alla situationer d\u00e4r agenten k\u00e4nner att han inte har tillr\u00e4cklig h\u00e4lsa f\u00f6r att besegra motst\u00e5ndaren. Detta m\u00f6jligg\u00f6r att \u00e4ndra prioriteringar baserat p\u00e5 ett antal kriterier, vilket g\u00f6r denna metod mer flexibel och variabel \u00e4n beteendetr\u00e4d eller FSM.<\/p>\n<p>Varje \u00e5tg\u00e4rd har m\u00e5nga villkor f\u00f6r att ber\u00e4kna programmet. Dessa kan skrivas p\u00e5 ett skriptspr\u00e5k eller som en serie matematiska formler. I The Sims, som modellerar karakt\u00e4rens dagliga rutiner, l\u00e4ggs en ytterligare niv\u00e5 av ber\u00e4kningar till - agenten f\u00e5r en rad \"motivationer\" som p\u00e5verkar nytta v\u00e4rderingarna. Om karakt\u00e4ren \u00e4r hungrig kommer han s\u00e5 sm\u00e5ningom att bli \u00e4nnu hungrigare, och nyttov\u00e4rdet f\u00f6r \u00e5tg\u00e4rden EatFood kommer att \u00f6ka tills karakt\u00e4ren utf\u00f6r den, vilket minskar hungerniv\u00e5n och \u00e5terst\u00e4ller v\u00e4rdet av EatFood till noll. <\/p>\n<p>Id\u00e9n att v\u00e4lja \u00e5tg\u00e4rder baserat p\u00e5 ett bed\u00f6mningssystem \u00e4r ganska enkel, s\u00e5 ett utility-baserat system kan anv\u00e4ndas som en del av AI: s beslutsprocesser snarare \u00e4n som en fullst\u00e4ndig ers\u00e4ttning. Beslutstr\u00e4det kan be om bed\u00f6mning av tv\u00e5 barnknutar och v\u00e4lja den som har h\u00f6gre v\u00e4rde. P\u00e5 liknande s\u00e4tt kan ett beteendetr\u00e4d ha en sammansatt nod Utility f\u00f6r att bed\u00f6ma nyttan av \u00e5tg\u00e4rder f\u00f6r att avg\u00f6ra vilken barnelement som ska utf\u00f6ras.<\/p>\n<h2>R\u00f6relse och navigering<\/h2>\n<p>\nI de tidigare exemplen hade vi en plattform som vi flyttade \u00e5t v\u00e4nster eller h\u00f6ger, och en v\u00e4ktare som patrullerade eller attackerade. Men hur hanterar vi sj\u00e4lva agentens r\u00f6relse \u00f6ver en viss tidsperiod? Hur st\u00e4ller vi in hastigheten, hur undviker vi hinder och hur planerar vi rutten om det \u00e4r sv\u00e5rare att n\u00e5 destinationen \u00e4n att bara r\u00f6ra sig i en rak linje? L\u00e5t oss ta en titt p\u00e5 detta.<\/p>\n<h3>Hantering<\/h3>\n<p>\nI b\u00f6rjan kommer vi att anta att varje agent har ett hastighetsv\u00e4rde, som inkluderar hur snabbt den r\u00f6r sig och i vilken riktning. Det kan m\u00e4tas i meter per sekund, kilometer per timme, pixlar per sekund, osv. Med minnet av cykeln Sinna\/T\u00e4nka\/Handla kan vi f\u00f6rest\u00e4lla oss att delen T\u00e4nka v\u00e4ljer hastigheten, medan delen Handla till\u00e4mpar den hastigheten p\u00e5 agenten. Vanligtvis finns det ett fysiksystem i spel som utf\u00f6r den h\u00e4r uppgiften \u00e5t dig, genom att studera hastighetsv\u00e4rdet f\u00f6r varje objekt och justera det. D\u00e4rf\u00f6r kan vi \u00f6verl\u00e5ta AI:t en enda uppgift \u2013 att avg\u00f6ra vilken hastighet agenten ska ha. Om vi vet var agenten ska vara, m\u00e5ste vi flytta den i r\u00e4tt riktning med den angivna hastigheten. En mycket trivial ekvation:<\/p>\n<p><i>desired_travel = destination_position \u2013 agent_position<\/i><\/p>\n<p>F\u00f6rest\u00e4ll dig en 2D-v\u00e4rld. Agenten befinner sig vid punkten (-2,-2), destinationen ligger n\u00e5gonstans nordost i punkten (30, 20), och den n\u00f6dv\u00e4ndiga v\u00e4gen f\u00f6r agenten att komma dit \u00e4r (32, 22). Anta att dessa positioner m\u00e4ts i meter \u2013 om vi antar att agentens hastighet \u00e4r 5 meter per sekund, kommer vi att skala v\u00e5r r\u00f6relsevektor och f\u00e5 en hastighet p\u00e5 ungef\u00e4r (4.12, 2.83). Med dessa parametrar skulle agenten n\u00e5 destinationen efter n\u00e4stan 8 sekunder.<\/p>\n<p>V\u00e4rden kan r\u00e4knas om n\u00e4r som helst. Om agenten var halvv\u00e4gs till m\u00e5let, skulle r\u00f6relsen vara h\u00e4lften av l\u00e4ngden, men eftersom agentens maximala hastighet \u00e4r 5 m\/s (vilket vi best\u00e4mde tidigare), kommer hastigheten att vara densamma. Detta fungerar ocks\u00e5 f\u00f6r r\u00f6rliga m\u00e5l, vilket g\u00f6r det m\u00f6jligt f\u00f6r agenten att g\u00f6ra sm\u00e5 justeringar n\u00e4r de r\u00f6r sig.<\/p>\n<p>Men vi vill ha mer variation \u2013 till exempel att l\u00e5ngsamt \u00f6ka hastigheten f\u00f6r att simulera en karakt\u00e4r som r\u00f6r sig fr\u00e5n stillast\u00e5ende till l\u00f6pande. Samma sak kan g\u00f6ras i slutet innan stopp. Dessa funktioner kallas steering behaviours, d\u00e4r varje har specifika namn: Seek (s\u00f6k), Flee (fly), Arrival (ankomst) osv. Id\u00e9n \u00e4r att accelerationer kan till\u00e4mpas p\u00e5 agentens hastighet, baserat p\u00e5 en j\u00e4mf\u00f6relse mellan agentens position och nuvarande hastighet med destinationen, f\u00f6r att anv\u00e4nda olika s\u00e4tt att r\u00f6ra sig mot m\u00e5let.<\/p>\n<p>Varje beteende har ett n\u00e5got annat syfte. Seek och Arrival \u00e4r s\u00e4tt att flytta agenten till destinationspunkten. Obstacle Avoidance (undvikande av hinder) och Separation (separation) justerar agentens r\u00f6relse f\u00f6r att kringg\u00e5 hinder p\u00e5 v\u00e4gen till m\u00e5let. Alignment (samordning) och Cohesion (sammanslutning) h\u00e5ller agenterna tillsammans n\u00e4r de r\u00f6r sig. Ett antal olika styrningsbeteenden kan summeras f\u00f6r att f\u00e5 en enda v\u00e4gvektor med h\u00e4nsyn till alla faktorer. En agent anv\u00e4nder beteendena Arrival, Separation och Obstacle Avoidance f\u00f6r att h\u00e5lla sig borta fr\u00e5n v\u00e4ggar och andra agenter. Denna metod fungerar bra i \u00f6ppna milj\u00f6er utan \u00f6verfl\u00f6diga detaljer. <\/p>\n<p>Under sv\u00e5rare f\u00f6rh\u00e5llanden fungerar sammanslagningen av olika beteenden s\u00e4mre \u2014 till exempel kan agenten fastna i v\u00e4ggen p\u00e5 grund av konflikten mellan Arrival och Obstacle Avoidance. D\u00e4rf\u00f6r m\u00e5ste vi \u00f6verv\u00e4ga alternativ som \u00e4r mer komplexa \u00e4n bara en enkel summering av alla v\u00e4rden. En s\u00e5dan metod \u00e4r: ist\u00e4llet f\u00f6r att summera resultaten av varje beteende kan vi \u00f6verv\u00e4ga r\u00f6relser i olika riktningar och v\u00e4lja den b\u00e4sta. <\/p>\n<p>Men i en komplex milj\u00f6 med \u00e5terv\u00e4ndsgr\u00e4nder och val av vilken riktning man ska g\u00e5, beh\u00f6ver vi n\u00e5got \u00e4nnu mer avancerat.<\/p>\n<h3>S\u00f6kv\u00e4g<\/h3>\n<p>\nSteering behaviours \u00e4r utm\u00e4rkta f\u00f6r enkel r\u00f6relse p\u00e5 \u00f6ppen mark (fotbollsplan eller arena), d\u00e4r v\u00e4gen fr\u00e5n A till B \u00e4r en rak linje med sm\u00e5 avvikelser runt hinder. F\u00f6r komplexa rutter beh\u00f6ver vi pathfinding (s\u00f6kv\u00e4g), som \u00e4r ett s\u00e4tt att utforska v\u00e4rlden och fatta beslut om rutten genom den.<\/p>\n<p>Det enklaste s\u00e4ttet \u00e4r att l\u00e4gga ett rutn\u00e4t \u00f6ver varje ruta intill agenten och bed\u00f6ma i vilka av dem det \u00e4r till\u00e5tet att r\u00f6ra sig. Om n\u00e5gon av dem \u00e4r en destination, f\u00f6lj v\u00e4gen fr\u00e5n varje ruta tillbaka till f\u00f6reg\u00e5ende, tills du n\u00e5r b\u00f6rjan. Det \u00e4r v\u00e4gen. Om inte upprepa processen med n\u00e4rmaste andra rutor, tills du hittar destinationen eller rutorna tar slut (detta inneb\u00e4r att det inte finns n\u00e5gon m\u00f6jlig v\u00e4g). Detta kallas formellt f\u00f6r Breadth-First Search eller BFS (bredd f\u00f6rst-s\u00f6kning). P\u00e5 varje steg tittar det \u00e5t alla h\u00e5ll (d\u00e4rav bredd). S\u00f6komr\u00e5det liknar en v\u00e5gfront som r\u00f6r sig tills den n\u00e5r m\u00e5let \u2014 s\u00f6komr\u00e5det expanderar f\u00f6r varje steg tills slutpunkten inkluderas, varefter v\u00e4gen tillbaka kan sp\u00e5ras till b\u00f6rjan.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/d367e62bc53033b05388538649853a41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSom ett resultat f\u00e5r du en lista \u00f6ver rutor som utg\u00f6r den \u00f6nskade v\u00e4gen. Detta \u00e4r v\u00e4gen (d\u00e4rav pathfinding) \u2014 en lista \u00f6ver st\u00e4llen som agenten kommer att bes\u00f6ka p\u00e5 v\u00e4g till destinationen.<\/p>\n<p>Eftersom vi k\u00e4nner till positionen f\u00f6r varje ruta i v\u00e4rlden kan vi anv\u00e4nda steering behaviors f\u00f6r att r\u00f6ra oss l\u00e4ngs v\u00e4gen \u2014 fr\u00e5n nod 1 till nod 2, sedan fr\u00e5n nod 2 till nod 3 och s\u00e5 vidare. Det enklaste alternativet \u00e4r att rikta in sig p\u00e5 mitten av n\u00e4sta ruta, men det \u00e4r \u00e4nnu b\u00e4ttre att stanna vid mitten av kanten mellan den nuvarande rutan och den n\u00e4sta. Detta g\u00f6r att agenten kan sk\u00e4ra h\u00f6rn vid branta sv\u00e4ngar.<\/p>\n<p>BFS-algoritmen har \u00e4ven nackdelar \u2014 den utforskar lika m\u00e5nga rutor i \"fel\" riktning som i \"r\u00e4tt\". H\u00e4r framtr\u00e4der en mer avancerad algoritm kallad A* (A star). Den fungerar p\u00e5 liknande s\u00e4tt men ist\u00e4llet f\u00f6r att blint utforska grannrutor (sen grannarnas grannar, sedan grannarnas grannars grannar och s\u00e5 vidare), samlar den noder i en lista och sorterar dem s\u00e5 att n\u00e4sta utforskade nod alltid \u00e4r den som leder till den kortaste v\u00e4gen. Noder sorteras baserat p\u00e5 en heuristik som beaktar tv\u00e5 saker \u2014 \"kostnaden\" f\u00f6r den hypotetiska v\u00e4gen till den \u00f6nskade rutan (inklusive eventuella r\u00f6rlighetskostnader) och en bed\u00f6mning av hur l\u00e5ngt denna ruta \u00e4r fr\u00e5n destinationen (och flyttar s\u00f6kningen i r\u00e4tt riktning).<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/1cab4f53fa5af6b31d352c7bcf453d7e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI det h\u00e4r exemplet visar vi hur agenten unders\u00f6ker ett avsnitt i taget, varje g\u00e5ng v\u00e4ljer det det mest lovande grannf\u00e4ltet. Den resulterande v\u00e4gen \u00e4r densamma som vid BFS, men under processen har f\u00e4rre avsnitt \u00f6verv\u00e4gts - vilket \u00e4r av stor betydelse f\u00f6r spelprestanda.<\/p>\n<h3>R\u00f6relse utan rutn\u00e4t<\/h3>\n<p>\nMen de flesta spel \u00e4r inte uppbyggda p\u00e5 ett rutn\u00e4t, och ofta g\u00e5r det inte att skapa ett utan att kompromissa med verklighetstrogenhet. Det kr\u00e4vs kompromisser. Vilka storlekar b\u00f6r avsnitten ha? F\u00f6r stora - och de kan inte korrekt representera smala korridorer eller sv\u00e4ngar, f\u00f6r sm\u00e5 - det kommer att vara f\u00f6r m\u00e5nga avsnitt att s\u00f6ka igenom, vilket kan ta mycket tid.<\/p>\n<p>Det f\u00f6rsta att f\u00f6rst\u00e5 \u00e4r att ett rutn\u00e4t ger oss en graf av sammankopplade noder. A* och BFS-algoritmer fungerar faktiskt p\u00e5 grafer och bryr sig \u00f6verhuvudtaget inte om v\u00e5rt rutn\u00e4t. Vi skulle kunna placera noder var som helst i spelv\u00e4rlden: om det finns en f\u00f6rbindelse mellan tv\u00e5 sammankopplade noder, s\u00e5v\u00e4l som mellan start- och slutpunkt och minst en av noderna - algoritmen kommer att fungera lika bra som tidigare. Detta kallas ofta en waypoint-system, eftersom varje nod representerar en betydelsefull position i v\u00e4rlden, vilket kan vara en del av ett antal hypotetiska v\u00e4gar.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/d87e9d4bb2a2fc713d32abc158506eaa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Exempel 1: en nod i varje avsnitt. S\u00f6kningen b\u00f6rjar fr\u00e5n noden d\u00e4r agenten befinner sig och slutar i noden f\u00f6r det avsnitt som beh\u00f6vs.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/b535a5db805efdc427d7c5724b866982.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Exempel 2: en mindre upps\u00e4ttning noder (waypoints). S\u00f6kningen b\u00f6rjar i avsnittet med agenten, passerar igenom n\u00f6dv\u00e4ndiga noder och forts\u00e4tter sedan till m\u00e5let.<\/i><\/p>\n<p>Detta \u00e4r ett ganska flexibelt och kraftfullt system. Men det kr\u00e4vs viss f\u00f6rsiktighet n\u00e4r det g\u00e4ller beslut om var och hur man placerar waypoints, annars kan agenterna helt enkelt missa den n\u00e4rmaste punkten och inte kunna b\u00f6rja sin v\u00e4g. Det skulle vara enklare om vi kunde automatiskt placera waypoints baserat p\u00e5 v\u00e4rldens geometri.<\/p>\n<p>H\u00e4r kommer navigation mesh eller navmesh (navigationsn\u00e4t) in. Detta \u00e4r vanligtvis ett 2D-n\u00e4t av trianglar som l\u00e4ggs p\u00e5 v\u00e4rldens geometri - \u00f6verallt d\u00e4r agenterna har till\u00e5telse att g\u00e5. Varje triangel i n\u00e4tet blir en nod i grafen och har upp till tre angr\u00e4nsande trianglar som blir grannnoder i grafen. <\/p>\n<p>Den h\u00e4r bilden \u00e4r ett exempel fr\u00e5n Unity-motorn \u2013 den analyserade geometrin i v\u00e4rlden och skapade en navmesh (visad i ljusbl\u00e5tt p\u00e5 sk\u00e4rmdumpen). Varje polygon i navmesh \u00e4r ett omr\u00e5de d\u00e4r en agent kan st\u00e5 eller r\u00f6ra sig fr\u00e5n en polygon till en annan. I det h\u00e4r exemplet \u00e4r polygonerna mindre \u00e4n de v\u00e5ningar d\u00e4r de ligger \u2013 detta g\u00f6rs f\u00f6r att ta h\u00e4nsyn till agentens storlek, som kan str\u00e4cka sig utanf\u00f6r dess nominella position.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/845705ba7b9a9d469203aedf7942da41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVi kan s\u00f6ka efter en rutt genom detta n\u00e4tverk, \u00e5terigen med hj\u00e4lp av A*-algoritmen. Detta ger oss en n\u00e4stan perfekt rutt i v\u00e4rlden som tar h\u00e4nsyn till all geometri och samtidigt inte kr\u00e4ver on\u00f6diga noder eller skapande av waypoints.<\/p>\n<p>Pathfinding \u00e4r ett f\u00f6r stort \u00e4mne f\u00f6r att t\u00e4ckas av ett enda avsnitt. Om du vill studera det mer detaljerat kan detta hj\u00e4lpa dig <noindex><a rel=\"nofollow\" href=\"https:\/\/www.redblobgames.com\/pathfinding\/a-star\/introduction.html\">Amita Patels webbplats<\/a><\/noindex>.<\/p>\n<h2>Planering<\/h2>\n<p>\nVi har bekr\u00e4ftat med pathfinding att det ibland inte r\u00e4cker med att bara v\u00e4lja en riktning och g\u00e5 \u2013 vi m\u00e5ste v\u00e4lja en rutt och g\u00f6ra n\u00e5gra sv\u00e4ngar f\u00f6r att n\u00e5 v\u00e5rt m\u00e5l. Vi kan sammanfatta denna id\u00e9: att n\u00e5 ett m\u00e5l \u00e4r inte bara n\u00e4sta steg, utan en hel sekvens d\u00e4r vi ibland m\u00e5ste titta fram\u00e5t flera steg f\u00f6r att veta hur det f\u00f6rsta ska vara. Detta kallas planering. Pathfinding kan betraktas som en av flera till\u00e4gg till planering. Ur v\u00e5rt perspektiv av cykeln Sense\/Think\/Act \u00e4r detta d\u00e4r Think-planerade delar Act f\u00f6r framtiden.<\/p>\n<p>L\u00e5t oss ta ett exempel fr\u00e5n kortspelet Magic: The Gathering. Vi spelar f\u00f6rst med f\u00f6ljande kort i handen:<\/p>\n<ul>\n<li>Swamp \u2013 ger 1 svart mana (landskort).<\/li>\n<li>Forest \u2013 ger 1 gr\u00f6n mana (landskort).<\/li>\n<li>Fugitive Wizard \u2013 kr\u00e4ver 1 bl\u00e5 mana f\u00f6r att \u00e5kalla.<\/li>\n<li>Elvish Mystic \u2013 kr\u00e4ver 1 gr\u00f6n mana f\u00f6r att \u00e5kalla.<\/li>\n<\/ul>\n<p>\nVi ignorerar de tre \u00e5terst\u00e5ende korten f\u00f6r enkelhetens skull. Enligt reglerna f\u00e5r spelaren spela ett landkort per tur, de kan \"tappa\" detta kort f\u00f6r att extrahera mana fr\u00e5n det och sedan anv\u00e4nda besv\u00e4rjelser (inklusive \u00e5kallande av varelser) baserat p\u00e5 m\u00e4ngden mana. I den h\u00e4r situationen vet den m\u00e4nskliga spelaren att de beh\u00f6ver spela Forest, \"tappa\" 1 gr\u00f6n mana och sedan \u00e5kalla Elvish Mystic. Men hur ska spelarkompjuter f\u00f6rst\u00e5 detta?<\/p>\n<h3>Enkel planering<\/h3>\n<p>\nDet triviala tillv\u00e4gag\u00e5ngss\u00e4ttet \u00e4r att prova varje \u00e5tg\u00e4rd i tur och ordning tills inga l\u00e4mpliga alternativ \u00e5terst\u00e5r. N\u00e4r AI tittar p\u00e5 korten ser det att det kan spela Swamp. Och det spelar det. Finns det n\u00e5gra andra \u00e5tg\u00e4rder kvar att g\u00f6ra den h\u00e4r turen? Det kan inte spela varken Elvish Mystic eller Fugitive Wizard, eftersom det kr\u00e4vs gr\u00f6n och bl\u00e5 mana f\u00f6r att spela dem och Swamp ger endast svart mana. Och den kan inte spela Forest eftersom den redan har spelat Swamp. S\u00e5 spel-IAn har f\u00f6ljt reglerna, men gjort det d\u00e5ligt. Det kan f\u00f6rb\u00e4ttras.<\/p>\n<p>Planering kan hitta en lista \u00f6ver \u00e5tg\u00e4rder som leder spelet till det \u00f6nskade tillst\u00e5ndet. Precis som varje ruta p\u00e5 v\u00e4gen hade grannar (i pathfinding) har varje \u00e5tg\u00e4rd i planen ocks\u00e5 grannar eller efterf\u00f6ljande \u00e5tg\u00e4rder. Vi kan s\u00f6ka efter dessa \u00e5tg\u00e4rder och f\u00f6ljande \u00e5tg\u00e4rder tills vi n\u00e5r det \u00f6nskade tillst\u00e5ndet.<\/p>\n<p>I v\u00e5rt exempel \u00e4r det \u00f6nskade resultatet \"\u00e5beropa en varelse om m\u00f6jligt\". I b\u00f6rjan av turen ser vi bara tv\u00e5 m\u00f6jliga \u00e5tg\u00e4rder som \u00e4r till\u00e5tna enligt spelets regler:<\/p>\n<p><i>1. Spela Swamp (resultat: Swamp i spelet)<br \/>\n2. Spela Forest (resultat: Forest i spelet)<\/i><\/p>\n<p>Varje \u00e5tg\u00e4rd som vidtas kan leda till ytterligare \u00e5tg\u00e4rder och st\u00e4nga andra, beroende p\u00e5 spelets regler. T\u00e4nk dig att vi spelade Swamp \u2014 det skulle ta bort Swamp som steg (vi har redan spelat det), det skulle ocks\u00e5 ta bort Forest (eftersom man f\u00e5r spela en landkort per tur enligt reglerna). Efter detta l\u00e4gger AI till som n\u00e4sta steg \u2014 att f\u00e5 1 svart mana, eftersom det inte finns n\u00e5gra andra alternativ. Om den g\u00e5r vidare och v\u00e4ljer att aktivera Swamp, f\u00e5r den 1 enhet svart mana och kan ingenting g\u00f6ra med den.<\/p>\n<p><i>1. Spela Swamp (resultat: Swamp i spelet)<br \/>\n 1.1 \u00abAktivera\u00bb Swamp (resultat: Swamp \u00abaktiverad\u00bb, +1 enhet svart mana)<br \/>\n Inga tillg\u00e4ngliga \u00e5tg\u00e4rder \u2013 SLUT<br \/>\n2. Spela Forest (resultat: Forest i spelet)<\/i><\/p>\n<p>Listan \u00f6ver \u00e5tg\u00e4rder blev kort, vi har k\u00f6rt fast. Vi upprepar processen f\u00f6r n\u00e4sta \u00e5tg\u00e4rd. Vi spelar Forest, \u00f6ppnar \u00e5tg\u00e4rden \"f\u00e5 1 gr\u00f6n mana\", vilket i sin tur \u00f6ppnar den tredje \u00e5tg\u00e4rden \u2014 \u00e5kalla Elvish Mystic.<\/p>\n<p><i>1. Spela Swamp (resultat: Swamp i spelet)<br \/>\n 1.1 \u00abAktivera\u00bb Swamp (resultat: Swamp \u00abaktiverad\u00bb, +1 enhet svart mana)<br \/>\n Inga tillg\u00e4ngliga \u00e5tg\u00e4rder \u2013 SLUT<br \/>\n2. Spela Forest (resultat: Forest i spelet)<br \/>\n 2.1 \u00abAktivera\u00bb Forest (resultat: Forest \u00abaktiverad\u00bb, +1 enhet gr\u00f6n mana)<br \/>\n 2.1.1 \u00c5kalla Elvish Mystic (resultat: Elvish Mystic i spelet, -1 enhet gr\u00f6n mana)<br \/>\n Inga tillg\u00e4ngliga \u00e5tg\u00e4rder \u2013 SLUT<\/i><\/p>\n<p>Slutligen har vi studerat alla m\u00f6jliga \u00e5tg\u00e4rder och hittat en plan f\u00f6r att \u00e5kalla en varelse.<\/p>\n<p>Detta \u00e4r ett mycket f\u00f6renklat exempel. Det \u00e4r \u00f6nskv\u00e4rt att v\u00e4lja den b\u00e4sta m\u00f6jliga planen, snarare \u00e4n n\u00e5gon som uppfyller vissa kriterier. Vanligtvis kan man bed\u00f6ma potentiella planer baserat p\u00e5 slutresultatet eller den sammanlagda vinsten fr\u00e5n att genomf\u00f6ra dem. Man kan ge sig sj\u00e4lv 1 po\u00e4ng f\u00f6r att spela en landkort och 3 po\u00e4ng f\u00f6r att kalla p\u00e5 en varelse. Att spela Swamp skulle ge 1 po\u00e4ng. Men att spela Forest \u2192 Tappa Forest \u2192 kalla p\u00e5 Elvish Mystic \u2014 skulle ge totalt 4 po\u00e4ng. <\/p>\n<p>S\u00e5 h\u00e4r fungerar planering i Magic: The Gathering, men samma logik kan till\u00e4mpas i andra situationer. Till exempel, flytta en bonde f\u00f6r att frig\u00f6ra utrymme f\u00f6r en l\u00f6parens drag i schack. Eller g\u00f6mma sig bakom en v\u00e4gg f\u00f6r att s\u00e4kert skjuta i XCOM s\u00e5. I allm\u00e4nhet f\u00f6rst\u00e5r du po\u00e4ngen.<\/p>\n<h3>F\u00f6rb\u00e4ttrad planering<\/h3>\n<p>\nIbland finns det f\u00f6r m\u00e5nga potentiella \u00e5tg\u00e4rder f\u00f6r att \u00f6verv\u00e4ga varje m\u00f6jlig variant. \u00c5terigen till exemplet med Magic: The Gathering: antag att det i spelet finns flera landkort och varelser i din hand \u2014 antalet m\u00f6jliga dragkombinationer kan uppg\u00e5 till tiotals. Det finns flera l\u00f6sningar p\u00e5 problemet.<\/p>\n<p>Det f\u00f6rsta s\u00e4ttet \u00e4r backwards chaining (bak\u00e5t kedjande). Ist\u00e4llet f\u00f6r att g\u00e5 igenom alla kombinationer, \u00e4r det b\u00e4ttre att b\u00f6rja med det slutliga resultatet och f\u00f6rs\u00f6ka hitta en direkt v\u00e4g. Ist\u00e4llet f\u00f6r att g\u00e5 fr\u00e5n roten av tr\u00e4det till ett visst blad, r\u00f6r vi oss bak\u00e5t \u2014 fr\u00e5n bladet till roten. Denna metod \u00e4r enklare och snabbare.<\/p>\n<p>Om motst\u00e5ndaren har 1 h\u00e4lsa, kan man hitta en plan \"att orsaka 1 eller fler skador\". F\u00f6r att uppn\u00e5 detta m\u00e5ste en serie villkor uppfyllas: <\/p>\n<p>1. Skadan kan orsakas av en trollformel \u2014 den m\u00e5ste vara p\u00e5 handen.<br \/>\n2. F\u00f6r att spela trollformeln \u2014 beh\u00f6vs mana.<br \/>\n3. F\u00f6r att f\u00e5 mana \u2014 m\u00e5ste man spela ett landkort.<br \/>\n4. F\u00f6r att spela ett landkort \u2014 m\u00e5ste man ha det i handen.<\/p>\n<p>Ett annat s\u00e4tt \u00e4r best-first search (b\u00e4sta f\u00f6rst s\u00f6kning). Ist\u00e4llet f\u00f6r att g\u00e5 igenom alla v\u00e4gar, v\u00e4ljer vi den mest passande. Detta s\u00e4tt ger oftast en optimal plan utan on\u00f6diga s\u00f6kningar. A* \u00e4r en typ av b\u00e4sta f\u00f6rsta s\u00f6kning \u2014 genom att unders\u00f6ka de mest lovande v\u00e4garna fr\u00e5n b\u00f6rjan kan den redan hitta den b\u00e4sta v\u00e4gen utan att beh\u00f6va kontrollera andra alternativ.<\/p>\n<p>En intressant och alltmer popul\u00e4r variant av best-first search \u00e4r Monte Carlo Tree Search. Ist\u00e4llet f\u00f6r att gissa vilka planer som \u00e4r b\u00e4ttre \u00e4n andra vid valet av varje efterf\u00f6ljande \u00e5tg\u00e4rd, v\u00e4ljer algoritmen slumpm\u00e4ssiga efterf\u00f6ljare vid varje steg tills den n\u00e5r slutet (n\u00e4r planen resulterar i vinst eller f\u00f6rlust). Slutresultatet anv\u00e4nds sedan f\u00f6r att \u00f6ka eller minska bed\u00f6mningen av \"vikten\" av de f\u00f6reg\u00e5ende alternativen. Genom att upprepa denna process flera g\u00e5nger ger algoritmen en bra uppskattning av vilket n\u00e4sta steg som \u00e4r b\u00e4ttre, \u00e4ven om situationen f\u00f6r\u00e4ndras (om motst\u00e5ndaren vidtar \u00e5tg\u00e4rder f\u00f6r att hindra spelaren). <\/p>\n<p>I ber\u00e4ttelsen om planering i spel kan vi inte undvika Goal-Oriented Action Planning eller GOAP (m\u00e5linriktad handlingsplanering). Detta \u00e4r en mycket anv\u00e4nd och diskuterad metod, men f\u00f6rutom n\u00e5gra distinkta detaljer \u00e4r det i grunden en metod f\u00f6r backwards chaining, som vi redan har pratat om. Om uppgiften \u00e4r att \"eliminera spelaren\", och spelaren g\u00f6mmer sig, kan planen vara: kasta granat \u2192 ta fram den \u2192 kasta.<\/p>\n<p>Det finns vanligtvis flera m\u00e5l, var och en med sin egen prioritet. Om m\u00e5let med h\u00f6gst prioritet inte kan uppfyllas (ingen kombination av \u00e5tg\u00e4rder skapar planen \"eliminera spelaren\" eftersom spelaren inte \u00e4r synlig), kommer AI:n att \u00e5terg\u00e5 till m\u00e5l med l\u00e4gre prioritet.<\/p>\n<h2>Inl\u00e4rning och anpassning<\/h2>\n<p>\nVi har redan n\u00e4mnt att spel-AI vanligtvis inte anv\u00e4nder maskininl\u00e4rning, eftersom det inte passar f\u00f6r att styra agenter i realtid. Men det betyder inte att man inte kan l\u00e5na n\u00e5got fr\u00e5n detta omr\u00e5de. Vi vill ha en motst\u00e5ndare i en shooter som vi kan l\u00e4ra oss n\u00e5got av. Till exempel, att f\u00e5 veta om de b\u00e4sta positionerna p\u00e5 kartan. Eller en motst\u00e5ndare i en fighting som skulle blockera ofta anv\u00e4nda komboattacker, vilket motiverar spelaren att anv\u00e4nda andra. S\u00e5 maskininl\u00e4rning kan vara mycket anv\u00e4ndbart i s\u00e5dana situationer.<\/p>\n<h3>Statistik och sannolikheter<\/h3>\n<p>\nInnan vi g\u00e5r vidare till mer komplexa exempel, l\u00e5t oss \u00f6verv\u00e4ga hur l\u00e5ngt vi kan g\u00e5 genom att ta n\u00e5gra enkla m\u00e4tningar och anv\u00e4nda dem f\u00f6r beslutsfattande. Till exempel, strategin i realtid \u2013 hur kan vi best\u00e4mma om en spelare kan starta en attack inom de f\u00f6rsta minuterna av spelet och vilken f\u00f6rsvar som ska f\u00f6rberedas mot detta? Vi kan studera spelarens tidigare erfarenheter f\u00f6r att f\u00f6rst\u00e5 vilken potentiell reaktion som kan komma i framtiden. L\u00e5t oss b\u00f6rja med att vi inte har n\u00e5gon s\u00e5dant utg\u00e5ngsmaterial, men vi kan samla det \u2013 varje g\u00e5ng AI spelar mot en m\u00e4nniska kan den registrera tiden f\u00f6r den f\u00f6rsta attacken. Efter n\u00e5gra sessioner kommer vi att f\u00e5 ett genomsnittligt v\u00e4rde f\u00f6r hur l\u00e5ng tid det tar innan spelaren attackerar i framtiden.<\/p>\n<p>Det finns ocks\u00e5 ett problem med medelv\u00e4rden: om en spelare har \"rushat\" 20 g\u00e5nger och spelat l\u00e5ngsamt 20 g\u00e5nger, s\u00e5 kommer de n\u00f6dv\u00e4ndiga v\u00e4rdena att ligga n\u00e5gonstans i mitten, vilket inte ger oss n\u00e5got anv\u00e4ndbart. En l\u00f6sning \u00e4r att begr\u00e4nsa ing\u00e5ngsdata \u2013 man kan \u00f6verv\u00e4ga de senaste 20 styckena.<\/p>\n<p>En liknande metod anv\u00e4nds f\u00f6r att bed\u00f6ma sannolikheten f\u00f6r vissa handlingar, som antar att spelarens tidigare preferenser kommer att vara desamma i framtiden. Om en spelare attackerar oss fem g\u00e5nger med en eldboll, tv\u00e5 g\u00e5nger med blixt och en g\u00e5ng i n\u00e4rstrid, \u00e4r det uppenbart att han f\u00f6redrar eldboll. L\u00e5t oss extrapolera och se sannolikheten f\u00f6r anv\u00e4ndning av olika vapen: eldboll=62,5%, blixt=25% och n\u00e4rstrid=12,5%. V\u00e5r spel-AI beh\u00f6ver f\u00f6rbereda sig p\u00e5 att skydda sig mot eld.<\/p>\n<p>En annan intressant metod \u00e4r att anv\u00e4nda Naive Bayes Classifier (naiv bayesisk klassificerare) f\u00f6r att studera stora m\u00e4ngder ing\u00e5ngsdata och klassificera situationen s\u00e5 att AI reagerar p\u00e5 r\u00e4tt s\u00e4tt. Bayesianska klassificerare \u00e4r mest k\u00e4nda f\u00f6r sin anv\u00e4ndning i skr\u00e4ppostfilter f\u00f6r e-post. D\u00e4r unders\u00f6ker de ord, j\u00e4mf\u00f6r dem med var dessa ord tidigare f\u00f6rekommit (i skr\u00e4ppost eller inte), och drar slutsatser om inkommande e-post. Vi kan g\u00f6ra samma sak \u00e4ven med mindre ing\u00e5ngsdata. Baserat p\u00e5 all anv\u00e4ndbar information som AI ser (till exempel vilka fiendens enheter som skapades, eller vilka besv\u00e4rjelser de anv\u00e4nder, eller vilka teknologier de forskar p\u00e5), och det slutliga resultatet (krig eller fred, \"rush\" eller f\u00f6rsvara, osv.) \u2013 v\u00e4ljer vi det beteende som AI ska ha.<\/p>\n<p>Alla dessa s\u00e4tt att l\u00e4ra sig \u00e4r tillr\u00e4ckliga, men det \u00e4r att f\u00f6redra att anv\u00e4nda dem baserat p\u00e5 data fr\u00e5n tester. AI kommer att l\u00e4ra sig att anpassa sig till olika strategier som dina playtestare har anv\u00e4nt. AI som anpassar sig efter spelaren efter sl\u00e4ppet kan bli f\u00f6ruts\u00e4gbar eller \u00e5 sin sida f\u00f6r sv\u00e5r att besegra.<\/p>\n<h3>Anpassning baserat p\u00e5 v\u00e4rden<\/h3>\n<p>\nMed tanke p\u00e5 inneh\u00e5llet i v\u00e5r spelv\u00e4rld och regler kan vi \u00e4ndra upps\u00e4ttningen v\u00e4rden som p\u00e5verkar beslutsfattandet, ist\u00e4llet f\u00f6r att bara anv\u00e4nda indata. Vi g\u00f6r s\u00e5 h\u00e4r:<\/p>\n<ul>\n<li>L\u00e5t AI samla in data om v\u00e4rldens tillst\u00e5nd och nyckelh\u00e4ndelser under spelets g\u00e5ng (som angivet ovan).<\/li>\n<li>Vi \u00e4ndrar n\u00e5gra viktiga v\u00e4rden baserat p\u00e5 dessa data.<\/li>\n<li>Vi genomf\u00f6r v\u00e5ra beslut baserat p\u00e5 bearbetningen eller utv\u00e4rderingen av dessa v\u00e4rden.<\/li>\n<\/ul>\n<p>\nTill exempel, agenten har flera rum att v\u00e4lja p\u00e5 i en f\u00f6rstapersonsskjutare-karta. Varje rum har ett v\u00e4rde som avg\u00f6r hur \u00f6nskv\u00e4rt det \u00e4r att bes\u00f6ka. AI v\u00e4ljer slumpm\u00e4ssigt vilket rum den ska g\u00e5 till, baserat p\u00e5 v\u00e4rdet. D\u00e4refter minns agenten vilket rum han blev d\u00f6dad i och minskar dess v\u00e4rde (sannolikheten att han g\u00e5r dit igen). Detsamma g\u00e4ller f\u00f6r den omv\u00e4nda situationen - om agenten f\u00f6rst\u00f6r m\u00e5nga motst\u00e5ndare \u00f6kar v\u00e4rdet p\u00e5 rummet.<\/p>\n<h3>Markovmodell<\/h3>\n<p>\nVad om vi anv\u00e4nder de insamlade data f\u00f6r att f\u00f6ruts\u00e4ga? Om vi kommer ih\u00e5g varje rum d\u00e4r vi ser spelaren under en viss tidsperiod, kan vi f\u00f6ruts\u00e4ga vilket rum spelaren kan g\u00e5 till. Genom att sp\u00e5ra och registrera spelarens r\u00f6relser mellan rummen (v\u00e4rden) kan vi g\u00f6ra prognoser.<\/p>\n<p>L\u00e5t oss ta tre rum: r\u00f6d, gr\u00f6n och bl\u00e5. Och \u00e4ven observationerna som vi har registrerat under visningen av spelsessionen:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/6e90a365b72a176c36c9a14213baaafc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAntalet observationer av varje rum \u00e4r n\u00e4stan lika \u2014 var vi ska g\u00f6ra en bra plats f\u00f6r en \u00f6verraskning vet vi fortfarande inte. Insamling av statistik f\u00f6rsv\u00e5ras ocks\u00e5 av respawn av spelare som dyker upp j\u00e4mnt \u00f6ver hela kartan. Men data om n\u00e4sta rum som de g\u00e5r in i efter att ha dykt upp p\u00e5 kartan \u00e4r redan anv\u00e4ndbar.<\/p>\n<p>Det \u00e4r tydligt att det gr\u00f6na rummet tilltalar spelarna \u2013 de flesta fr\u00e5n det r\u00f6da g\u00e5r \u00f6ver dit, och 50 % av dem stannar kvar d\u00e4r. Det bl\u00e5 rummet d\u00e4remot \u00e4r inte popul\u00e4rt, n\u00e4stan ingen g\u00e5r dit, och om de g\u00f6r det, stannar de inte l\u00e4nge. <\/p>\n<p>Men uppgifterna s\u00e4ger oss n\u00e5got mer viktigt \u2013 n\u00e4r spelaren befinner sig i det bl\u00e5 rummet, \u00e4r n\u00e4sta rum d\u00e4r vi troligen kommer att se dem det r\u00f6da, inte det gr\u00f6na. Trots att det gr\u00f6na rummet \u00e4r popul\u00e4rare \u00e4n det r\u00f6da, f\u00f6r\u00e4ndras situationen om spelaren befinner sig i det bl\u00e5. Det n\u00e4sta tillst\u00e5ndet (allts\u00e5 rummet som spelaren kommer att g\u00e5 till) beror p\u00e5 det f\u00f6reg\u00e5ende tillst\u00e5ndet (det rum d\u00e4r spelaren befinner sig just nu). Genom att studera beroenden kommer vi att g\u00f6ra f\u00f6ruts\u00e4gelser som \u00e4r mer exakta \u00e4n om vi bara r\u00e4knade observationer oberoende av varandra.<\/p>\n<p>Att f\u00f6ruts\u00e4ga framtida tillst\u00e5nd baserat p\u00e5 data fr\u00e5n tidigare tillst\u00e5nd kallas en Markov-modell, och s\u00e5dana exempel (med rum) kallas Markovkedjor. Eftersom modellerna representerar sannolikheten f\u00f6r f\u00f6r\u00e4ndringar mellan konsekutiva tillst\u00e5nd, visas de visuellt i form av FSM med sannolikhet f\u00f6r varje \u00f6verg\u00e5ng. Tidigare anv\u00e4nde vi FSM f\u00f6r att representera det beteendem\u00e4ssiga tillst\u00e5ndet hos agenten, men detta koncept str\u00e4cker sig till vilket tillst\u00e5nd som helst, oavsett om det \u00e4r kopplat till agenten eller inte. I detta fall representerar tillst\u00e5nden rummet som agenten befinner sig i:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/edb32dff7a3298b19c3fa4d66f48e9f4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDetta \u00e4r en enkel form av att representera relativ sannolikhet f\u00f6r f\u00f6r\u00e4ndringar av tillst\u00e5nd, vilket ger AI en viss m\u00f6jlighet att f\u00f6ruts\u00e4ga n\u00e4sta tillst\u00e5nd. Flera steg fram\u00e5t kan f\u00f6ruts\u00e4gas.<\/p>\n<p>Om spelaren \u00e4r i det gr\u00f6na rummet finns det 50 % chans att de stannar kvar d\u00e4r vid n\u00e4sta observation. Men vad \u00e4r sannolikheten att de fortfarande kommer att vara d\u00e4r \u00e4ven efter\u00e5t? Det finns inte bara en chans att spelaren stannade i det gr\u00f6na rummet efter tv\u00e5 observationer, utan ocks\u00e5 en chans att de l\u00e4mnat och kommit tillbaka. H\u00e4r \u00e4r en ny tabell med h\u00e4nsyn till de nya uppgifterna:<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/f87afff68b066a879661e37f68654ae2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAv den framg\u00e5r det att chansen att se spelaren i det gr\u00f6na rummet efter tv\u00e5 observationer kommer att vara 51 % \u2013 21 % att de kommer fr\u00e5n det r\u00f6da rummet, 5 % av dem att spelaren bes\u00f6ker det bl\u00e5 rummet mellan dem, och 25 % att spelaren \u00f6verhuvudtaget inte l\u00e4mnar det gr\u00f6na rummet.<\/p>\n<p>Tabellen \u00e4r ett enkelt visuellt verktyg \u2013 proceduren kr\u00e4ver endast att man multiplicerar sannolikheter vid varje steg. Det inneb\u00e4r att du kan se l\u00e5ngt in i framtiden med ett f\u00f6rbeh\u00e5ll: vi f\u00f6ruts\u00e4tter att chansen att komma in i ett rum helt beror p\u00e5 det aktuella rummet. Detta kallas Markov-egenskapen (Markov Property) \u2013 framtida tillst\u00e5nd beror endast p\u00e5 nuvarande. Men detta \u00e4r inte hundraprocentigt exakt. Spelare kan \u00e4ndra beslut baserat p\u00e5 andra faktorer: h\u00e4lsoniv\u00e5 eller m\u00e4ngd ammunition. Eftersom vi inte fastst\u00e4ller dessa v\u00e4rden kommer v\u00e5ra prognoser att vara mindre exakta.<\/p>\n<h3>N-Grams<\/h3>\n<p>\nOch vad s\u00e4gs om exemplet med fightingspel och f\u00f6ruts\u00e4gelse av spelarens kombinationer? Detsamma! Men ist\u00e4llet f\u00f6r ett tillst\u00e5nd eller en h\u00e4ndelse kommer vi att unders\u00f6ka hela sekvenser som kombinationsslaget best\u00e5r av.<\/p>\n<p>Ett s\u00e4tt att g\u00f6ra detta \u00e4r att spara varje input (t.ex. Kick, Punch eller Block) i en buffer och registrera hela bufferten som en h\u00e4ndelse. S\u00e5 spelaren trycker flera g\u00e5nger p\u00e5 Kick, Kick, Punch f\u00f6r att anv\u00e4nda attacken SuperDeathFist, AI-systemet sparar alla inputs i bufferten och kommer ih\u00e5g de senaste tre som anv\u00e4nds vid varje steg.<\/p>\n<p><img decoding=\"async\" alt=\"Hur man skapar ett spel-AI: en guide f\u00f6r nyb\u00f6rjare\" src=\"\/wp-content\/uploads\/2019\/11\/9a95226ae155dca5e45a66d4440f3cd4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(Fetmarkerade rader indikerar n\u00e4r spelaren startar attacken SuperDeathFist.)<\/p>\n<p>AI:n kommer att se alla alternativ n\u00e4r spelaren valde Kick, f\u00f6ljt av en annan Kick, och d\u00e4refter m\u00e4rk att n\u00e4sta input alltid \u00e4r Punch. Detta g\u00f6r att agenten kan f\u00f6ruts\u00e4ga kombinationen SuperDeathFist och blockera den om m\u00f6jligt.<\/p>\n<p>Dessa sekvenser av h\u00e4ndelser kallas N-gram (N-grams), d\u00e4r N \u00e4r antalet lagrade element. I det tidigare exemplet var det en 3-gram (trigram), vilket betyder att de f\u00f6rsta tv\u00e5 inspelningarna anv\u00e4nds f\u00f6r att f\u00f6ruts\u00e4ga den tredje. P\u00e5 samma s\u00e4tt i en 5-gram f\u00f6ruts\u00e4ger de f\u00f6rsta fyra inspelningarna den femte och s\u00e5 vidare.<\/p>\n<p>Utvecklaren m\u00e5ste noggrant v\u00e4lja storleken p\u00e5 N-gram. Ett mindre antal N kr\u00e4ver mindre minne, men lagrar ocks\u00e5 en kortare historia. Till exempel, en 2-gram (bigram) kommer att registrera Kick, Kick eller Kick, Punch, men kan inte lagra Kick, Kick, Punch, s\u00e5 AI:n kommer inte att reagera p\u00e5 kombinationen SuperDeathFist.<\/p>\n<p>\u00c5 andra sidan kr\u00e4ver st\u00f6rre siffror mer minne och det blir sv\u00e5rare f\u00f6r AI:n att l\u00e4ra sig eftersom det kommer att finnas m\u00e5nga fler m\u00f6jliga alternativ. Om du hade tre m\u00f6jliga inputs Kick, Punch eller Block, och vi anv\u00e4nde en 10-gram, skulle det ge cirka 60 000 olika alternativ.<\/p>\n<p>Bigrammodellen \u00e4r en enkel Markovkedja - varje par \"tidigare tillst\u00e5nd\/nuvarande tillst\u00e5nd\" \u00e4r ett bigram, och du kan f\u00f6ruts\u00e4ga det andra tillst\u00e5ndet baserat p\u00e5 det f\u00f6rsta. Trigram och st\u00f6rre N-gram kan ocks\u00e5 betraktas som Markovkedjor, d\u00e4r alla element (f\u00f6rutom den sista i N-grammet) tillsammans bildar det f\u00f6rsta tillst\u00e5ndet, medan det sista elementet \u00e4r det andra. Ett exempel med fighting visar \u00f6verg\u00e5ngschanser fr\u00e5n tillst\u00e5ndet Kick och Kick till tillst\u00e5ndet Kick och Punch. Genom att betrakta flera poster i ing\u00e5ngshistoriken som en enhet omvandlar vi i praktiken ing\u00e5ngssekvensen till en del av ett helt tillst\u00e5nd. Detta ger oss Markovegenskapen, vilket g\u00f6r det m\u00f6jligt att anv\u00e4nda Markovkedjor f\u00f6r att f\u00f6ruts\u00e4ga n\u00e4sta ing\u00e5ng och gissa vilken kombo-move som kommer att f\u00f6ljas.<\/p>\n<h2>Slutsats<\/h2>\n<p>\nVi har diskuterat de vanligaste verktygen och metoderna inom utveckling av artificiell intelligens. Vi har ocks\u00e5 g\u00e5tt igenom situationer d\u00e4r de ska till\u00e4mpas och d\u00e4r de \u00e4r s\u00e4rskilt anv\u00e4ndbara. <\/p>\n<p>Detta b\u00f6r vara tillr\u00e4ckligt f\u00f6r att f\u00f6rst\u00e5 de grundl\u00e4ggande aspekterna av spel-AI. Men sj\u00e4lvklart \u00e4r detta l\u00e5ngt ifr\u00e5n alla metoder. Bland de mindre popul\u00e4ra, men lika effektiva, finns:<\/p>\n<ul>\n<li>optimeringsalgoritmer, inklusive hill climbing, gradientnedstigning och genetiska algoritmer<\/li>\n<li>konkurrerande s\u00f6k-\/planeringsalgoritmer (minimax och alpha-beta pruning)<\/li>\n<li>klassificeringsmetoder (perceptron, neurala n\u00e4tverk och st\u00f6dvektormaskiner)<\/li>\n<li>system f\u00f6r att bearbeta perception och minne hos agenter<\/li>\n<li>arkitektoniska angreppss\u00e4tt f\u00f6r AI (hybrida system, delm\u00e4ngd av arkitekturer och andra s\u00e4tt att \u00f6verlagra AI-system)<\/li>\n<li>animationsverktyg (planering och samordning av r\u00f6relse)<\/li>\n<li>prestandafaktorer (detaljniv\u00e5, anytime-algoritmer, och tidsdelning)<\/li>\n<\/ul>\n<p>\nInternetresurser om \u00e4mnet:<\/p>\n<p>1. P\u00e5 GameDev.net finns det <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gamedev.net\/articles\/programming\/artificial-intelligence\/\">ett avsnitt med artiklar och handledningar om AI<\/a><\/noindex>, samt <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gamedev.net\/forums\/forum\/6-artificial-intelligence\/\">forum<\/a><\/noindex>.<br \/>\n2. <noindex><a rel=\"nofollow\" href=\"http:\/\/aigamedev.com\/\">AiGameDev.com<\/a><\/noindex> inneh\u00e5ller m\u00e5nga presentationer och artiklar om ett brett spektrum av relaterade \u00e4mnen inom utveckling av spel-AI.<br \/>\n3. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gdcvault.com\/\">GDC Vault<\/a><\/noindex> inkluderar \u00e4mnen fr\u00e5n GDC AI-summit, m\u00e5nga av vilka \u00e4r tillg\u00e4ngliga gratis.<br \/>\n4. Anv\u00e4ndbara material kan ocks\u00e5 hittas p\u00e5 webbplatsen <noindex><a rel=\"nofollow\" href=\"http:\/\/gameai.com\/\">AI Game Programmers Guild<\/a><\/noindex>.<br \/>\n5. Tommy Thompson, AI-forskare och spelutvecklare, g\u00f6r videor p\u00e5 YouTube-kanalen <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/tthompso\">AI and Games<\/a><\/noindex> med f\u00f6rklaringar och hypoteser kring AI i kommersiella spel.<\/p>\n<p>B\u00f6cker om \u00e4mnet:<\/p>\n<p>1. Serien av b\u00f6ckerna Game AI Pro \u00e4r samlingar av korta artiklar som f\u00f6rklarar hur man implementerar specifika funktioner eller hur man l\u00f6ser specifika problem.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"http:\/\/go.gamedev.net\/?id=13722X707581&amp;xs=1&amp;isjs=1&amp;url=https%3A%2F%2Famzn.to%2F2KGoB8n&amp;xguid=f8ad586e5984991508efff4754027dbd&amp;xuuid=305451ecead59d76ca830fded0aab276&amp;xsessid=6ccb8b9fa3f10b478b65f7ed703a447b&amp;xcreo=0&amp;xed=0&amp;sref=https%3A%2F%2Fwww.gamedev.net%2Farticles%2Fprogramming%2Fartificial-intelligence%2Fthe-total-beginners-guide-to-game-ai-r4942%2F%3Fdo%3Dedit%26d%3D1%26id%3D4942%26csrfKey%3D7015c6d2c5c643e87baa74f8e5d2c094&amp;pref=https%3A%2F%2Fwww.gamedev.net%2Farticles%2Fprogramming%2Fartificial-intelligence%2Fthe-total-beginners-guide-to-game-ai-r4942%2F&amp;xtz=420&amp;jv=13.7.1&amp;bv=2.5.1\">Game AI Pro: Insamlad visdom fr\u00e5n spel-AI-professionella<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"http:\/\/go.gamedev.net\/?id=13722X707581&amp;xs=1&amp;isjs=1&amp;url=https%3A%2F%2Famzn.to%2F2KFKyoe&amp;xguid=f8ad586e5984991508efff4754027dbd&amp;xuuid=305451ecead59d76ca830fded0aab276&amp;xsessid=6ccb8b9fa3f10b478b65f7ed703a447b&amp;xcreo=0&amp;xed=0&amp;sref=https%3A%2F%2Fwww.gamedev.net%2Farticles%2Fprogramming%2Fartificial-intelligence%2Fthe-total-beginners-guide-to-game-ai-r4942%2F%3Fdo%3Dedit%26d%3D1%26id%3D4942%26csrfKey%3D7015c6d2c5c643e87baa74f8e5d2c094&amp;pref=https%3A%2F%2Fwww.gamedev.net%2Farticles%2Fprogramming%2Fartificial-intelligence%2Fthe-total-beginners-guide-to-game-ai-r4942%2F&amp;xtz=420&amp;jv=13.7.1&amp;bv=2.5.1\">Game AI Pro 2: Insamlad visdom fr\u00e5n spel-AI-professionella<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2KF4irS\">Game AI Pro 3: Insamlad visdom fr\u00e5n spel-AI-professionella<\/a><\/noindex><\/p>\n<p>2. Serien AI Game Programming Wisdom \u00e4r f\u00f6reg\u00e5ngaren till serien Game AI Pro. Den inneh\u00e5ller \u00e4ldre metoder, men n\u00e4stan alla \u00e4r fortfarande relevanta idag.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2ARFhKx\">AI Game Programming Wisdom 1<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2Mkv4eh\">AI Game Programming Wisdom 2<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2nnuYEh\">AI Game Programming Wisdom 3<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2ARFEEV\">AI Game Programming Wisdom 4<\/a><\/noindex><\/p>\n<p>3. <noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2AWKuRh\">Artificial Intelligence: A Modern Approach<\/a><\/noindex> \u2014 det \u00e4r en av de grundl\u00e4ggande texterna f\u00f6r alla som vill f\u00f6rst\u00e5 det allm\u00e4nna omr\u00e5det f\u00f6r artificiell intelligens. Denna bok handlar inte om spelutveckling \u2014 den l\u00e4r ut de grundl\u00e4ggande principerna f\u00f6r AI.<br \/>\n<br \/>K\u00e4lla: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/pixonic\/blog\/428892\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431 \u0438\u0441\u043a\u0443\u0441\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c \u0438\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0435 \u0432 \u0438\u0433\u0440\u0430\u0445. \u0421 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0432\u0435\u0449\u0435\u0439 \u043f\u0440\u043e \u0418\u0418 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u0445, \u0430 \u0435\u0449\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0434\u043b\u044f \u0435\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041a\u0430\u043a, \u0433\u0434\u0435 \u0438 \u043a\u043e\u0433\u0434\u0430 \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u2014 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c. \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0432 \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c 35 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-52118","post","type-post","status-publish","format-standard","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/sv\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0418\u0418: \u0433\u0430\u0439\u0434 \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/sv\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T10:59:47+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Hur man skapar gaming AI: en guide f\u00f6r nyb\u00f6rjare | ProHoster","description":"Snubblade \u00f6ver intressant material om.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0418\u0418: \u0433\u0430\u0439\u0434 \u0434\u043b\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0445 | ProHoster","og:description":"\u041d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043e\u0431.","og:url":"https:\/\/prohoster.info\/sv\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T21:00:00+00:00","article:modified_time":"2020-02-18T10:59:47+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"52118","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 02:32:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:49:49","updated":"2026-01-24 02:32:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/52118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=52118"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/52118\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=52118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=52118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=52118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}