{"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\/hr\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","title":{"rendered":"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/9e57175b233a104e0df98383b374eded.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNai\u0161ao sam na zanimljiv materijal o umjetnoj inteligenciji u igricama. S obja\u0161njenjem osnovnih stvari o AI na jednostavnim primjerima, a tako\u0111er unutar se nalazi mnogo korisnih alata i metoda za njegovu jednostavnu razvoj i projektiranje. Kako, gdje i kada ih koristiti \u2014 tako\u0111er je obja\u0161njeno.<\/p>\n<p>Ve\u0107ina primjera je napisana u pseudokodu, tako da duboko poznavanje programiranja ne\u0107e biti potrebno. Ispod \u0107ete na\u0107i 35 stranica teksta s slikama i gifovima, pa se pripremite.<\/p>\n<p>UPD. Ispri\u010davam se, no vlastiti prijevod ovog \u010dlanka na Habr\u00e9 ve\u0107 sam napravio. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/PatientZero\/\">PatientZero<\/a><\/noindex>. Njegovu verziju mo\u017eete pro\u010ditati <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/420219\/\">ovdje<\/a><\/noindex>, ali avaj, \u010dlanak mi je nekako promakao (koristio sam pretragu, ali ne\u0161to nije i\u0161lo kako treba). A budu\u0107i da pi\u0161em u blogu posve\u0107enom razvoju igara, odlu\u010dio sam ostaviti svoju verziju prijevoda za pretplatnike (neki trenuci su kod mene obra\u0111eni druga\u010dije, a neki su namjerno propu\u0161teni prema savjetu programera).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>\u0160to je AI?<\/h2>\n<p>\nIgrivi AI usredoto\u010duje se na to koje radnje objekt treba poduzeti, temelje\u0107i se na uvjetima u kojima se nalazi. Obi\u010dno se to naziva upravljanje 'inteligentnim agentima', gdje je agent igriva osoba, vozilo, bot, a ponekad i ne\u0161to apstraktnije: cijela skupina entiteta ili \u010dak civilizacija. U svakom slu\u010daju, to je stvar koja treba vidjeti svoje okru\u017eenje, donositi odluke na temelju njega i djelovati u skladu s njima. To se naziva ciklusom Sense\/Think\/Act (Osje\u0107ati\/Misliti\/Djelovati):<\/p>\n<ul>\n<li>Sense: agent nalazi ili prima informacije o stvarima u svom okru\u017eenju koje mogu utjecati na njegovo pona\u0161anje (pretnje u blizini, predmeti za prikupljanje, zanimljiva mjesta za istra\u017eivanje).<\/li>\n<li>Think: agent odlu\u010duje kako reagirati (razmatra je li dovoljno sigurno prikupiti predmete ili se prvo boriti\/skrivati).<\/li>\n<li>Act: agent poduzima radnje kako bi ostvario prethodnu odluku (po\u010dinje se kretati prema neprijatelju ili predmetu).<\/li>\n<li>\u2026sada se situacija promijenila zbog akcija likova, pa se ciklus ponavlja s novim podacima.<\/li>\n<\/ul>\n<p>\nAI se obi\u010dno fokusira na dio ciklusa pod nazivom Sense. Na primjer, autonomni automobili snimaju cestu, kombiniraju te podatke s radarima i lidarnim senzorima, te ih interpretiraju. To obi\u010dno radi strojno u\u010denje, koje obra\u0111uje ulazne podatke i im daje smisao, izvode\u0107i semanti\u010dke informacije poput \"ima jo\u0161 jedan automobil 20 jardi ispred vas\". Ovo su takozvani problemi klasifikacije.<\/p>\n<p>Igrama nije potreban slo\u017een sustav za izvla\u010denje informacija, jer je velika ve\u0107ina podataka ve\u0107 sastavni dio igre. Nema potrebe pokretati algoritme za prepoznavanje slika kako bi se odredilo ima li neprijatelj ispred \u2014 igra to ve\u0107 zna i proslje\u0111uje podatke izravno tijekom procesa odlu\u010divanja. Stoga je dio ciklusa Sense \u010desto daleko jednostavniji od dijelova Think i Act.<\/p>\n<h2>Ograni\u010denja igra\u010dkog AI-a<\/h2>\n<p>\nAI ima niz ograni\u010denja koja treba po\u0161tovati:<\/p>\n<ul>\n<li>AI se ne mora unaprijed obu\u010davati, kao \u0161to je to slu\u010daj s algoritmom strojnog u\u010denja. Besmisleno je pisati neuronsku mre\u017eu tijekom razvoja kako biste promatrali desetke tisu\u0107a igra\u010da i u\u010dili najbolji na\u010din igre protiv njih. Za\u0161to? Zato \u0161to igra nije objavljena, a igra\u010da nema.<\/li>\n<li>Igra mora zabavljati i izazivati, stoga agenti ne bi smjeli pronalaziti najbolji pristup protiv ljudi.<\/li>\n<li>Agentima je potrebno izgledati realisti\u010dni, kako bi igra\u010di imali osje\u0107aj da se bore protiv pravih ljudi. Program AlphaGo nadma\u0161io je \u010dovjeka, ali odabrani potezi bili su daleko od tradicionalnog shva\u0107anja igre. Ako igra imitira ljudskog protivnika, to se ne smije dogoditi. Algoritam se mora prilagoditi kako bi donosio uvjerljive odluke, a ne savr\u0161ene.<\/li>\n<li>AI mora raditi u stvarnom vremenu. To zna\u010di da algoritam ne mo\u017ee monopolizirati procesor tijekom duljeg vremena za dono\u0161enje odluka. \u010cak i 10 milisekundi za to \u2014 predugo je, jer ve\u0107ini igara treba od 16 do 33 milisekunde za cijelu obradu i prelazak na sljede\u0107i okvir grafike.<\/li>\n<li>Idealno je da barem dio sustava bude upravljan podacima, kako bi \"neprogrameri\" mogli donositi promjene, a korekcije se doga\u0111ale br\u017ee.<\/li>\n<\/ul>\n<p>\nPogledajmo pristupe AI-u koji obuhva\u0107aju cijeli ciklus Sense\/Think\/Act.<\/p>\n<h3>Donositi osnovne odluke<\/h3>\n<p>\nZapo\u010dnimo s najjednostavnijom igrom \u2014 Pong. Cilj: pomjeriti platformu (paddle) kako bi lopta odskakala od nje, a ne prolazila pored. To je poput tenisa, gdje gubite ako ne udarite loptu. Ovdje AI ima relativno lagan zadatak \u2014 odlu\u010diti u kojem smjeru pomjeriti platformu.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/e1935d657b9f090bf60c365c21e8f92b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Uvjetni operatori<\/h3>\n<p>\nZa AI u Pongu postoji najobi\u010dnije re\u0161enje \u2014 uvijek nastojati postaviti platformu ispod lopte.<\/p>\n<p>Jednostavni algoritam za to, napisan u pseudokodu:<\/p>\n<p><i>svaki okvir\/azuriranje dok igra traje:<br \/>\nako je lopta lijevo od platforme:<br \/>\n pomjeri platformu lijevo<br \/>\nina\u010de ako je lopta desno od platforme:<br \/>\n pomjeri platformu desno<\/i><\/p>\n<p>Ako se platforma kre\u0107e brzinom lopte, to je idealan algoritam za AI u Pongu. Nema potrebe komplicirati, ako podataka i mogu\u0107ih akcija za agenta nije mnogo.<\/p>\n<p>Ovaj pristup je toliko jednostavan da je cijeli ciklus Sense\/Think\/Act jedva primjetan. Ali on postoji:<\/p>\n<ul>\n<li>Dio Sense se nalazi u dva operatora if. Igra zna gdje je lopta i gdje je platforma, tako da AI tra\u017ei te informacije od nje. <\/li>\n<li>Dio Think tako\u0111er uklju\u010duje dva operatora if. Oni predstavljaju dva rje\u0161enja koja su u ovom slu\u010daju me\u0111usobno isklju\u010diva. Kao rezultat, bira se jedna od tri akcije \u2014 pomjeriti platformu lijevo, pomjeriti desno ili ne raditi ni\u0161ta ako je ve\u0107 ispravno postavljena.<\/li>\n<li>Dio Act se nalazi u operatorima Move Paddle Left i Move Paddle Right. Ovisno o dizajnu igre, oni mogu pomjeriti platformu trenutno ili s odre\u0111enom brzinom. <\/li>\n<\/ul>\n<p>\nTakve pristupe nazivamo reaktivnim \u2014 postoji jednostavan set pravila (u ovom slu\u010daju operatori if u kodu) koji reagiraju na trenutno stanje svijeta i djeluju.<\/p>\n<h3>Stablo odluka<\/h3>\n<p>\nPrimjer sa igrom Pong zapravo odgovara formalnoj konceptu AI, nazvanom stablo odluka. Algoritam ga prolazi kako bi do\u0161ao do 'lista' \u2014 odluke o tome koju akciju poduzeti.<\/p>\n<p>Napravimo blok dijagram stabla odluka za algoritam na\u0161e platforme:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/d3b7290ba93144967cd849416cd5eef3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSvaki dio stabla naziva se node (\u010dvor) \u2014 AI koristi teoriju grafova za opisivanje sli\u010dnih struktura. Postoje dva tipa \u010dvorova:<\/p>\n<ul>\n<li>\u010cvorovi odluka: izbor izme\u0111u dvije alternative na temelju provjere nekog uvjeta, gdje je svaka alternativa predstavljena kao zaseban \u010dvor.<\/li>\n<li>Zavr\u0161ni \u010dvorovi: akcija koja se izvr\u0161ava i predstavlja kona\u010dnu odluku.<\/li>\n<\/ul>\n<p>\nAlgoritam po\u010dinje s prvim \u010dvorom (\u201ekorijenom\u201c drveta). On ili donosi odluku o tome kojem pod\u010dvoru pre\u0107i, ili izvr\u0161ava radnju pohranjenu u \u010dvoru, i zavr\u0161ava.<\/p>\n<p>Koja je prednost ako stablo odluka obavlja istu funkciju kao i if-operatori u prethodnom odjeljku? Ovdje postoji cjeloviti sustav gdje svaka odluka ima samo jedan uvjet i dva mogu\u0107a rezultata. To omogu\u0107ava programeru da kreira AI iz podataka koji predstavljaju odluke u stablu, izbjegavaju\u0107i njegovu hardkodiranost. Predstavimo to u obliku tablice:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/6875293a60ff9d0efa26fb5e1aa4b21c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNa strani koda dobit \u0107ete sustav za \u010ditanje redaka. Stvorite \u010dvor za svaki od njih, pove\u017eite logiku dono\u0161enja odluka na temelju druge kolone i pod\u010dvorove na temelju tre\u0107e i \u010detvrte kolone. I dalje \u0107ete morati programirati uvjete i radnje, ali sada \u0107e struktura igre biti slo\u017eenija. U nju dodajete dodatne odluke i radnje, a zatim prilago\u0111avate cijeli AI jednostavno ure\u0111uju\u0107i tekstualnu datoteku s definicijom stabla. Zatim predajte datoteku game designeru, koji \u0107e mo\u0107i promijeniti pona\u0161anje bez ponovnog kompiliranja igre i promjene koda.<\/p>\n<p>Stabla odluka su vrlo korisna kada se automatski grade na temelju velikog skupa primjera (na primjer, kori\u0161tenjem ID3 algoritma). To ih \u010dini u\u010dinkovitim i visoko performantnim alatom za klasifikaciju situacija na temelju dobivenih podataka. Me\u0111utim, idemo dalje od jednostavnog sustava za odabir radnji agenata.<\/p>\n<h3>Skripte<\/h3>\n<p>\nRazradili smo sustav stabla odluka koji je koristio unaprijed definirane uvjete i radnje. Osoba koja projektira AI mo\u017ee organizirati stablo kako \u017eeli, ali se jo\u0161 uvijek mora oslanjati na programera koji je sve to kodirao. \u0160to ako bismo mogli dati dizajneru alate za stvaranje vlastitih uvjeta ili radnji?<\/p>\n<p>Kako programer ne bi morao pisati kod za uvjete Is Ball Left Of Paddle i Is Ball Right Of Paddle, mo\u017ee napraviti sustav u kojem \u0107e dizajner unositi uvjete za provjeru tih vrijednosti. Tada \u0107e podaci stabla odluka izgledati ovako:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/8e77f7c3410d097e8b7d8e1209355cc6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nU su\u0161tini, ovo je isto kao u prvoj tabeli, ali re\u0161enja unutar sebe imaju svoj vlastiti kod, ne\u0161to poput uslovnog dela if-operatora. Na strani koda, ovo bi se o\u010ditavalo u drugoj koloni za \u010dvorove dono\u0161enja odluka, ali umesto da tra\u017ei konkretno stanje za izvr\u0161enje (Da li je lopta levo od palice), procenjuje uslovni izraz i vra\u0107a true ili false u skladu s tim. Ovo se posti\u017ee kori\u0161\u0107enjem skriptnih jezika Lua ili Angelscript. Uz njih, programer mo\u017ee uzimati objekte u svojoj igri (lopta i palica) i kreirati promenljive koje \u0107e biti dostupne u skripti (ball.position). Pored toga, skripting je jednostavniji od C++. Ne zahteva punu fazu kompilacije, \u0161to ga \u010dini idealnim za brze ispravke logike igre i omogu\u0107ava \u201eneprogramerima\u201c da sami kreiraju potrebne funkcije.<\/p>\n<p>U datom primeru, skriptni jezik se koristi samo za procenu uslovnog izraza, ali se mo\u017ee koristiti i za akcije. Na primer, podaci o kretanju palice udesno mogu postati skriptni operator (ball.position.x += 10). Tako, da se akcija tako\u0111e defini\u0161e u skripti, bez potrebe za programiranjem Move Paddle Right.<\/p>\n<p>Mo\u017eete oti\u0107i jo\u0161 dalje i potpuno napisati drvo odluka na skriptnom jeziku. To \u0107e biti kod u obliku \u010dvrsto programiranih uslovnih operatora, ali \u0107e se nalaziti u spoljnim skript datotekama, \u0161to zna\u010di da se mogu menjati bez rekopilacije celog programa. \u010cesto mo\u017eete promeniti skriptnu datoteku direktno tokom igre kako biste brzo testirali razli\u010dite reakcije AI.<\/p>\n<h3>Reagovanje na doga\u0111aje<\/h3>\n<p>\nGore navedeni primeri savr\u0161eno odgovaraju Pong-u. Neprekidno pokre\u0107u ciklus Sense\/Think\/Act i deluju na osnovu poslednjeg stanja sveta. Me\u0111utim, u slo\u017eenijim igrama, potrebno je reagovati na pojedina\u010dne doga\u0111aje, a ne procenjivati sve odjednom. U tom slu\u010daju, Pong nije dobar primer. Izaberi\u0107emo ne\u0161to drugo. <\/p>\n<p>Zamislite puca\u010dinu, gde su neprijatelji nepomi\u010dni dok ne otkriju igra\u010da, nakon \u010dega deluju u zavisnosti od svoje \u201especijalizacije\u201c: neki \u0107e potr\u010dati napred, neki \u0107e napadati izdaleka. Ovo je i dalje osnovni reaktivan sistem \u2014 \u201eako je igra\u010d prime\u0107en, uradi ne\u0161to\u201c \u2014 ali mo\u017ee se logi\u010dki podeliti na doga\u0111aj Igra\u010d Prime\u0107en (Player Seen) i reakciju (izaberi odgovor i izvr\u0161i ga).<\/p>\n<p>To se vra\u0107a na ciklus Osje\u0107aj\/Misli\/Djeluj. Mo\u017eemo programirati dio Osje\u0107aj koji \u0107e svakog okvira provjeravati vidi li AI igra\u010da. Ako ne vidi - ni\u0161ta se ne doga\u0111a, ali ako vidi, nastaje doga\u0111aj Igra\u010d Vi\u0111en. Kod \u0107e imati poseban odjeljak koji ka\u017ee: \u00abkada se dogodi doga\u0111aj Igra\u010d Vi\u0111en, napravi\u00bb, gdje je - odgovor koji vam treba kako biste se obratili dijelovima Misli i Djeluj. Tako \u0107ete postaviti reakcije na doga\u0111aj Igra\u010d Vi\u0111en: za \u00abnapada\u010dkog\u00bb lika - Napadni i Napadni, a za snajpera - Sakrij se i Snajper. Ove veze mogu se stvoriti u datoteci podataka za brzo ure\u0111ivanje bez potrebe da se ponovo kompajlira. I ovdje se mo\u017ee koristiti jezik skripte.<\/p>\n<h2>Dono\u0161ene slo\u017eenih odluka<\/h2>\n<p>\nIako su jednostavni sustavi reakcija vrlo u\u010dinkoviti, postoji mnogo situacija kada to nije dovoljno. Ponekad je potrebno donijeti razli\u010dite odluke na temelju toga \u0161to agent trenutno radi, ali predstavljanje toga kao uvjeta je te\u0161ko. Ponekad postoji previ\u0161e uvjeta da bi se u\u010dinkovito predstavili u stablu odluka ili skripti. Ponekad je potrebno unaprijed procijeniti kako \u0107e se situacija promijeniti prije nego \u0161to donesete odluku o sljede\u0107em koraku. Za rje\u0161avanje ovih problema potrebni su slo\u017eeniji pristupi.<\/p>\n<h3>Kon\u010dni automati<\/h3>\n<p>\nKon\u010dni automat ili FSM (Finite State Machine) je na\u010din da se ka\u017ee da se na\u0161 agent trenutno nalazi u jednom od nekoliko mogu\u0107ih stanja i da mo\u017ee prelaziti iz jednog stanja u drugo. Takvih stanja ima odre\u0111eni broj - odatle i naziv. Najbolji mre\u017easti primjer je semafor. Na razli\u010ditim mjestima razli\u010dite su sekvence svjetala, ali princip je isti - svako stanje predstavlja ne\u0161to (stoj, idi itd.). Semafor je u svakom trenutku u samo jednom stanju i prelazi iz jednog u drugo na temelju jednostavnih pravila.<\/p>\n<p>S NPC-ima u igrama sli\u010dna je pri\u010da. Uzmimo za primjer stra\u017eara s ovim stanjima:<\/p>\n<ul>\n<li>Patrolira (Patrolling).<\/li>\n<li>Napada (Attacking).<\/li>\n<li>Bje\u017ei (Fleeing).<\/li>\n<\/ul>\n<p>\nI s ovim uvjetima za promjenu njegovog stanja:<\/p>\n<ul>\n<li>Ako stra\u017ear vidi neprijatelja, napada.<\/li>\n<li>Ako stra\u017ear napada, ali vi\u0161e ne vidi neprijatelja, vra\u0107a se patroliranju.<\/li>\n<li>Ako stra\u017ear napada, ali je te\u0161ko ranjen, bje\u017ei.<\/li>\n<\/ul>\n<p>\nTako\u0111er je mogu\u0107e napisati if-uvjete s varijablom stanja \u010duvara i razne provjere: postoji li neprijatelj u blizini, koja je razina zdravlja NPC-a itd. Dodajmo jo\u0161 nekoliko stanja:<\/p>\n<ul>\n<li>Neaktivnost (Idling) \u2014 izme\u0111u patrole.<\/li>\n<li>Potraga (Searching) \u2014 kada je primije\u0107en neprijatelj, ali se sakrio.<\/li>\n<li>Tra\u017eenje pomo\u0107i (Finding Help) \u2014 kada je neprijatelj vi\u0111en, ali je prejak za borbu s njim sam.<\/li>\n<\/ul>\n<p>\nIzbor za svakog od njih je ograni\u010den \u2014 na primjer, \u010duvar ne\u0107e i\u0107i tra\u017eiti sakrivenog neprijatelja ako ima nisko zdravlje.<\/p>\n<p>Na kraju, ogroman popis &bdquo;ako&ldquo; &lt;x \u0438 y, \u043d\u043e \u043d\u0435 z&gt;, tada &lt;p&gt;mo\u017ee postati previ&scaron;e optere\u0107en, stoga je potrebno formalizirati metodu koja \u0107e nam omogu\u0107iti da zadr\u017eimo u umu stanja i prijelaze izme\u0111u stanja. Da bismo to postigli, uzet \u0107emo u obzir sva stanja i pod svakim stanjem zabilje\u017eiti popis svih prijelaza u druga stanja, zajedno s potrebnim uvjetima za njih.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/ba4c401aa20de3d22d2478cba5a4b1ec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOvo je tablica prijelaza stanja \u2014 slo\u017een na\u010din predstavljanja FSM-a. Nacrtat \u0107emo dijagram i dobiti potpuni pregled na\u010dina na koji se pona\u0161anje NPC-a mijenja.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/b4182359983cf573872dacc575af13dc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDijagram odra\u017eava sr\u017e dono\u0161enja odluka za ovog agenta na temelju trenutne situacije. Svaka strelica prikazuje prijelaz izme\u0111u stanja, ako je uvjet uz nju istinit.<\/p>\n<p>Svake nadogradnje provjeravamo trenutno stanje agenta, pregledavamo popis prijelaza, a ako su uvjeti za prijelaz ispunjeni, prihva\u0107a novo stanje. Na primjer, svakim okvirom provjeravamo je li istekao 10-sekundi tajmer, i ako jest, \u010duvar prelazi iz stanja Idling u Patrolling. Na sli\u010dan na\u010din, stanje Attacking provjerava zdravlje agenta \u2014 ako je nisko, prelazi u stanje Fleeing.<\/p>\n<p>To je obrada prijelaza izme\u0111u stanja, ali \u0161to je s pona\u0161anjem vezanim uz sama stanja? Kada je rije\u010d o implementaciji stvarnog pona\u0161anja za odre\u0111eno stanje, obi\u010dno postoje dvije vrste 'kuka', gdje dodjeljujemo akcije FSM-u:<\/p>\n<ul>\n<li>Akcije koje periodi\u010dno izvr\u0161avamo za trenutno stanje.<\/li>\n<li>Akcije koje poduzimamo prilikom prijelaza iz jednog stanja u drugo.<\/li>\n<\/ul>\n<p>\nPrimjeri za prvi tip. Stanje Patrolling svaki okvir \u0107e premjestiti agenta po ruti patrole. Stanje Attacking svaki okvir \u0107e poku\u0161ati zapo\u010deti napad ili pre\u0107i u stanje kada to postane mogu\u0107e.<\/p>\n<p>Za drugi tip razmotrit \u0107emo prijelaz \u00abako je neprijatelj vidljiv i neprijatelj je prejaka, tada pre\u0111ite u stanje Pronala\u017eenja Pomo\u0107i. Agentu treba odabrati kamo oti\u0107i po pomo\u0107 i sa\u010duvati tu informaciju kako bi stanje Pronala\u017eenja Pomo\u0107i znalo kamo se obratiti. Kada pomo\u0107 bude prona\u0111ena, agent se vra\u0107a u stanje Napada. U tom trenutku \u0107e htjeti obavijestiti saveznika o prijetnji, stoga mo\u017ee nastati akcija Obavijesti Saveznika O Prijetnji.<\/p>\n<p>I ponovno mo\u017eemo pogledati ovaj sustav kroz prizmu ciklusa Osjeti\/Pomislite\/Prikazite. Osjeti se ostvaruje u podacima koji se koriste za logiku prijelaza. Pomislite \u2014 prijelazima dostupnim u svakoj situaciji. A Prikazite se ostvaruje aksiomima koji se povremeno poduzimaju unutar stanja ili na prijelazima izme\u0111u stanja.<\/p>\n<p>Ponekad neprekidno ispitivanje uvjeta prijelaza mo\u017ee biti skupo. Na primjer, ako svaki agent provodi slo\u017eene izra\u010dune svaki kadar kako bi odredio vidi li neprijatelje i mo\u017ee li pre\u0107i iz stanja Patroliranja u Napad \u2014 to \u0107e zauzeti puno procesorskog vremena. <\/p>\n<p>Va\u017ene promjene u stanju svijeta mogu se smatrati doga\u0111ajima koji \u0107e se obra\u0111ivati dok se pojavljuju. Umjesto da FSM svake sekunde provjeri uvjet prijelaza \u00abmo\u017ee li moj agent vidjeti igra\u010da?\u00bb, mo\u017ee se postaviti zaseban sustav da provodi provjere rje\u0111e (na primjer, 5 puta u sekundi). A rezultat isporu\u010diti Igra\u010d Vidjen, kada provjera bude pro\u0161la. <\/p>\n<p>To se proslje\u0111uje FSM-u, koji sada treba pre\u0107i u uvjet Primljen doga\u0111aj Igra\u010d Vidjen i odgovaraju\u0107e reagirati. Kona\u010dno pona\u0161anje je isto osim gotovo neprimjetnog ka\u0161njenja prije odgovora. No, performanse su pobolj\u0161ane zbog odvajanja dijela Osjeti u zaseban dio programa.<\/p>\n<h3>Hijerarhijska kona\u010dna stanja ma\u0161ina<\/h3>\n<p>\nMe\u0111utim, rad sa velikim FSM-ima nije uvijek prakti\u010dan. Ako \u017eelimo pro\u0161iriti stanje napada, zamjenjuju\u0107i ga posebnim MeleeAttacking (bliski napad) i RangedAttacking (daljinski napad), morat \u0107emo izmijeniti prijelaze iz svih drugih stanja koji vode u stanje Napada (trenutna i budu\u0107a).<\/p>\n<p>Sigurno ste primijetili da u na\u0161em primjeru ima mnogo dupliciranih prijelaza. Ve\u0107ina prijelaza u stanju Idling identi\u010dna je prijelazima u stanju Patrolling. Bilo bi dobro ne ponavljati se, posebno ako dodamo jo\u0161 sli\u010dnih stanja. Ima smisla grupirati Idling i Patrolling pod zajedni\u010dkom oznakom \"ne-borbeni\", gdje postoji samo jedan zajedni\u010dki skup prijelaza u borbena stanja. Ako ovu oznaku zamislimo kao stanje, tada Idling i Patrolling postaju podstanja. Primjer kori\u0161tenja odvojene tablice prijelaza za novo ne-borbeno podstanje:<\/p>\n<p><i>Osnovna stanja:<\/i><br \/>\n<img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/d86dd918acbe81b9bf22c2fb34aecee3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<i>Stanje izvan borbe:<\/i><br \/>\n<img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/9d5bc2053010a32c5f68d7f0192c04ed.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI u obliku dijagrama:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/0ccf95ecafa9ce2a6ea5b5b9833ddc4f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOvo je isti sustav, ali s novim ne-borbenim stanjem koje uklju\u010duje Idling i Patrolling. Svako stanje koje sadr\u017ei FSM s podstanjima (a ova podstanja, zauzvrat, sadr\u017ee vlastite FSM \u2014 i tako dalje koliko vam treba), dobivamo Hijerarhijski kona\u010dni automat ili HFSM. Grupiranjem ne-borbenog stanja, izbacili smo mno\u0161tvo suvi\u0161nih prijelaza. Istu stvar mo\u017eemo u\u010diniti za bilo koja nova stanja s zajedni\u010dkim prijelazima. Na primjer, ako u budu\u0107nosti pro\u0161irimo stanje Attacking na stanja MeleeAttacking i MissileAttacking, ona \u0107e biti podstanja koja prelaze jedno na drugo na temelju udaljenosti do neprijatelja i dostupnosti streljiva. Kao rezultat toga, slo\u017eeni modeli pona\u0161anja i podmodeli pona\u0161anja mogu se predstaviti s minimalnom koli\u010dinom dupliciranih prijelaza.<\/p>\n<h3>Stablo pona\u0161anja<\/h3>\n<p>\nS HFSM stvaraju se slo\u017eene kombinacije pona\u0161anja na jednostavan na\u010din. Me\u0111utim, postoji mala pote\u0161ko\u0107a u tome \u0161to dono\u0161enje odluka u obliku pravila prijelaza usko je povezano s trenutnim stanjem. I u mnogim igrama to je upravo ono \u0161to treba. Pa pa\u017eljivo kori\u0161tenje hijerarhije stanja mo\u017ee smanjiti broj ponavljanja prilikom prijelaza. No ponekad su potrebna pravila koja djeluju neovisno o tome u kojem se stanju nalazite ili koja se primjenjuju gotovo u svim stanjima. Na primjer, ako je zdravlje agenta palo ispod 25%, \u017eelite da pobjegne bez obzira na to je li bio u borbi, besposleno ili razgovarao \u2014 morat \u0107ete dodati ovaj uvjet u svako stanje. A ako va\u0161 dizajner kasnije \u017eeli promijeniti prag niskog zdravlja s 25% na 10%, opet \u0107e se morati time baviti.<\/p>\n<p>U idealnom slu\u010daju, za ovu situaciju potrebna je sustav u kojem su odluke \"u kojem stanju biti\" izvan samih stanja, omogu\u0107uju\u0107i promjene na jednom mjestu bez dodirivanja uvjeta prijelaza. Ovdje se javljaju stabla pona\u0161anja.<\/p>\n<p>Postoji nekoliko na\u010dina implementacije, ali su\u0161tina svima je otprilike ista i nalikuje stablu odluka: algoritam zapo\u010dinje s \"korijenskim\" \u010dvorom, a u stablu se nalaze \u010dvorovi koji predstavljaju ili odluke ili akcije. Me\u0111utim, postoje neka klju\u010dna odstupanja:<\/p>\n<ul>\n<li>Sada \u010dvorovi vra\u0107aju jednu od tri vrijednosti: Succeeded (ako je zadatak dovr\u0161en), Failed (ako se ne mo\u017ee pokrenuti) ili Running (ako je jo\u0161 uvijek aktivan i nema kona\u010dnog rezultata).<\/li>\n<li>Vi\u0161e nema \u010dvorova odluka za odabir izme\u0111u dvije alternative. Umjesto njih, tu su Decorator \u010dvorovi, koji imaju jedan pod\u010dvor. Ako uspiju, izvr\u0161avaju svoj jedini pod\u010dvor.<\/li>\n<li>\u010cvorovi koji izvr\u0161avaju akcije vra\u0107aju vrijednost Running koja predstavlja aktivne radnje.<\/li>\n<\/ul>\n<p>\nOvaj mali skup \u010dvorova mo\u017ee se kombinirati za stvaranje velikog broja slo\u017eenih modela pona\u0161anja. Zamislimo HFSM stra\u017eara iz prethodnog primjera u obliku stabla pona\u0161anja:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/5eaa5c725e4ada8285f16f95bb206d53.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nS ovom strukturom ne bi smjelo do\u0107i do o\u010ditog prijelaza iz stanja Idling\/Patrolling u stanje Attacking ili bilo koje drugo. Ako je neprijatelj vidljiv, a zdravlje lika nisko, izvr\u0161avanje \u0107e se zaustaviti na \u010dvoru Fleeing, bez obzira na to koji je \u010dvor ranije izvr\u0161avao \u2014 Patrolling, Idling, Attacking ili bilo koji drugi.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/e1c1dcc2055174aa7cfa846364b1709a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nStabla pona\u0161anja su slo\u017eena \u2014 postoji mnogo na\u010dina za njihovu konstrukciju, a pronala\u017eenje pravog spoja dekoratora i kompozitnih \u010dvorova mo\u017ee biti problemati\u010dno. Tu su i pitanja o tome koliko \u010desto provjeravati stablo \u2014 \u017eelimo li prolaziti kroz sve dijelove ili samo kada se jedan od uvjeta promijeni? Kako pohraniti stanje vezano za \u010dvorove \u2014 kako znati kada smo bili u stanju Idling 10 sekundi ili kako znati koji su \u010dvorovi izvr\u0161eni zadnji put, kako bismo ispravno obradili sekvencu?<\/p>\n<p>Zato postoje brojne implementacije. Na primjer, u nekim sustavima, \u010dvorovi dekoratora zamijenjeni su ugra\u0111enim dekoratorima. Oni ponovo ocjenjuju stablo kada se uvjeti dekoratora promijene, poma\u017eu u povezivanju \u010dvorova i osiguravaju periodi\u010dna a\u017euriranja.<\/p>\n<h3>Sustav temeljen na korisnosti<\/h3>\n<p>\nNeke igre imaju brojne razli\u010dite mehanike. Idealno bi bilo da iskori\u0161tavaju sve prednosti jednostavnih i op\u0107ih pravila prelaska, ali ne nu\u017eno u obliku cjelovitog stabla pona\u0161anja. Umjesto da imaju jasan skup izbora ili stablo mogu\u0107ih radnji, lak\u0161e je prou\u010diti sve radnje i odabrati najprikladniju u tom trenutku.<\/p>\n<p>Sustav temeljen na korisnosti pomo\u0107i \u0107e u tome. To je sustav u kojem agent ima mno\u0161tvo radnji, a on sam bira koju \u0107e izvr\u0161iti, temelje\u0107i se na relativnoj korisnosti svake. Gdje je korisnost proizvoljna mjera koliko je va\u017eno ili po\u017eeljno izvr\u0161enje te radnje za agenta. <\/p>\n<p>Izra\u010dunatu korisnost radnje temelji na trenutnom stanju i okru\u017eenju, agent mo\u017ee provjeriti i odabrati najprikladnije drugo stanje u bilo kojem trenutku. Ovo je sli\u010dno FSM-u, osim \u0161to su prijelazi odre\u0111eni procjenom za svako potencijalno stanje, uklju\u010duju\u0107i i trenutno. Imajte na umu da biramo najkorisniju radnju za prijelaz (ili ostajemo, ako smo je ve\u0107 izvr\u0161ili). Za ve\u0107u raznolikost to mo\u017ee biti te\u017eak, ali nasumi\u010dan odabir iz malog popisa.<\/p>\n<p>Sustav dodjeljuje proizvoljan raspon vrijednosti korisnosti - na primjer, od 0 (potpuno nepo\u017eeljno) do 100 (potpuno po\u017eeljno). Svaka radnja ima niz parametara koji utje\u010du na izra\u010dunavanje te vrijednosti. Vra\u0107aju\u0107i se na\u0161em primjeru s \u010duvarom:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/085fb2c197bde93d78455d18e63c9c25.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nPrijelazi izme\u0111u radnji nisu jednozna\u010dni - bilo koje stanje mo\u017ee slijediti bilo koje drugo. Prioriteti radnji odre\u0111eni su vra\u0107enim vrijednostima korisnosti. Ako je neprijatelj vidljiv, i taj neprijatelj je jak, a zdravlje lika nisko, tada \u0107e i Bijeg i Pronalazak pomo\u0107i vratiti visoke nenulte vrijednosti. Pri tome \u0107e Pronalazak pomo\u0107i uvijek biti vi\u0161i. Sli\u010dno tome, neborbene radnje nikada ne vra\u0107aju vi\u0161e od 50, stoga \u0107e uvijek biti ni\u017ee od borbenih. To treba uzeti u obzir prilikom kreiranja radnji i izra\u010dunavanja njihove korisnosti.<\/p>\n<p>U na\u0161em primjeru radnje vra\u0107aju ili fiksnu konstantnu vrijednost ili jednu od dvije fiksne vrijednosti. Realisti\u010dniji sustav podrazumijeva vra\u0107anje procjene iz kontinuiranog raspona vrijednosti. Na primjer, radnja Bje\u017eanje vra\u0107a vi\u0161e vrijednosti korisnosti ako je zdravlje agenta nisko, dok radnja Napad vra\u0107a ni\u017ee vrijednosti ako je neprijatelj prejak. Zbog toga radnja Bje\u017eanje ima prioritet nad Napadom u bilo kojoj situaciji kada agent osje\u0107a da mu nedostaje zdravlja za pobjedu nad protivnikom. Ovo omogu\u0107ava promjenu prioriteta radnji na temelju razli\u010ditih kriterija, \u010dine\u0107i ovaj pristup fleksibilnijim i varijabilnijim od stabla pona\u0161anja ili FSM-a.<\/p>\n<p>Svaka radnja ima mnogo uvjeta za izra\u010dun programa. Mogu se napisati na jeziku skripti ili u obliku niza matemati\u010dkih formula. U The Sims, koji modelira svakodnevicu lika, dodaje se dodatna razina prora\u010duna \u2014 agent dobiva niz \"motivacija\" koje utje\u010du na procjene korisnosti. Ako je lik gladan, s vremenom \u0107e postati jo\u0161 gladniji, a rezultat korisnosti radnje Jedite hranu \u0107e rasti sve dok ga lik ne izvr\u0161i, smanjuju\u0107i razinu gladi i vra\u0107aju\u0107i vrijednost Jedite hranu na nulu. <\/p>\n<p>Ideja odabira radnji na temelju sustava procjena prili\u010dno je jednostavna, pa se sustav temeljen na korisnosti mo\u017ee koristiti kao dio procesa dono\u0161enja odluka AI-a, a ne kao potpuna zamjena. Stablo odluka mo\u017ee zatra\u017eiti procjenu korisnosti dviju dje\u010djih \u010dvorova i odabrati onu s vi\u0161om procjenom. Sli\u010dno tome, stablo pona\u0161anja mo\u017ee imati slo\u017eeni \u010dvor Korisnost za procjenu korisnosti radnji kako bi odlu\u010dilo koju dijeljenje izvr\u0161iti.<\/p>\n<h2>Kretanje i navigacija<\/h2>\n<p>\nU prethodnim primjerima imali smo platformu koju smo pomicali lijevo ili desno, i \u010duvara koji je patrolirao ili napadao. No kako to\u010dno obra\u0111ujemo kretanje agenta tijekom odre\u0111enog vremenskog razdoblja? Kako postavljamo brzinu, kako izbjegavamo prepreke, i kako planiramo rutu ako je do\u0107i do odredi\u0161ta komplikovanije od jednostavnog kretanja pravo? Pogledajmo to.<\/p>\n<h3>Upravljanje<\/h3>\n<p>\nNa po\u010detku \u0107emo pretpostaviti da svaki agent ima vrijednost brzine koja uklju\u010duje brzinu kretanja i smjer. Ona se mo\u017ee mjeriti u metrima u sekundi, kilometrima na sat, pikselima u sekundi itd. Podsje\u0107aju\u0107i se na ciklus Sense\/Think\/Act, mo\u017eemo zamisliti da dio Think odabire brzinu, dok dio Act primjenjuje tu brzinu na agenta. Obi\u010dno u igrama postoji fizi\u010dki sustav koji izvr\u0161ava ovu zada\u0107u umjesto vas, analiziraju\u0107i vrijednost brzine svakog objekta i prilago\u0111avaju\u0107i je. Stoga mo\u017eemo ostaviti AI s jednom zada\u0107om \u2014 da odlu\u010di koju brzinu agent treba imati. Ako se zna gdje agent treba biti, treba ga premjestiti u pravom smjeru s postavljenom brzinom. Veoma trivijalna jednad\u017eba:<\/p>\n<p><i>desired_travel = destination_position \u2013 agent_position<\/i><\/p>\n<p>Zamislite 2D svijet. Agent se nalazi na to\u010dki (-2,-2), destinacija negdje na sjeveroistoku na to\u010dki (30, 20), a potrebna putanja za agenta da bi se tamo na\u0161ao je (32, 22). Pretpostavimo da se te pozicije mjere u metrima \u2014 ako uzmemo brzinu agenta kao 5 metara u sekundi, tada \u0107emo skalirati na\u0161 vektor kretanja i dobiti brzinu otprilike (4.12, 2.83). Sa tim parametrima agent bi stigao na destinaciju gotovo za 8 sekundi.<\/p>\n<p>Vrijednosti se mogu ponovno izra\u010dunati u bilo kojem trenutku. Ako je agent bio na pola puta prema cilju, pomak bi se polovi\u0107no produ\u017eio, ali budu\u0107i da je maksimalna brzina agenta 5 m\/s (to smo odlu\u010dili ranije), brzina \u0107e ostati ista. To tako\u0111er funkcionira za pokretne ciljeve, omogu\u0107uju\u0107i agentu da unese male promjene dok se oni kre\u0107u.<\/p>\n<p>No, \u017eelimo vi\u0161e varijabilnosti \u2014 na primjer, polagano pove\u0107ati brzinu kako bismo simulirali lik koji se kre\u0107e iz nepomi\u010dnog stanja u tr\u010danje. Isto se mo\u017ee u\u010diniti i na kraju, prije zaustavljanja. Ove karakteristike poznate su kao steering behaviours, od kojih svaka ima specifi\u010dno ime: Seek (tra\u017eenje), Flee (bijeg), Arrival (dolazak) itd. Ideja je u tome da se sile ubrzanja mogu primijeniti na brzinu agenta, na temelju usporedbe polo\u017eaja agenta i trenutne brzine s destinacijom, kako bi se primijenili razli\u010diti na\u010dini kretanja prema cilju.<\/p>\n<p>Svako pona\u0161anje ima pomalo druga\u010diju svrhu. Seek i Arrival su na\u010dini premje\u0161tanja agenta do odredi\u0161ta. Obstacle Avoidance (izbjegavanje prepreka) i Separation (razdvajanje) ispravljaju kretanje agenta kako bi zaobi\u0161li prepreke na putu do cilja. Alignment (saglasnost) i Cohesion (kohezija) dr\u017ee agente zajedno tokom kretanja. Bilo koji broj razli\u010ditih pona\u0161anja upravljanja mo\u017ee se sabrati kako bi se dobio jedan putni vektor uzimaju\u0107i u obzir sve faktore. Agent koristi pona\u0161anja Arrival, Separation i Obstacle Avoidance kako bi se dr\u017eao podalje od zidova i drugih agenata. Ovaj pristup dobro funkcioni\u0161e u otvorenim prostorima bez suvi\u0161nih detalja. <\/p>\n<p>U te\u017eim uslovima, sabiranje razli\u010ditih pona\u0161anja radi lo\u0161ije \u2014 na primer, agent se mo\u017ee zaglaviti u zidu zbog sukoba izme\u0111u Arrival i Obstacle Avoidance. Zbog toga je potrebno razmotriti slo\u017eenije opcije od jednostavnog sabiranja svih vrednosti. Jedan pristup je taj da umesto sabiranja rezultata svakog pona\u0161anja, razmotrimo kretanje u razli\u010ditim pravcima i izaberemo najbolju opciju. <\/p>\n<p>Me\u0111utim, u slo\u017eenom okru\u017eenju s slijepim uli\u010dicama i izborom koje strane krenuti, trebat \u0107e nam ne\u0161to jo\u0161 naprednije.<\/p>\n<h3>Pretraga puta<\/h3>\n<p>\nSteering behaviours su odli\u010dni za jednostavno kretanje na otvorenom terenu (fudbalsko igrali\u0161te ili arena), gde je put od A do B direktna staza s malim odmakom od prepreka. Za slo\u017eenije rute potrebna nam je pretraga puta (pathfinding), \u0161to je na\u010din istra\u017eivanja sveta i dono\u0161enja odluka o ruti kroz njega.<\/p>\n<p>Najjednostavnije je staviti mre\u017eu na svaki kvadrat pored agenta i procijeniti u kojima od njih je dopu\u0161teno kretanje. Ako je neki od njih odredi\u0161te, slijedite iz njega put od svakog kvadrata do prethodnog, sve dok ne do\u0111ete do po\u010detka. To je put. U suprotnom, ponavljajte proces s najbli\u017eim preostalim kvadratima, sve dok ne prona\u0111ete odredi\u0161te ili ne iscrpite kvadrate (\u0161to zna\u010di da ne postoji mogu\u0107i put). To je formalno poznato kao pretra\u017eivanje u \u0161irinu, ili BFS (Breadth-First Search). U svakom koraku gleda u svim smjerovima (zato \u0161irina, \u201ebreadth\u201c). Prostor pretra\u017eivanja nalikuje valnom frontu koji se kre\u0107e sve dok ne do\u0111e do tra\u017eenog mjesta \u2014 podru\u010dje pretra\u017eivanja se \u0161iri s svakim korakom dok ne uhvati krajnju to\u010dku, nakon \u010dega se mo\u017ee pratiti put do po\u010detka.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/d367e62bc53033b05388538649853a41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKao rezultat, dobit \u0107ete popis kvadrata koji \u010dine potrebni put. To je put (odakle naziv pathfinding) \u2014 popis mjesta koje \u0107e agent posjetiti na putu do odredi\u0161ta.<\/p>\n<p>S obzirom na to da znamo polo\u017eaj svakog kvadrata u svijetu, mo\u017eemo koristiti pona\u0161anja vo\u0111enja (steering behaviours) da se kre\u0107emo putem \u2014 od \u010dvora 1 do \u010dvora 2, zatim od \u010dvora 2 do \u010dvora 3, i tako dalje. Najjednostavnija opcija je usmjeriti se prema sredi\u0161tu sljede\u0107eg kvadrata, ali je jo\u0161 bolje stati na sredini stranice izme\u0111u trenutnog kvadrata i sljede\u0107eg. Na taj na\u010din agent mo\u017ee skratiti kutove na o\u0161trim zavojima.<\/p>\n<p>Algoritam BFS ima i nedostataka \u2014 istra\u017euje koliko kvadrata u \u201epogre\u0161nom\u201c smjeru koliko i u \u201epravom\u201c. Ovdje se pojavljuje slo\u017eeniji algoritam pod nazivom A* (A star). On radi na sli\u010dan na\u010din, ali umjesto slijepog istra\u017eivanja susjednih kvadrata (zatim susjeda susjeda, zatim susjeda susjeda susjeda itd.), prikuplja \u010dvorove u popis i sortira ih tako da je sljede\u0107i istra\u017eivani \u010dvor uvijek onaj koji \u0107e dovesti do najkra\u0107eg puta. \u010cvorovi se sortiraju na temelju heuristike koja uzima u obzir dvije stvari \u2014 \u201ecijenu\u201c hipotetskog puta do potrebnog kvadrata (uklju\u010duju\u0107i sve tro\u0161kove kretanja) i procjenu koliko je taj kvadrat daleko od odredi\u0161ta (pomjeraju\u0107i pretra\u017eivanje u pravom smjeru).<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/1cab4f53fa5af6b31d352c7bcf453d7e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOvaj primjer pokazuje kako agent istra\u017euje jedan kvadrat u jednom trenutku, svaki put biraju\u0107i susjedni koji je najperspektivniji. Dobiveni put je isti kao i kod BFS-a, ali je tijekom procesa razmotreno manje kvadrata \u2014 \u0161to je od velike va\u017enosti za performanse igre.<\/p>\n<h3>Kretanje bez mre\u017ee<\/h3>\n<p>\nMe\u0111utim, ve\u0107ina igara nije raspore\u0111ena na mre\u017ei, a \u010desto je nemogu\u0107e to u\u010diniti bez \u0161tete za realisti\u010dnost. Potrebni su kompromisi. Koje bi trebale biti dimenzije kvadrata? Preveliki \u2014 ne mogu ispravno prikazati male prolaze ili okrete, premali \u2014 bit \u0107e previ\u0161e kvadrata za pretra\u017eivanje, \u0161to \u0107e na kraju trajati puno vremena.<\/p>\n<p>Prvo \u0161to trebate razumjeti je da mre\u017ea daje graf povezanih \u010dvorova. A* i BFS algoritmi zapravo rade na grafovima i uop\u0107e ih ne zanima na\u0161a mre\u017ea. Mogli bismo postaviti \u010dvorove bilo gdje u igrivom svijetu: s povezano\u0161\u0107u izme\u0111u bilo koja dva povezana \u010dvora, kao i izme\u0111u po\u010detne i kona\u010dne to\u010dke i barem jednog od \u010dvorova \u2014 algoritam \u0107e raditi jednako dobro kao i prije. Ovo se \u010desto naziva sustavom putnih to\u010daka (waypoint), s obzirom da svaki \u010dvor predstavlja zna\u010dajnu poziciju u svijetu koja mo\u017ee biti dio bilo kojeg broja hipotetskih puteva.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/d87e9d4bb2a2fc713d32abc158506eaa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Primjer 1: \u010dvor u svakom kvadratu. Pretra\u017eivanje zapo\u010dinje iz \u010dvora u kojem se nalazi agent i zavr\u0161ava u \u010dvoru potrebnog kvadrata.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/b535a5db805efdc427d7c5724b866982.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Primjer 2: manji skup \u010dvorova (putnih to\u010daka). Pretra\u017eivanje zapo\u010dinje u kvadratu s agentom, prolazi kroz potrebni broj \u010dvorova, a zatim se nastavlja do odredi\u0161ta.<\/i><\/p>\n<p>Ovo je prili\u010dno fleksibilan i mo\u0107an sustav. Me\u0111utim, potrebna je odre\u0111ena opreznost u odlukama gdje i kako postaviti putnu to\u010dku, ina\u010de agenti mo\u017eda ne\u0107e vidjeti najbli\u017eu to\u010dku i ne\u0107e mo\u0107i zapo\u010deti put. Bilo bi lak\u0161e kad bismo mogli automatski rasporediti putne to\u010dke na temelju geometrije svijeta.<\/p>\n<p>Ovdje dolazi do izra\u017eaja navigation mesh ili navmesh (navigacijska mre\u017ea). To je obi\u010dno 2D mre\u017ea trokuta koja se nanosi na geometriju svijeta \u2014 svugdje gdje agentima nije dopu\u0161teno kretanje. Svaki trokut u mre\u017ei postaje \u010dvor u grafu i ima do tri susjedna trokuta koji postaju susjedni \u010dvorovi u grafu. <\/p>\n<p>Ova slika je primjer iz Unity engine-a \u2014 analizirao je geometriju u svijetu i stvorio navmesh (na slici svijetloplave boje). Svaki poligon u navmeshu je podru\u010dje na kojem agent mo\u017ee stajati ili se kretati s jednog poligona na drugi. U ovom primjeru, poligoni su manji od katova na kojima se nalaze \u2014 to je u\u010dinjeno da se uzmu u obzir dimenzije agenta koji \u0107e izlaziti izvan svoje nominalne pozicije.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/845705ba7b9a9d469203aedf7942da41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMo\u017eemo tra\u017eiti rutu kroz ovu mre\u017eu, ponovo koriste\u0107i A* algoritam. To \u0107e nam dati gotovo savr\u0161enu rutu u svijetu koja uzima u obzir cijelu geometriju, a ne zahtijeva dodatne \u010dvorove i stvaranje kontrolnih to\u010daka.<\/p>\n<p>Pronalazak puta \u2014 pre\u0161iroka tema o kojoj jedan odjeljak \u010dlanka nije dovoljan. Ako \u017eelite istra\u017eiti detaljnije, to \u0107e vam pomo\u0107i <noindex><a rel=\"nofollow\" href=\"https:\/\/www.redblobgames.com\/pathfinding\/a-star\/introduction.html\">web stranica Amita Patela<\/a><\/noindex>.<\/p>\n<h2>Planiranje<\/h2>\n<p>\nS pathfindingom smo se uvjerili da ponekad nije dovoljno samo izabrati pravac i krenuti \u2014 moramo odabrati rutu i napraviti nekoliko skretanja da bismo do\u0161li do \u017eeljenog odredi\u0161ta. Ovu ideju mo\u017eemo sa\u017eeti: postizanje cilja nije samo sljede\u0107i korak, ve\u0107 cijela sekvenca, gdje je ponekad potrebno gledati unaprijed nekoliko koraka kako bismo otkrili kakav bi trebao biti prvi. To se naziva planiranje. Pronalazak puta mo\u017ee se smatrati jednim od nekoliko dopuna planiranju. Iz perspektive na\u0161eg ciklusa Sense\/TThink\/Act, to je mjesto gdje dio Think planira nekoliko dijelova Act za budu\u0107nost.<\/p>\n<p>Razmotrit \u0107emo primjer iz dru\u0161tvene igre Magic: The Gathering. Igramo prvi s takvim skupom karata u ruci:<\/p>\n<ul>\n<li>Swamp \u2014 daje 1 crnu manu (karta zemlje).<\/li>\n<li>Forest \u2014 daje 1 zelenu manu (karta zemlje).<\/li>\n<li>Fugitive Wizard \u2014 zahtijeva 1 plavu manu za prizivanje.<\/li>\n<li>Elvish Mystic \u2014 zahtijeva 1 zelenu manu za prizivanje.<\/li>\n<\/ul>\n<p>\nPreostale tri karte zanemarujemo radi jednostavnosti. Prema pravilima, igra\u010du je dozvoljeno igrati 1 kartu zemlje po potezu, mo\u017ee \"tapnuti\" tu kartu da bi izvukao manau, a zatim koristiti \u010darolije (uklju\u010duju\u0107i prizivanje stvorenja) prema koli\u010dini mane. U ovoj situaciji, igra\u010d zna da treba igrati Forest, \"tapnuti\" 1 zelenu manu, a zatim prizvati Elvish Mystic. No, kako to shvatiti igra\u010devoj AI?<\/p>\n<h3>Jednostavno planiranje<\/h3>\n<p>\nTrivijalan pristup je poku\u0161avati svaku radnju redom dok ne ostanu odgovaraju\u0107e. Gledaju\u0107i karte, AI vidi da mo\u017ee igrati Swamp. I igra ga. Ima li drugih radnji u ovoj rundi? Ne mo\u017ee pozvati ni Elvish Mystic ni Fugitive Wizard, jer za njihovo pozivanje su potrebni zeleni i plavi mana, dok Swamp daje samo crnu manu. Tako\u0111er ne mo\u017ee igrati Forest, jer je ve\u0107 odigrao Swamp. Stoga je AI igrao prema pravilima, ali to je u\u010dinio lo\u0161e. To se mo\u017ee pobolj\u0161ati.<\/p>\n<p>Planiranje mo\u017ee prona\u0107i popis radnji koje dovode igru u \u017eeljeno stanje. Tako kao \u0161to je svaka kvadrati\u0107 na putu imao susjede (u pronala\u017eenju puta), svaka radnja u planu tako\u0111er ima susjede ili nasljednike. Mo\u017eemo tra\u017eiti te radnje i sljede\u0107e radnje sve dok ne postignemo \u017eeljeno stanje.<\/p>\n<p>U na\u0161em primjeru, \u017eeljeni rezultat je 'pozvati stvorenje, ako je to mogu\u0107e'. Na po\u010detku runde vidimo samo dvije mogu\u0107e radnje dopu\u0161tene pravilima igre:<\/p>\n<p><i>1. Igrati Swamp (rezultat: Swamp u igri)<br \/>\n2. Igrati Forest (rezultat: Forest u igri)<\/i><\/p>\n<p>Svaka prihva\u0107ena radnja mo\u017ee dovesti do daljnjih radnji i zatvoriti druge, opet ovisno o pravilima igre. Zamislite da smo odigrali Swamp \u2014 to \u0107e ukloniti Swamp kao sljede\u0107i korak (ve\u0107 smo ga odigrali), tako\u0111er \u0107e ukloniti i Forest (jer prema pravilima mo\u017ee se odigrati jedna karta zemlje po rundi). Nakon toga, AI dodaje kao sljede\u0107i korak \u2014 dobivanje 1 crne mane, jer drugih opcija nema. Ako nastavi i odabere Tap the Swamp, dobit \u0107e 1 jedinicu crne mane i ne\u0107e mo\u0107i ni\u0161ta s njom u\u010diniti.<\/p>\n<p><i>1. Igrati Swamp (rezultat: Swamp u igri)<br \/>\n 1.1 'Tapnuti' Swamp (rezultat: Swamp 'tapnut', +1 jedinica crne mane)<br \/>\n Nema dostupnih radnji \u2013 KRAJ<br \/>\n2. Igrati Forest (rezultat: Forest u igri)<\/i><\/p>\n<p>Popis radnji se zavr\u0161io, do\u0161li smo do slijepog kraja. Ponovno ponavljamo postupak za sljede\u0107u radnju. Igramo Forest, otvaramo radnju 'dobiti 1 zelenu manu', koja \u0107e zauzvrat otvoriti tre\u0107u radnju \u2014 poziv Elvish Mystic.<\/p>\n<p><i>1. Igrati Swamp (rezultat: Swamp u igri)<br \/>\n 1.1 'Tapnuti' Swamp (rezultat: Swamp 'tapnut', +1 jedinica crne mane)<br \/>\n Nema dostupnih radnji \u2013 KRAJ<br \/>\n2. Igrati Forest (rezultat: Forest u igri)<br \/>\n 2.1 'Tapnuti' Forest (rezultat: Forest 'tapnut', +1 jedinica zelene mane)<br \/>\n 2.1.1 Pozvati Elvish Mystic (rezultat: Elvish Mystic u igri, -1 jedinica zelene mane)<br \/>\n Nema dostupnih radnji \u2013 KRAJ<\/i><\/p>\n<p>Na kraju, prou\u010dili smo sve mogu\u0107e radnje i prona\u0161li plan za pozivanje stvorenja.<\/p>\n<p>Ovo je vrlo pojednostavljen primjer. Preporu\u010duje se odabrati najbolji mogu\u0107i plan, a ne bilo koji koji ispunjava odre\u0111ene kriterije. Kao pravilo, mogu se ocijeniti potencijalni planovi na temelju krajnjeg rezultata ili ukupne koristi od njihovog izvr\u0161avanja. Mo\u017eete si dodijeliti 1 bod za igranje karte zemlje i 3 boda za prizivanje stvorenja. Igranje Swamp bi bio plan koji donosi 1 bod. A igranje Forest \u2192 Tap the Forest \u2192 prizvati Elvish Mystic odjednom daje 4 boda. <\/p>\n<p>Evo kako funkcionira planiranje u Magic: The Gathering, ali ista logika se primjenjuje i u drugim situacijama. Na primjer, pomaknuti pje\u0161aka kako biste oslobodili prostor za potez slona u \u0161ahu. Ili skloniti se iza zida da biste sigurno pucali u XCOM-u. Uglavnom, shvatili ste poantu.<\/p>\n<h3>Pobolj\u0161ano planiranje<\/h3>\n<p>\nPonekad ima previ\u0161e potencijalnih akcija da bismo razmatrali svaku mogu\u0107u opciju. Vra\u0107aju\u0107i se primjeru iz Magic: The Gathering: pretpostavimo da u igri imate nekoliko karata zemlje i stvorenja \u2014 broj mogu\u0107ih kombinacija poteza mo\u017ee se mjeriti desecima. Postoji nekoliko rje\u0161enja za ovaj problem.<\/p>\n<p>Prvi na\u010din je backtracking (potraga unazad). Umjesto da razmatramo sve kombinacije, bolje je po\u010deti od kona\u010dnog rezultata i poku\u0161ati prona\u0107i izravnu rutu. Umjesto puta od korijena drveta do odre\u0111enog lista, kre\u0107emo se u suprotnom smjeru \u2014 od lista prema korijenu. Ovaj pristup je jednostavniji i br\u017ei.<\/p>\n<p>Ako protivnik ima 1 jedinu \u017eivotnu to\u010dku, mo\u017eete prona\u0107i plan \"nanijeti 1 ili vi\u0161e \u0161tete\". Da biste to postigli, potrebno je ispuniti niz uvjeta: <\/p>\n<p>1. \u0160tetu mo\u017ee nanijeti \u010darolija \u2014 treba je imati u ruci.<br \/>\n2. Da biste odigrali \u010daroliju \u2014 potrebna je mana.<br \/>\n3. Da biste dobili manau \u2014 treba odigrati kartu zemlje.<br \/>\n4. Da biste odigrali kartu zemlje \u2014 treba je imati u ruci.<\/p>\n<p>Drugi na\u010din je best-first search (najbolja prva pretraga). Umjesto da razmatramo sve putanje, biramo najprikladniju. Naj\u010de\u0161\u0107e ovaj pristup daje optimalan plan bez nepotrebnih tro\u0161kova pretra\u017eivanja. A* je oblik najbolje prve pretrage \u2014 istra\u017euju\u0107i najperspektivnije rute od samog po\u010detka, mo\u017ee ve\u0107 prona\u0107i najbolji put bez potrebe za provjerom ostalih opcija.<\/p>\n<p>Zanimljiv i sve popularniji pristup best-first pretra\u017eivanju je Monte Carlo Tree Search. Umjesto da naga\u0111a koji su planovi bolji od drugih pri odabiru svakog sljede\u0107eg koraka, algoritam odabire nasumi\u010dne nasljednike na svakom koraku dok ne dosegne kraj (kada plan dovede do pobjede ili poraza). Zatim se kona\u010dni rezultat koristi za pove\u0107anje ili smanjenje ocjene \"te\u017eine\" prethodnih mogu\u0107nosti. Ponovnim izvo\u0111enjem ovog procesa nekoliko puta, algoritam daje dobru procjenu koji je sljede\u0107i korak bolji, \u010dak i ako se situacija promijeni (ako protivnik poduzme mjere da ometa igra\u010da). <\/p>\n<p>U pri\u010di o planiranju u igrama ne mo\u017ee se zaobi\u0107i Goal-Oriented Action Planning ili GOAP (planiranje akcija usmjerenih na cilj). Ovo je \u0161iroko kori\u0161tena i raspravljana metoda, ali osim nekoliko prepoznatljivih detalja, to je u su\u0161tini metoda unazadnog povezivanja o kojoj smo ranije govorili. Ako je zadatak \"uni\u0161titi igra\u010da\", a igra\u010d se nalazi iza zaklona, plan mo\u017ee izgledati ovako: uni\u0161ti granatom \u2192 dohvati je \u2192 baci.<\/p>\n<p>Obi\u010dno postoji nekoliko ciljeva, svaki sa svojim prioritetom. Ako cilj s najvi\u0161im prioritetom ne mo\u017ee biti ostvaren (nijedna kombinacija radnji ne stvara plan \"uni\u0161ti igra\u010da\" jer igra\u010d nije vidljiv), AI \u0107e se vratiti na ciljeve s ni\u017eim prioritetom.<\/p>\n<h2>U\u010denje i prilagodba<\/h2>\n<p>\nVe\u0107 smo spomenuli da igra\u0107i AI obi\u010dno ne koristi strojno u\u010denje, jer nije pogodno za upravljanje agentima u stvarnom vremenu. No to ne zna\u010di da se ne mo\u017ee posuditi ne\u0161to iz te oblasti. \u017delimo takvog protivnika u shooteru od kojeg mo\u017eemo ne\u0161to nau\u010diti. Na primjer, da saznamo o najboljim pozicijama na karti. Ili protivnika u borbenoj igri koji bi blokirao \u010desto kori\u0161tene kombinacije igra\u010da, poti\u010du\u0107i ih da koriste druge. Tako da strojno u\u010denje u takvim situacijama mo\u017ee biti vrlo korisno.<\/p>\n<h3>Statistika i vjerojatnosti<\/h3>\n<p>\nPrije nego \u0161to pre\u0111emo na slo\u017eenije primjere, razmotrit \u0107emo koliko daleko mo\u017eemo oti\u0107i uzimaju\u0107i nekoliko jednostavnih mjerenja i koriste\u0107i ih za dono\u0161enje odluka. Na primjer, u strategiji u stvarnom vremenu \u2014 kako mo\u017eemo utvrditi mo\u017ee li igra\u010d zapo\u010deti napad u prvih nekoliko minuta igre i kakvu obranu protiv toga pripremiti? Mo\u017eemo prou\u010diti prethodno iskustvo igra\u010da kako bismo razumjeli koja bi mogla biti budu\u0107a reakcija. Po\u010dnimo s tim da nemamo takve ulazne podatke, ali ih mo\u017eemo prikupiti \u2014 svaki put kada AI igra protiv \u010dovjeka, mo\u017ee zabilje\u017eiti vrijeme prvog napada. Nakon nekoliko sesija dobit \u0107emo prosje\u010dnu vrijednost vremena kada \u0107e igra\u010d napasti u budu\u0107nosti.<\/p>\n<p>Postoji i problem s prosje\u010dnim vrijednostima: ako je igra\u010d 20 puta napao brzo, a 20 puta igrao polako, potrebne vrijednosti bit \u0107e negdje u sredini, a to nam ne\u0107e dati ni\u0161ta korisno. Jedno od rje\u0161enja je ograni\u010denje ulaznih podataka \u2014 mo\u017eemo uzeti u obzir posljednjih 20 slu\u010dajeva.<\/p>\n<p>Sli\u010dan pristup se koristi za procjenu vjerojatnosti odre\u0111enih akcija, pod pretpostavkom da \u0107e pro\u0161le preferencije igra\u010da biti iste u budu\u0107nosti. Ako nas igra\u010d napada pet puta vatrenom kuglom, dva puta munjom i jednom iz blizine, o\u010dito je da preferira vatrenu kuglu. Ekstrapolirajmo i vidimo vjerojatnost kori\u0161tenja razli\u010ditog oru\u017eja: vatrena kugla = 62,5%, munja = 25% i iz blizine = 12,5%. Na\u0161 igrivi AI treba se pripremiti za obranu od vatre.<\/p>\n<p>Jo\u0161 jedna zanimljiva metoda je kori\u0161tenje Naive Bayes Classifier (naivni bayesovski klasifikator) za prou\u010davanje velikih koli\u010dina ulaznih podataka i klasificiranje situacije kako bi AI reagirao na odgovaraju\u0107i na\u010din. Bayesovski klasifikatori su najpoznatiji po kori\u0161tenju u spam filtrima elektroni\u010dke po\u0161te. Tamo prou\u010davaju rije\u010di, uspore\u0111uju ih s onim gdje su se te rije\u010di ranije pojavljivale (u spam porukama ili ne) i donose zaklju\u010dke o dolaznim porukama. Mo\u017eemo u\u010diniti isto \u010dak i s manjim brojem ulaznih podataka. Na temelju svih korisnih informacija koje AI vidi (na primjer, koje neprijateljske jedinice su stvorene, ili koje \u010darolije koriste, ili koje tehnologije istra\u017euju) i kona\u010dnog rezultata (rat ili mir, \u201enapasti\u201c ili obraniti se itd.) \u2014 odabrat \u0107emo odgovaraju\u0107e pona\u0161anje AI.<\/p>\n<p>Svi ti na\u010dini u\u010denja su dovoljni, ali je po\u017eeljno koristiti ih na temelju podataka iz testiranja. AI \u0107e nau\u010diti prilagoditi se razli\u010ditim strategijama koje su koristili va\u0161i testeri. AI koji se prilago\u0111ava igra\u010du nakon izlaska igre mo\u017ee postati previ\u0161e predvidljiv ili, s druge strane, prete\u017eak za pobijediti.<\/p>\n<h3>Prilagodba na temelju vrijednosti<\/h3>\n<p>\nUzimaju\u0107i u obzir sadr\u017eaj na\u0161eg igre i pravila, mo\u017eemo promijeniti skup vrijednosti koje utje\u010du na dono\u0161enje odluka, a ne samo koristiti ulazne podatke. Radimo ovako:<\/p>\n<ul>\n<li>Neka AI prikuplja podatke o stanju svijeta i klju\u010dnim doga\u0111ajima tijekom igre (kao \u0161to je navedeno gore).<\/li>\n<li>Promijenimo nekoliko va\u017enih vrijednosti (value) na temelju tih podataka.<\/li>\n<li>Implementirajmo svoja rje\u0161enja temeljem obrade ili procjene tih vrijednosti.<\/li>\n<\/ul>\n<p>\nNa primjer, agent ima nekoliko soba za odabir na karti puca\u010dine iz prvog lica. Svaka soba ima svoju vrijednost, koja odre\u0111uje koliko je po\u017eeljna za posjet. AI nasumi\u010dno bira u koju sobu \u0107e i\u0107i, temelje\u0107i se na vrijednosti. Zatim agent zapamti u kojoj je sobi ubijen i smanjuje njezinu vrijednost (vjerojatnost da se vrati). Sli\u010dna situacija se doga\u0111a kada agent uni\u0161ti mnogo protivnika \u2014 tada se vrijednost sobe pove\u0107ava.<\/p>\n<h3>Markov model<\/h3>\n<p>\n\u0160to ako iskoristimo prikupljene podatke za predvi\u0111anje? Ako zapamtimo svaku sobu u kojoj smo vidjeli igra\u010da tijekom odre\u0111enog vremenskog razdoblja, predvi\u0111at \u0107emo u koju sobu igra\u010d mo\u017ee pre\u0107i. Pra\u0107enjem i zapisivanjem kretanja igra\u010da po sobama (values), mo\u017eemo ih predvidjeti.<\/p>\n<p>Uzmimo tri sobe: crvenu, zelenu i plavu. Tako\u0111er, zabilje\u017eimo opa\u017eanja koja smo prikupili tijekom gledanja igra\u010dke sesije:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/6e90a365b72a176c36c9a14213baaafc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nBroj opa\u017eanja svake sobe je gotovo jednak \u2014 jo\u0161 uvijek ne znamo gdje napraviti dobro mjesto za zasjedu. Prikupljanje statistike tako\u0111er ote\u017eava respawn igra\u010da koji se pojavljuju ravnomjerno po cijeloj karti. No, podaci o sljede\u0107oj sobi u koju ulaze nakon pojavljivanja na karti \u2014 ve\u0107 su korisni.<\/p>\n<p>Vidljivo je da zelena soba privla\u010di igra\u010de - ve\u0107ina ljudi iz crvene dolazi u nju, a 50% njih ostaje unutra. Plava soba, s druge strane, nije popularna, gotovo nitko ne ide u nju, a ako idu, ne zadr\u017eavaju se. <\/p>\n<p>Ali podaci nam govore ne\u0161to va\u017enije - kada je igra\u010d u plavoj sobi, sljede\u0107a soba u kojoj \u0107emo ga najvjerojatnije vidjeti bit \u0107e crvena, a ne zelena. Unato\u010d tome \u0161to je zelena soba popularnija od crvene, situacija se mijenja ako je igra\u010d u plavoj. Sljede\u0107e stanje (tj. soba u koju \u0107e igra\u010d pre\u0107i) ovisi o prethodnom stanju (tj. sobi u kojoj se igra\u010d trenutno nalazi). Zbog istra\u017eivanja ovih zavisnosti, prognoze \u0107emo raditi to\u010dnije nego da smo samo brojali promatranja neovisno jedno o drugome.<\/p>\n<p>Predvi\u0111anje budu\u0107eg stanja na temelju podataka pro\u0161log stanja naziva se Markovljevim modelom, a takvi primjeri (s sobama) nazivaju se Markovljevim lancima. Budu\u0107i da modeli predstavljaju vjerojatnost promjena izme\u0111u uzastopnih stanja, vizualno se prikazuju kao FSM s vjerojatnostima oko svake tranzicije. Ranije smo koristili FSM za predstavljanje pona\u0161ajnog stanja agenta, ali ovaj koncept se pro\u0161iruje na bilo koje stanje, bez obzira je li povezano s agentom ili ne. U ovom slu\u010daju, stanja predstavljaju sobu koju zauzima agent:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/edb32dff7a3298b19c3fa4d66f48e9f4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nOvo je jednostavna varijanta prikazivanja relativne vjerojatnosti promjena stanja, koja daje AI odre\u0111enu mogu\u0107nost predvi\u0111anja sljede\u0107eg stanja. Mo\u017ee se predvidjeti nekoliko koraka unaprijed.<\/p>\n<p>Ako je igra\u010d u zelenoj sobi, postoji 50% \u0161anse da \u0107e ostati unutra pri sljede\u0107em promatranju. Ali koja je vjerojatnost da \u0107e i dalje ostati \u010dak i nakon toga? Postoji ne samo \u0161ansa da je igra\u010d ostao u zelenoj sobi nakon dva promatranja, ve\u0107 i \u0161ansa da je oti\u0161ao i vratio se. Evo nove tablice s obzirom na nove podatke:<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/f87afff68b066a879661e37f68654ae2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nIz nje se vidi da \u0107e \u0161ansa da vidimo igra\u010da u zelenoj sobi nakon dva promatranja biti 51% - 21% da dolazi iz crvene sobe, 5% da \u0107e igra\u010d posjetiti plavu sobu izme\u0111u njih, i 25% da igra\u010d uop\u0107e ne napusti zelenu sobu.<\/p>\n<p>Tablica je jednostavan vizualni alat; postupak zahtijeva samo mno\u017eenje vjerojatnosti na svakom koraku. To zna\u010di da mo\u017eete zagledati daleko u budu\u0107nost uz jednu ispravku: pretpostavljamo da \u0161ansa ulaska u sobu potpuno ovisi o trenutnoj sobi. To se naziva Markovljevo svojstvo (Markov Property) \u2014 budu\u0107e stanje ovisi samo o sada\u0161njosti. Ali to nije sto posto to\u010dno. Igra\u010di mogu mijenjati odluke prema drugim faktorima: razini zdravlja ili broju metaka. Kako ne bilje\u017eimo te vrijednosti, na\u0161i prognoze \u0107e biti manje to\u010dne.<\/p>\n<h3>N-Grami<\/h3>\n<p>\nA \u0161to je s primjerom borbene igre i predvi\u0111anjem kombinacija poteza igra\u010da? Ista stvar! No umjesto jednog stanja ili doga\u0111aja, istra\u017eujemo cijele sekvence koje \u010dine kombo-potez.<\/p>\n<p>Jedan od na\u010dina da to u\u010dinite je zadr\u017eati svaki unos (npr. Kick, Punch ili Block) u baferu i zapisati cijeli bafer kao doga\u0111aj. Dakle, igra\u010d neprekidno pritisne Kick, Kick, Punch da bi iskoristio napad SuperDeathFist, a sustav AI pohranjuje sve unose u baferu i pamti posljednja tri, kori\u0161tena na svakom koraku.<\/p>\n<p><img decoding=\"async\" alt=\"Kako stvoriti gaming AI: vodi\u010d za po\u010detnike\" src=\"\/wp-content\/uploads\/2019\/11\/9a95226ae155dca5e45a66d4440f3cd4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(Pojedine linije su podebljane kada igra\u010d pokrene napad SuperDeathFist.)<\/p>\n<p>AI \u0107e vidjeti sve varijante kada igra\u010d odabere Kick, a zatim jo\u0161 jedan Kick, a nakon toga uo\u010di da je sljede\u0107i unos uvijek Punch. To \u0107e omogu\u0107iti agentu da predvidi kombo-potez SuperDeathFist i blokira ga, ako je mogu\u0107e.<\/p>\n<p>Ove sekvence doga\u0111aja nazivamo N-gramima (N-grams), gdje je N broj pohranjenih elemenata. U prethodnom primjeru to je bila 3-grama (trigram), \u0161to zna\u010di: prva dva unosa koriste se za predvi\u0111anje tre\u0107eg. Tako\u0111er, u 5-grami, prva \u010detiri unosa predvi\u0111aju peti i tako dalje.<\/p>\n<p>Razvija\u010d mora pa\u017eljivo birati veli\u010dinu N-grama. Manji broj N zahtijeva manje memorije, ali pohranjuje manje povijesti. Na primjer, 2-grama (bigram) \u0107e bilje\u017eiti Kick, Kick ili Kick, Punch, ali ne mo\u017ee pohraniti Kick, Kick, Punch, stoga AI ne\u0107e reagirati na kombo SuperDeathFist.<\/p>\n<p>S druge strane, ve\u0107i brojevi zahtijevaju vi\u0161e memorije i AI \u0107e biti te\u017ee obu\u010diti se, budu\u0107i da \u0107e postojati mnogo vi\u0161e mogu\u0107ih varijanti. Ako ste imali tri mogu\u0107a unosa Kick, Punch ili Block, a koristili smo 10-gramu, dobili bismo oko 60 tisu\u0107a razli\u010ditih varijanti.<\/p>\n<p>Model bigram je jednostavna Markovljeva lanca \u2014 svaka par \"pro\u0161la stanja\/aktualno stanje\" je bigram, a mo\u017eete predvidjeti drugo stanje na temelju prvog. 3-grami i ve\u0107i N-grami tako\u0111er se mogu smatrati Markovljevim lancima, gdje svi elementi (osim posljednjeg u N-gramu) zajedno \u010dine prvo stanje, a posljednji element drugo. Primjer s borila\u010dkim vje\u0161tinama pokazuje vjerojatnost prijelaza iz stanja Kick i Kick u stanje Kick i Punch. Gledaju\u0107i nekoliko unosa ulazne povijesti kao jednu jedinicu, zapravo transformiramo ulaznu sekvencu u dio cjelokupnog stanja. To nam daje Markovsku svojstvo, omogu\u0107uju\u0107i kori\u0161tenje Markovljevih lanaca za predvi\u0111anje sljede\u0107eg unosa i poga\u0111anje koji \u0107e akcijski potez biti sljede\u0107i.<\/p>\n<h2>Zaklju\u010dak<\/h2>\n<p>\nRazgovarali smo o naj\u010de\u0161\u0107im alatima i pristupima u razvoju umjetne inteligencije. Tako\u0111er smo raspravili o situacijama u kojima ih treba primijeniti i gdje su posebno korisni. <\/p>\n<p>To bi trebalo biti dovoljno za razumijevanje osnovnih stvari u igranom AI. No, naravno, to nije sve metode. Mnoge manje popularne, ali jednako u\u010dinkovite uklju\u010duju:<\/p>\n<ul>\n<li>algoritmi optimizacije, uklju\u010duju\u0107i uspinjanje na brdo, gradijentni spust i genetske algoritme<\/li>\n<li>natjecateljski algoritmi pretra\u017eivanja\/plansiranja (minimax i alpha-beta rezanje)<\/li>\n<li>metode klasifikacije (perceptroni, neuronske mre\u017ee i potporne vektorske ma\u0161ine)<\/li>\n<li>sustavi za obradu percepcije i memoriju agenata<\/li>\n<li>architektonski pristupi AI (hibridni sustavi, podskup arhitektura i drugi na\u010dini preklapanja AI sustava)<\/li>\n<li>alat za animaciju (planiranje i uskla\u0111ivanje pokreta)<\/li>\n<li>faktori performansi (razina detalja, anytime algoritmi i timeslicing)<\/li>\n<\/ul>\n<p>\nInternet izvori o temi:<\/p>\n<p>1. Na GameDev.net postoji <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gamedev.net\/articles\/programming\/artificial-intelligence\/\">odjeljak s \u010dlancima i tutorijalima o AI<\/a><\/noindex>, kao i <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> sadr\u017ei brojne prezentacije i \u010dlanke o \u0161irokom spektru povezanih s razvojem igranog AI.<br \/>\n3. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gdcvault.com\/\">The GDC Vault<\/a><\/noindex> uklju\u010duje teme sa samita GDC AI, od kojih su mnoge dostupne besplatno.<br \/>\n4. Korisni materijali tako\u0111er se mogu na\u0107i na stranici <noindex><a rel=\"nofollow\" href=\"http:\/\/gameai.com\/\">AI Game Programmers Guild<\/a><\/noindex>.<br \/>\n5. Tommy Thompson, istra\u017eiva\u010d AI i razvoj igara, snima videa na YouTube kanalu <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/tthompso\">AI and Games<\/a><\/noindex> s obja\u0161njenjem i prou\u010davanjem AI u komercijalnim igrama.<\/p>\n<p>Knjige o temi:<\/p>\n<p>1. Serija knjiga Game AI Pro predstavlja zbirke kratkih \u010dlanaka koji obja\u0161njavaju kako implementirati odre\u0111ene funkcionalnosti ili kako rje\u0161avati specifi\u010dne probleme.<\/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: Prikupljena mudrost profesionalaca iz podru\u010dja igara<\/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: Prikupljena mudrost profesionalaca iz podru\u010dja igara<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2KF4irS\">Game AI Pro 3: Prikupljena mudrost profesionalaca iz podru\u010dja igara<\/a><\/noindex><\/p>\n<p>2. Serija AI Game Programming Wisdom \u2014 prethodnica serije Game AI Pro. Sadr\u017ei starije metode, ali su gotovo sve i dalje aktualne.<\/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\">Umjetna inteligencija: Moderni pristup<\/a><\/noindex> \u2014 jedan je od osnovnih tekstova za sve koji \u017eele razumjeti op\u0107e podru\u010dje umjetne inteligencije. Ova knjiga nije o razvoju igara \u2014 podu\u010dava osnovnim principima AI.<br \/>\n<br \/>Izvor: <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\/hr\/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=\"hr_HR\" \/>\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\/hr\/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\udd47Kako stvoriti gaming AI: vodi\u010d za po\u010detnike | ProHoster","description":"Nai\u0161ao sam na zanimljiv materijal o.","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\/hr\/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\/hr\/wp-json\/wp\/v2\/posts\/52118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=52118"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/52118\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=52118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=52118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=52118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}