{"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\/pl\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","title":{"rendered":"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/9e57175b233a104e0df98383b374eded.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNatkn\u0105\u0142em si\u0119 na interesuj\u0105cy materia\u0142 o sztucznej inteligencji w grach. Z wyja\u015bnieniem podstawowych rzeczy o AI na prostych przyk\u0142adach oraz z wieloma przydatnymi narz\u0119dziami i metodami do wygodnego rozwoju i projektowania. Jak, gdzie i kiedy ich u\u017cywa\u0107 \u2014 r\u00f3wnie\u017c jest.<\/p>\n<p>Wi\u0119kszo\u015b\u0107 przyk\u0142ad\u00f3w jest napisana w pseudokodzie, wi\u0119c nie s\u0105 wymagane g\u0142\u0119bokie znajomo\u015bci programowania. Pod tym linkiem 35 stron tekstu z obrazkami i gifami, wi\u0119c przygotujcie si\u0119.<\/p>\n<p>UPD. Przepraszam, ale ju\u017c zrobi\u0142em w\u0142asny przek\u0142ad tego artyku\u0142u na Habra. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/users\/PatientZero\/\">PatientZero<\/a><\/noindex>. Mo\u017cna przeczyta\u0107 jego wersj\u0119 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/post\/420219\/\">tutaj<\/a><\/noindex>, ale jako\u015b artyku\u0142 umkn\u0105\u0142 mojej uwadze (korzysta\u0142em z wyszukiwarki, ale co\u015b posz\u0142o nie tak). A poniewa\u017c pisz\u0119 na blogu po\u015bwi\u0119conym grom, postanowi\u0142em zostawi\u0107 swoj\u0105 wersj\u0119 przek\u0142adu dla subskrybent\u00f3w (niekt\u00f3re momenty u mnie s\u0105 uj\u0119te inaczej, inne \u2014 celowo pomini\u0119te na rad\u0119 tw\u00f3rc\u00f3w).<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Co to jest AI?<\/h2>\n<p>\nAI w grach koncentruje si\u0119 na tym, jakie dzia\u0142ania powinien podejmowa\u0107 obiekt w zale\u017cno\u015bci od warunk\u00f3w, w jakich si\u0119 znajduje. Zwykle nazywa si\u0119 to zarz\u0105dzaniem \u201einteligentnymi agentami\u201d, gdzie agentem jest posta\u0107 w grze, \u015brodek transportu, bot, a czasem co\u015b bardziej abstrakcyjnego: ca\u0142a grupa byt\u00f3w lub nawet cywilizacja. W ka\u017cdym przypadku chodzi o to, \u017ce co\u015b musi dostrzega\u0107 swoje otoczenie, podejmowa\u0107 na jego podstawie decyzje i dzia\u0142a\u0107 zgodnie z nimi. To nazywa si\u0119 cyklem Sense \/ Think \/ Act (Czuj \/ My\u015bl \/ Dzia\u0142aj):<\/p>\n<ul>\n<li>Czuj: agent znajduje lub otrzymuje informacje o rzeczach w swoim otoczeniu, kt\u00f3re mog\u0105 wp\u0142yn\u0105\u0107 na jego zachowanie (zagro\u017cenia w pobli\u017cu, przedmioty do zebrania, interesuj\u0105ce miejsca do zbadania).<\/li>\n<li>My\u015bl: agent decyduje, jak zareagowa\u0107 (rozwa\u017ca, czy zbiera\u0107 przedmioty, czy najpierw stawi\u0107 czo\u0142a zagro\u017ceniu \/ schowa\u0107 si\u0119).<\/li>\n<li>Dzia\u0142aj: agent wykonuje dzia\u0142ania w celu wdro\u017cenia poprzedniej decyzji (rozpoczyna ruch w stron\u0119 przeciwnika lub przedmiotu).<\/li>\n<li>\u2026teraz sytuacja zmieni\u0142a si\u0119 z powodu dzia\u0142a\u0144 postaci, dlatego cykl powtarza si\u0119 z nowymi danymi.<\/li>\n<\/ul>\n<p>\nSztuczna inteligencja koncentruje si\u0119 zazwyczaj na cz\u0119\u015bci cyklu Sense. Na przyk\u0142ad autonomiczne samochody wykonuj\u0105 zdj\u0119cia drogi, \u0142\u0105cz\u0105 je z danymi radarowymi i lidarowymi oraz je interpretuj\u0105. Zwykle robi to uczenie maszynowe, kt\u00f3re przetwarza dane wej\u015bciowe i nadaje im sens, wydobywaj\u0105c informacje semantyczne, takie jak \u201ejest jeszcze jeden samoch\u00f3d 20 jard\u00f3w przed tob\u0105\u201d. To tak zwane problemy klasyfikacyjne.<\/p>\n<p>Gry nie potrzebuj\u0105 skomplikowanego systemu do wydobywania informacji, poniewa\u017c wi\u0119kszo\u015b\u0107 danych jest ju\u017c ich nieod\u0142\u0105czn\u0105 cz\u0119\u015bci\u0105. Nie ma potrzeby uruchamiania algorytm\u00f3w rozpoznawania obraz\u00f3w, aby stwierdzi\u0107, czy przed nami znajduje si\u0119 wr\u00f3g \u2014 gra ju\u017c wie i przekazuje informacje bezpo\u015brednio w procesie podejmowania decyzji. Dlatego cz\u0119\u015b\u0107 cyklu Sense jest zwykle znacznie prostsza ni\u017c Think i Act.<\/p>\n<h2>Ograniczenia AI w grach<\/h2>\n<p>\nAI ma szereg ogranicze\u0144, kt\u00f3re nale\u017cy uwzgl\u0119dni\u0107:<\/p>\n<ul>\n<li>AI nie musi by\u0107 wcze\u015bniej szkolone, jak algorytm uczenia maszynowego. Nie ma sensu tworzy\u0107 sieci neuronowej w trakcie rozwoju, aby obserwowa\u0107 dziesi\u0105tki tysi\u0119cy graczy i uczy\u0107 si\u0119, jak najlepiej gra\u0107 przeciwko nim. Dlaczego? Poniewa\u017c gra nie zosta\u0142a wydana, a graczy nie ma.<\/li>\n<li>Gra powinna zapewnia\u0107 rozrywk\u0119 i stawia\u0107 wyzwania, dlatego agenci nie powinni znajdowa\u0107 najlepszego podej\u015bcia do ludzi.<\/li>\n<li>Agenci musz\u0105 wygl\u0105da\u0107 realistycznie, aby gracze czuli, \u017ce graj\u0105 przeciwko prawdziwym ludziom. Program AlphaGo przewy\u017cszy\u0142 cz\u0142owieka, ale wybrane ruchy by\u0142y dalekie od tradycyjnego rozumienia gry. Je\u015bli gra imituje przeciwnika-ludzkiego, takie odczucie nie powinno zosta\u0107 wywo\u0142ane. Algorytm musi zosta\u0107 zmieniony, aby podejmowa\u0142 prawdopodobne decyzje, a nie idealne.<\/li>\n<li>AI musi dzia\u0142a\u0107 w czasie rzeczywistym. Oznacza to, \u017ce algorytm nie mo\u017ce monopolizowa\u0107 procesora przez d\u0142ugi czas na podejmowanie decyzji. Nawet 10 milisekund na to to zbyt d\u0142ugo, poniewa\u017c wi\u0119kszo\u015b\u0107 gier potrzebuje od 16 do 33 milisekund na przetworzenie wszystkiego i przej\u015bcie do nast\u0119pnej klatki grafiki.<\/li>\n<li>Idealnie, je\u015bli przynajmniej cz\u0119\u015b\u0107 systemu jest zarz\u0105dzana danymi, aby \u201enieprogrami\u015bci\u201d mogli wprowadza\u0107 zmiany, a modyfikacje odbywa\u0142y si\u0119 szybciej.<\/li>\n<\/ul>\n<p>\nRozwa\u017cmy podej\u015bcia AI, kt\u00f3re obejmuj\u0105 ca\u0142y cykl Sense\/Think\/Act.<\/p>\n<h3>Podejmowanie podstawowych decyzji<\/h3>\n<p>\nZacznijmy od najprostszej gry \u2014 Pong. Cel: przesun\u0105\u0107 platform\u0119 (paddle) tak, aby pi\u0142ka odbija\u0142a si\u0119 od niej, a nie przechodzi\u0142a obok. To jak w tenisie, w kt\u00f3rym przegrywasz, je\u015bli nie odbijesz pi\u0142ki. Tutaj AI ma stosunkowo \u0142atwe zadanie \u2014 ustali\u0107, w kt\u00f3rym kierunku przesun\u0105\u0107 platform\u0119.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/e1935d657b9f090bf60c365c21e8f92b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Operatory warunkowe<\/h3>\n<p>\nDla AI w Pong jest najbardziej oczywistym rozwi\u0105zaniem \u2014 zawsze stara\u0107 si\u0119 umie\u015bci\u0107 platform\u0119 pod pi\u0142k\u0105.<\/p>\n<p>Prosty algorytm do tego, zapisany w pseudokodzie:<\/p>\n<p><i>co klatk\u0119\/aktualizacj\u0119, gdy gra trwa:<br \/>\nje\u015bli pi\u0142ka jest po lewej stronie platformy:<br \/>\n przesu\u0144 platform\u0119 w lewo<br \/>\nw przeciwnym razie, je\u015bli pi\u0142ka jest po prawej stronie platformy:<br \/>\n przesu\u0144 platform\u0119 w prawo<\/i><\/p>\n<p>Je\u015bli platforma porusza si\u0119 z pr\u0119dko\u015bci\u0105 pi\u0142ki, to idealny algorytm dla AI w Pong. Nie ma potrzeby komplikowa\u0107, je\u015bli dane i mo\u017cliwe dzia\u0142ania dla agenta nie s\u0105 zbyt liczne.<\/p>\n<p>Podej\u015bcie to jest na tyle proste, \u017ce ca\u0142y cykl Sense\/Think\/Act jest ledwie zauwa\u017calny. Ale on istnieje:<\/p>\n<ul>\n<li>Cz\u0119\u015b\u0107 Sense znajduje si\u0119 w dw\u00f3ch operatorach if. Gra wie, gdzie jest pi\u0142ka, a gdzie platforma, wi\u0119c AI korzysta z tych informacji. <\/li>\n<li>Cz\u0119\u015b\u0107 Think tak\u017ce zawiera dwa operatory if. Reprezentuj\u0105 one dwa rozwi\u0105zania, kt\u00f3re w tym przypadku s\u0105 wzajemnie wykluczaj\u0105ce. W efekcie wybierane jest jedno z trzech dzia\u0142a\u0144 \u2014 przesuni\u0119cie platformy w lewo, w prawo lub nic nie robienie, je\u015bli ju\u017c jest prawid\u0142owo ustawiona.<\/li>\n<li>Cz\u0119\u015b\u0107 Act znajduje si\u0119 w operatorach Move Paddle Left i Move Paddle Right. W zale\u017cno\u015bci od projektu gry, mog\u0105 one przesuwa\u0107 platform\u0119 natychmiastowo lub z okre\u015blon\u0105 pr\u0119dko\u015bci\u0105. <\/li>\n<\/ul>\n<p>\nTakie podej\u015bcia nazywane s\u0105 reaguj\u0105cymi \u2014 istnieje prosty zestaw regu\u0142 (w tym przypadku operatory if w kodzie), kt\u00f3re reaguj\u0105 na aktualny stan \u015bwiata i dzia\u0142aj\u0105.<\/p>\n<h3>Drzewo decyzyjne<\/h3>\n<p>\nPrzyk\u0142ad z gr\u0105 Pong r\u00f3wnoznaczny jest formalnej koncepcji AI, zwanej drzewem decyzyjnym. Algorytm przechodzi przez nie, aby osi\u0105gn\u0105\u0107 \u00abli\u015b\u0107\u00bb \u2014 decyzj\u0119, jakie dzia\u0142anie podj\u0105\u0107.<\/p>\n<p>Zr\u00f3bmy schemat blokowy drzewa decyzyjnego dla algorytmu naszej platformy:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/d3b7290ba93144967cd849416cd5eef3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nKa\u017cda cz\u0119\u015b\u0107 drzewa nazywa si\u0119 node (w\u0119ze\u0142) \u2014 AI wykorzystuje teori\u0119 graf\u00f3w do opisu podobnych struktur. Istniej\u0105 dwa typy w\u0119z\u0142\u00f3w:<\/p>\n<ul>\n<li>W\u0119z\u0142y decyzyjne: wyb\u00f3r mi\u0119dzy dwoma alternatywami na podstawie sprawdzenia pewnego warunku, gdzie ka\u017cda alternatywa reprezentowana jest w postaci oddzielnego w\u0119z\u0142a.<\/li>\n<li>W\u0119z\u0142y ko\u0144cowe: dzia\u0142anie do wykonania, reprezentuj\u0105ce ostateczn\u0105 decyzj\u0119.<\/li>\n<\/ul>\n<p>\nAlgorytm zaczyna si\u0119 od pierwszego w\u0119z\u0142a (\u201ekorzenia\u201d drzewa). Decyduje on, do kt\u00f3rego w\u0119z\u0142a potomnego przej\u015b\u0107, lub wykonuje dzia\u0142anie zapisane w w\u0119\u017ale i ko\u0144czy dzia\u0142anie.<\/p>\n<p>Jakie s\u0105 korzy\u015bci, skoro drzewo decyzyjne wykonuje t\u0119 sam\u0105 prac\u0119, co operatory if z poprzedniej sekcji? Istnieje tu wsp\u00f3lny system, w kt\u00f3rym ka\u017cda decyzja ma tylko jeden warunek i dwa mo\u017cliwe wyniki. Pozwala to programi\u015bcie na tworzenie AI z danych reprezentuj\u0105cych decyzje w drzewie, unikaj\u0105c jego twardego zakodowania. Mo\u017cemy to przedstawi\u0107 w formie tabeli:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/6875293a60ff9d0efa26fb5e1aa4b21c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPo stronie kodu otrzymasz system do odczytu wierszy. Utw\u00f3rz w\u0119ze\u0142 dla ka\u017cdego z nich, po\u0142\u0105cz logik\u0119 podejmowania decyzji na podstawie drugiej kolumny oraz w\u0119z\u0142y potomne na podstawie trzeciej i czwartej kolumny. Nadal musisz zaprogramowa\u0107 warunki i dzia\u0142ania, ale teraz struktura gry stanie si\u0119 bardziej z\u0142o\u017cona. Dodasz dodatkowe decyzje i dzia\u0142ania, a nast\u0119pnie dostosujesz ca\u0142e AI, po prostu edytuj\u0105c plik tekstowy z definicj\u0105 drzewa. Nast\u0119pnie przeka\u017cesz plik projektantowi gier, kt\u00f3ry b\u0119dzie m\u00f3g\u0142 zmieni\u0107 zachowanie bez rekompilacji gry i zmiany kodu.<\/p>\n<p>Drewa decyzyjne s\u0105 bardzo u\u017cyteczne, gdy s\u0105 automatycznie budowane na podstawie du\u017cego zestawu przyk\u0142ad\u00f3w (na przyk\u0142ad z u\u017cyciem algorytmu ID3). Sprawia to, \u017ce s\u0105 one efektywnym i wydajnym narz\u0119dziem do klasyfikacji sytuacji na podstawie uzyskiwanych danych. Jednak wykraczamy poza prosty system do dobierania dzia\u0142a\u0144 przez agent\u00f3w.<\/p>\n<h3>Scenariusze<\/h3>\n<p>\nOm\u00f3wili\u015bmy system drzewa decyzyjnego, kt\u00f3ry wykorzystywa\u0142 wcze\u015bniej ustalone warunki i dzia\u0142ania. Osoba projektuj\u0105ca AI mo\u017ce zorganizowa\u0107 drzewo tak, jak chce, ale wci\u0105\u017c musi polega\u0107 na programi\u015bcie, kt\u00f3ry to wszystko zaprogramowa\u0142. Co by by\u0142o, gdyby\u015bmy mogli da\u0107 projektantowi narz\u0119dzia do tworzenia w\u0142asnych warunk\u00f3w lub dzia\u0142a\u0144?<\/p>\n<p>Aby programista nie musia\u0142 pisa\u0107 kodu dla warunk\u00f3w Is Ball Left Of Paddle i Is Ball Right Of Paddle, mo\u017ce stworzy\u0107 system, w kt\u00f3rym projektant zapisze warunki do sprawdzenia tych warto\u015bci. W\u00f3wczas dane drzewa decyzyjnego b\u0119d\u0105 wygl\u0105da\u0107 tak:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/8e77f7c3410d097e8b7d8e1209355cc6.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW zasadzie jest to to samo, co w pierwszej tabeli, ale rozwi\u0105zania maj\u0105 w\u0142asny kod, troch\u0119 przypominaj\u0105cy warunkow\u0105 cz\u0119\u015b\u0107 if-operatora. W kodzie by\u0142oby to odczytywane w drugiej kolumnie dla w\u0119z\u0142\u00f3w podejmowania decyzji, ale zamiast szuka\u0107 konkretnego warunku do spe\u0142nienia (Is Ball Left Of Paddle), ocenia wyra\u017cenie warunkowe i zwraca true lub false odpowiednio. Odbywa si\u0119 to za pomoc\u0105 j\u0119zyka skryptowego Lua lub Angelscript. Dzi\u0119ki nim deweloper mo\u017ce przyjmowa\u0107 obiekty w swojej grze (ball i paddle) i tworzy\u0107 zmienne, kt\u00f3re b\u0119d\u0105 dost\u0119pne w skrypcie (ball.position). Ponadto, j\u0119zyk skryptowy jest prostszy ni\u017c C++. Nie wymaga pe\u0142nego etapu kompilacji, co czyni go idealnym do szybkiej korekty logiki gry i pozwala \u201enieprogramistom\u201d na samodzielne tworzenie wymaganych funkcji.<\/p>\n<p>W podanym przyk\u0142adzie j\u0119zyk skryptowy jest u\u017cywany tylko do oceny wyra\u017cenia warunkowego, ale mo\u017cna go r\u00f3wnie\u017c wykorzysta\u0107 do dzia\u0142a\u0144. Na przyk\u0142ad dane Move Paddle Right mog\u0105 sta\u0107 si\u0119 operatorem skryptowym (ball.position.x += 10). Tak, aby dzia\u0142anie by\u0142o tak\u017ce definiowane w skrypcie, bez potrzeby programowania Move Paddle Right.<\/p>\n<p>Mo\u017cna p\u00f3j\u015b\u0107 jeszcze dalej i ca\u0142kowicie napisa\u0107 drzewo decyzji w j\u0119zyku skryptowym. To b\u0119dzie kod w postaci twardo zaprogramowanych operator\u00f3w warunkowych, ale b\u0119d\u0105 one znajdowa\u0107 si\u0119 w zewn\u0119trznych plikach skryptu, to znaczy mog\u0105 by\u0107 zmienione bez rekompilacji ca\u0142ego programu. Cz\u0119sto mo\u017cna zmieni\u0107 plik skryptu w trakcie gry, aby szybko przetestowa\u0107 r\u00f3\u017cne reakcje AI.<\/p>\n<h3>Reagowanie na zdarzenia<\/h3>\n<p>\nPodane przyk\u0142ady idealnie pasuj\u0105 do Pong. Nieprzerwanie uruchamiaj\u0105 cykl Sense\/Think\/Act i dzia\u0142aj\u0105 na podstawie ostatniego stanu \u015bwiata. Jednak w bardziej skomplikowanych grach trzeba reagowa\u0107 na poszczeg\u00f3lne zdarzenia, a nie ocenia\u0107 wszystko naraz. W takim przypadku Pong jest ju\u017c nietrafionym przyk\u0142adem. Wybierzmy inny. <\/p>\n<p>Wyobra\u017a sobie strzelank\u0119, w kt\u00f3rej wrogowie s\u0105 nieruchomi, dop\u00f3ki nie zauwa\u017c\u0105 gracza, po czym dzia\u0142aj\u0105 w zale\u017cno\u015bci od swojej \u201especjalizacji\u201d: niekt\u00f3rzy zaczn\u0105 \u201erushowa\u0107\u201d, inni b\u0119d\u0105 atakowa\u0107 z daleka. To wci\u0105\u017c podstawowy system reaguj\u0105cy \u2014 \u201eje\u015bli gracz jest zauwa\u017cony, to zr\u00f3b co\u015b\u201d \u2014 ale mo\u017cna go logicznie podzieli\u0107 na zdarzenie Player Seen (gracz zauwa\u017cony) i reakcj\u0119 (wybierz odpowied\u017a i j\u0105 wykonaj).<\/p>\n<p>To wracamy do cyklu Sense\/Think\/Act. Mo\u017cemy stworzy\u0107 cz\u0119\u015b\u0107 Sense, kt\u00f3ra w ka\u017cdej klatce b\u0119dzie sprawdza\u0107, czy AI widzi gracza. Je\u015bli nie \u2014 nic si\u0119 nie dzieje, ale je\u015bli widzi, tworzy si\u0119 zdarzenie Player Seen. Kod b\u0119dzie mia\u0142 osobn\u0105 sekcj\u0119, w kt\u00f3rej b\u0119dzie napisane: \u201egdy nast\u0105pi zdarzenie Player Seen, zr\u00f3b \u201d, gdzie  to odpowied\u017a, kt\u00f3rej potrzebujesz do odwo\u0142ania do cz\u0119\u015bci Think i Act. W ten spos\u00f3b skonfigurujesz reakcje na zdarzenie Player Seen: dla \u201eszar\u017cuj\u0105cego\u201d bohatera \u2014 ChargeAndAttack, a dla snajpera \u2014 HideAndSnipe. Te powi\u0105zania mo\u017cna stworzy\u0107 w pliku danych do szybkiej edycji bez potrzeby ponownego kompilowania. Tu te\u017c mo\u017cna u\u017cy\u0107 j\u0119zyka skryptowego.<\/p>\n<h2>Podejmowanie z\u0142o\u017conych decyzji<\/h2>\n<p>\nCho\u0107 proste systemy reakcji s\u0105 bardzo skuteczne, jest wiele sytuacji, w kt\u00f3rych s\u0105 niewystarczaj\u0105ce. Czasami trzeba podejmowa\u0107 r\u00f3\u017cne decyzje w zale\u017cno\u015bci od tego, co agent robi w danym momencie, ale przedstawienie tego jako warunek jest trudne. Czasami istnieje zbyt wiele warunk\u00f3w, aby efektywnie przedstawi\u0107 je w drzewie decyzji lub skrypcie. Czasami trzeba z wyprzedzeniem oceni\u0107, jak zmieni si\u0119 sytuacja, zanim podejmie si\u0119 decyzj\u0119 o nast\u0119pnym kroku. Do rozwi\u0105zania tych problem\u00f3w potrzebne s\u0105 bardziej z\u0142o\u017cone podej\u015bcia.<\/p>\n<h3>Maszyna stan\u00f3w sko\u0144czonych<\/h3>\n<p>\nMaszyna stan\u00f3w sko\u0144czonych, czyli FSM (Finite State Machine) \u2014 to spos\u00f3b na powiedzenie, \u017ce nasz agent w danym momencie znajduje si\u0119 w jednym z kilku mo\u017cliwych stan\u00f3w i \u017ce mo\u017ce przechodzi\u0107 z jednego stanu do drugiego. Takich stan\u00f3w jest okre\u015blona ilo\u015b\u0107 \u2014 st\u0105d nazwa. Najlepszym przyk\u0142adem z \u017cycia jest sygnalizacja \u015bwietlna. W r\u00f3\u017cnych miejscach r\u00f3\u017cne sekwencje \u015bwiate\u0142, ale zasada jest ta sama \u2014 ka\u017cdy stan reprezentuje co\u015b (st\u00f3j, id\u017a itd.). Sygnalizator \u015bwietlny znajduje si\u0119 tylko w jednym stanie w danym momencie i przechodzi z jednego do drugiego na podstawie prostych zasad.<\/p>\n<p>W przypadku NPC w grach mamy podobn\u0105 histori\u0119. Na przyk\u0142ad we\u017amy stra\u017cnika z takimi stanami:<\/p>\n<ul>\n<li>Patroluj\u0105cy (Patrolling).<\/li>\n<li>Atakuj\u0105cy (Attacking).<\/li>\n<li>Uciekaj\u0105cy (Fleeing).<\/li>\n<\/ul>\n<p>\nI takimi warunkami do zmiany jego stanu:<\/p>\n<ul>\n<li>Je\u015bli stra\u017cnik widzi przeciwnika, atakuje.<\/li>\n<li>Je\u015bli stra\u017cnik atakuje, ale ju\u017c nie widzi przeciwnika, wraca do patrolowania.<\/li>\n<li>Je\u015bli stra\u017cnik atakuje, ale jest powa\u017cnie ranny, ucieka.<\/li>\n<\/ul>\n<p>\nMo\u017cesz r\u00f3wnie\u017c napisa\u0107 operatory if z zmienn\u0105 stanu stra\u017cnika oraz r\u00f3\u017cnymi kontrolami: czy wr\u00f3g jest blisko, jaki poziom zdrowia ma NPC itp. Dodajmy jeszcze kilka stan\u00f3w:<\/p>\n<ul>\n<li>Bezczynno\u015b\u0107 (Idling) \u2014 mi\u0119dzy patrolami.<\/li>\n<li>Poszukiwanie (Searching) \u2014 gdy zauwa\u017cony wr\u00f3g ukry\u0142 si\u0119.<\/li>\n<li>Prosz\u0105c o pomoc (Finding Help) \u2014 gdy wr\u00f3g zosta\u0142 zauwa\u017cony, ale jest zbyt silny, aby walczy\u0107 z nim samodzielnie.<\/li>\n<\/ul>\n<p>\nWyb\u00f3r dla ka\u017cdego z nich jest ograniczony \u2014 na przyk\u0142ad stra\u017cnik nie p\u00f3jdzie szuka\u0107 ukrywaj\u0105cego si\u0119 wroga, je\u015bli ma niskie zdrowie.<\/p>\n<p>Ostatecznie ogromna lista &bdquo;je\u015bli &lt;x \u0438 y, \u043d\u043e \u043d\u0435 z&gt;, to &lt;p&gt;&bdquo; mo\u017ce sta\u0107 si\u0119 zbyt niepor\u0119czna, dlatego nale\u017cy sformalizowa\u0107 metod\u0119, kt&oacute;ra pozwoli nam mie\u0107 na uwadze stany i przej\u015bcia mi\u0119dzy nimi. Aby to zrobi\u0107, we\u017amiemy pod uwag\u0119 wszystkie stany i pod ka\u017cdym stanem zapiszemy na li\u015bcie wszystkie przej\u015bcia do innych stan&oacute;w, wraz z wymaganymi dla nich warunkami.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/ba4c401aa20de3d22d2478cba5a4b1ec.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo jest tabela przej\u015b\u0107 stan\u00f3w \u2014 z\u0142o\u017cony spos\u00f3b przedstawienia FSM. Narysujmy diagram i uzyskamy pe\u0142ny przegl\u0105d tego, jak zmienia si\u0119 zachowanie NPC.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/b4182359983cf573872dacc575af13dc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDiagram odzwierciedla sedno podejmowania decyzji przez tego agenta w oparciu o aktualn\u0105 sytuacj\u0119. Ka\u017cda strza\u0142ka pokazuje przej\u015bcie mi\u0119dzy stanami, je\u015bli warunek obok niej jest prawdziwy.<\/p>\n<p>Podczas ka\u017cdej aktualizacji sprawdzamy aktualny stan agenta, przegl\u0105damy list\u0119 przej\u015b\u0107, a je\u015bli warunki przej\u015bcia s\u0105 spe\u0142nione, przejmuje on nowy stan. Na przyk\u0142ad, w ka\u017cdej klatce sprawdzamy, czy 10-sekundowy timer min\u0105\u0142, a je\u015bli tak, stra\u017cnik przechodzi ze stanu Bezczynno\u015bci do Patrolowania. W ten sam spos\u00f3b stan Atakuj\u0105cy sprawdza zdrowie agenta \u2014 je\u015bli jest niskie, przechodzi do stanu Uciekaj\u0105cego.<\/p>\n<p>To jest przetwarzanie przej\u015b\u0107 mi\u0119dzy stanami, ale co z zachowaniem zwi\u0105zanym z samymi stanami? Je\u015bli chodzi o implementacj\u0119 faktycznego zachowania dla konkretnego stanu, zazwyczaj istniej\u0105 dwa typy \u201ehak\u00f3w\u201d, kt\u00f3re przypisujemy dzia\u0142aniom do FSM:<\/p>\n<ul>\n<li>Dzia\u0142ania, kt\u00f3re okresowo wykonujemy dla aktualnego stanu.<\/li>\n<li>Dzia\u0142ania, kt\u00f3re podejmujemy przy przej\u015bciu z jednego stanu do innego.<\/li>\n<\/ul>\n<p>\nPrzyk\u0142ady dla pierwszego typu. Stan Patrolowania co klatk\u0119 przesuwa agenta po trasie patrolu. Stan Atakuj\u0105cy co klatk\u0119 pr\u00f3buje rozpocz\u0105\u0107 atak lub przej\u015b\u0107 do stanu, gdy to mo\u017cliwe.<\/p>\n<p>Dla drugiego typu rozwa\u017cmy przej\u015bcie \u201eje\u015bli wr\u00f3g jest widoczny i jest zbyt silny, to przejd\u017a do stanu Znalezienie Pomocy. Agent musi wybra\u0107, gdzie p\u00f3j\u015b\u0107 po pomoc, a nast\u0119pnie zapisa\u0107 t\u0119 informacj\u0119, aby stan Znalezienie Pomocy wiedzia\u0142, gdzie si\u0119 uda\u0107. Gdy pomoc zostanie znaleziona, agent wraca do stanu Atakowania. W tym momencie b\u0119dzie chcia\u0142 powiadomi\u0107 sojusznika o zagro\u017ceniu, wi\u0119c mo\u017ce nast\u0105pi\u0107 akcja PowiadomienieSojusznikaOzagro\u017ceniu.<\/p>\n<p>I zn\u00f3w mo\u017cemy spojrze\u0107 na ten system przez pryzmat cyklu Sense\/Think\/Act. Sense urzeczywistnia si\u0119 w danych wykorzystywanych przez logik\u0119 przej\u015bcia. Think - to przej\u015bcia dost\u0119pne w ka\u017cdym stanie. A Act polega na dzia\u0142aniach podejmowanych okresowo w ramach stanu lub podczas przej\u015b\u0107 mi\u0119dzy stanami.<\/p>\n<p>Czasami ci\u0105g\u0142e sprawdzanie warunk\u00f3w przej\u015bcia mo\u017ce by\u0107 kosztowne. Na przyk\u0142ad, je\u015bli ka\u017cdy agent mia\u0142by wykonywa\u0107 z\u0142o\u017cone obliczenia w ka\u017cdej klatce, aby okre\u015bli\u0107, czy widzi wrog\u00f3w i czy mo\u017ce przej\u015b\u0107 z stanu Patrolowania do Atakowania \u2013 to zajmie zbyt du\u017co czasu procesora. <\/p>\n<p>Wa\u017cne zmiany w stanie \u015bwiata mo\u017cna traktowa\u0107 jako zdarzenia, kt\u00f3re b\u0119d\u0105 przetwarzane, gdy si\u0119 pojawi\u0105. Zamiast tego, aby FSM sprawdza\u0142 warunek przej\u015bcia \u201eczy m\u00f3j agent widzi gracza?\u201d w ka\u017cdej klatce, mo\u017cna skonfigurowa\u0107 oddzielny system, aby przeprowadza\u0107 kontrole rzadziej (na przyk\u0142ad 5 razy na sekund\u0119). A wynikiem by\u0142oby Gracz Widoczny, gdy kontrola przechodzi. <\/p>\n<p>To jest przekazywane do FSM, kt\u00f3ry teraz musi przej\u015b\u0107 do warunku wydarzenia Otrzymano Gracz Widoczny i odpowiednio zareagowa\u0107. Ostateczne zachowanie pozostaje takie samo, z wyj\u0105tkiem prawie niedostrzegalnego op\u00f3\u017anienia w odpowiedzi. Dzi\u0119ki temu wydajno\u015b\u0107 zosta\u0142a poprawiona w wyniku od\u0142\u0105czenia cz\u0119\u015bci Sense od g\u0142\u00f3wnej cz\u0119\u015bci programu.<\/p>\n<h3>Hierarchiczna maszyna stan\u00f3w sko\u0144czonych<\/h3>\n<p>\nJednak praca z du\u017cymi FSM nie zawsze jest wygodna. Je\u015bli zechcemy rozwin\u0105\u0107 stan ataku, zast\u0119puj\u0105c go oddzielnymi MeleeAttacking (atak w zwarciu) i RangedAttacking (atak z dystansu), b\u0119dziemy musieli zmieni\u0107 przej\u015bcia ze wszystkich innych stan\u00f3w prowadz\u0105cych do stanu Atakowania (zar\u00f3wno bie\u017c\u0105cych, jak i przysz\u0142ych).<\/p>\n<p>Z pewno\u015bci\u0105 zauwa\u017cyli\u015bcie, \u017ce w naszym przyk\u0142adzie jest wiele powtarzaj\u0105cych si\u0119 przej\u015b\u0107. Wi\u0119kszo\u015b\u0107 przej\u015b\u0107 w stanie Idling jest identyczna z przej\u015bciami w stanie Patrolling. Dobrze by\u0142oby unikn\u0105\u0107 powt\u00f3rze\u0144, szczeg\u00f3lnie je\u015bli dodamy wi\u0119cej podobnych stan\u00f3w. Ma sens, aby zgrupowa\u0107 Idling i Patrolling pod wsp\u00f3ln\u0105 etykiet\u0105 \u201eniena\u017ceniowe\u201d, gdzie jest tylko jeden wsp\u00f3lny zbi\u00f3r przej\u015b\u0107 do stan\u00f3w bojowych. Je\u015bli przedstawimy t\u0119 etykiet\u0119 jako stan, to Idling i Patrolling stan\u0105 si\u0119 podstanami. Przyk\u0142ad u\u017cycia osobnej tabeli przej\u015b\u0107 dla nowego niena\u017ceniowego podstanu:<\/p>\n<p><i>G\u0142\u00f3wne stany:<\/i><br \/>\n<img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/d86dd918acbe81b9bf22c2fb34aecee3.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<i>Stan poza walk\u0105:<\/i><br \/>\n<img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/9d5bc2053010a32c5f68d7f0192c04ed.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI w formie schematu:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/0ccf95ecafa9ce2a6ea5b5b9833ddc4f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo ten sam system, ale z nowym niena\u017ceniowym stanem, kt\u00f3re obejmuje Idling i Patrolling. Z ka\u017cdym stanem, kt\u00f3ry zawiera FSM z podstanami (a te podstany z kolei zawieraj\u0105 w\u0142asne FSM \u2014 i tak dalej, ile potrzebujesz), otrzymujemy Hierarchical Finite State Machine lub HFSM (hierarchiczna maszyna stan\u00f3w sko\u0144czonych). Grupuj\u0105c niena\u017ceniowy stan, wyeliminowali\u015bmy mn\u00f3stwo zb\u0119dnych przej\u015b\u0107. To samo mo\u017cemy zrobi\u0107 dla wszelkich nowych stan\u00f3w z wsp\u00f3lnymi przej\u015bciami. Na przyk\u0142ad, je\u015bli w przysz\u0142o\u015bci rozszerzymy stan Attacking na stany MeleeAttacking i MissileAttacking, b\u0119d\u0105 one podstanami, przechodz\u0105cymi mi\u0119dzy sob\u0105 w zale\u017cno\u015bci od odleg\u0142o\u015bci do wroga i dost\u0119pno\u015bci amunicji. W rezultacie skomplikowane modele zachowania i podmodele zachowania mo\u017cna przedstawi\u0107 przy minimalnej liczbie powtarzaj\u0105cych si\u0119 przej\u015b\u0107.<\/p>\n<h3>Drzewo zachowa\u0144<\/h3>\n<p>\nZ HFSM mo\u017cna tworzy\u0107 skomplikowane kombinacje zachowa\u0144 w prosty spos\u00f3b. Niemniej jednak, jest ma\u0142a trudno\u015b\u0107, \u017ce podejmowanie decyzji w postaci zasad przej\u015bcia jest \u015bci\u015ble zwi\u0105zane z aktualnym stanem. I w wielu grach jest to w\u0142a\u015bnie to, czego potrzeba. A staranne wykorzystanie hierarchii stan\u00f3w mo\u017ce zmniejszy\u0107 liczb\u0119 powt\u00f3rze\u0144 podczas przej\u015bcia. Ale czasem potrzebne s\u0105 zasady, kt\u00f3re dzia\u0142aj\u0105 niezale\u017cnie od tego, w jakim stanie jeste\u015b lub kt\u00f3re maj\u0105 zastosowanie prawie w ka\u017cdym stanie. Na przyk\u0142ad, je\u015bli zdrowie agenta spad\u0142o do 25%, b\u0119dziesz chcia\u0142, aby ucieka\u0142, niezale\u017cnie od tego, czy by\u0142 w walce, bezczynny czy rozmawia\u0142 \u2014 musisz doda\u0107 ten warunek do ka\u017cdego stanu. A je\u015bli tw\u00f3j projektant p\u00f3\u017aniej zechce zmieni\u0107 pr\u00f3g niskiego zdrowia z 25% na 10%, zn\u00f3w b\u0119dziesz musia\u0142 si\u0119 tym zaj\u0105\u0107.<\/p>\n<p>W idealnym przypadku do tej sytuacji potrzebny jest system, w kt\u00f3rym decyzje o tym, w jakim stanie powinien by\u0107 system, s\u0105 poza samymi stanami, co pozwala na wprowadzanie zmian w jednym miejscu i nie dotykanie warunk\u00f3w przej\u015bcia. Tu pojawiaj\u0105 si\u0119 drzewa zachowa\u0144.<\/p>\n<p>Istnieje kilka sposob\u00f3w ich realizacji, ale istota jest dla wszystkich mniej wi\u0119cej taka sama i przypomina drzewo decyzji: algorytm zaczyna si\u0119 od w\u0119z\u0142a 'korzeniowego', a w drzewie znajduj\u0105 si\u0119 w\u0119z\u0142y, kt\u00f3re reprezentuj\u0105 albo decyzje, albo dzia\u0142ania. Istniej\u0105 jednak pewne kluczowe r\u00f3\u017cnice:<\/p>\n<ul>\n<li>Teraz w\u0119z\u0142y zwracaj\u0105 jedn\u0105 z trzech warto\u015bci: Succeeded (je\u015bli praca zosta\u0142a zako\u0144czona), Failed (je\u015bli nie mo\u017cna uruchomi\u0107) lub Running (je\u017celi nadal dzia\u0142a i nie ma ostatecznego wyniku).<\/li>\n<li>Nie ma ju\u017c w\u0119z\u0142\u00f3w decyzyjnych do wyboru mi\u0119dzy dwiema alternatywami. Zamiast nich s\u0105 w\u0119z\u0142y Decorator, kt\u00f3re maj\u0105 jeden w\u0119ze\u0142 potomny. Je\u015bli zako\u0144cz\u0105 si\u0119 powodzeniem, wykonuj\u0105 sw\u00f3j jedyny w\u0119ze\u0142 potomny.<\/li>\n<li>W\u0119z\u0142y wykonuj\u0105ce dzia\u0142ania zwracaj\u0105 warto\u015b\u0107 Running, aby reprezentowa\u0107 wykonywane dzia\u0142ania.<\/li>\n<\/ul>\n<p>\nTen niewielki zestaw w\u0119z\u0142\u00f3w mo\u017cna po\u0142\u0105czy\u0107 w celu stworzenia du\u017cej liczby z\u0142o\u017conych modeli zachowa\u0144. Przedstawmy HFSM stra\u017cnika z poprzedniego przyk\u0142adu w formie drzewa zachowa\u0144:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/5eaa5c725e4ada8285f16f95bb206d53.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nZ t\u0105 struktur\u0105 nie powinno by\u0107 bezpo\u015bredniego przej\u015bcia od stan\u00f3w Idling\/Patrolling do stanu Attacking lub jakiegokolwiek innego. Je\u015bli wrogowie s\u0105 widoczni, a zdrowie postaci jest niskie, wykonanie zatrzymuje si\u0119 na w\u0119\u017ale Fleeing, niezale\u017cnie od tego, kt\u00f3ry w\u0119ze\u0142 by\u0142 wcze\u015bniej wykonywany - Patrolling, Idling, Attacking lub jakikolwiek inny.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/e1c1dcc2055174aa7cfa846364b1709a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDrzewa zachowa\u0144 s\u0105 skomplikowane - istnieje wiele sposob\u00f3w ich konstruowania, a znalezienie w\u0142a\u015bciwej kombinacji dekorator\u00f3w i w\u0119z\u0142\u00f3w z\u0142o\u017conych mo\u017ce by\u0107 problematyczne. S\u0105 te\u017c pytania o to, jak cz\u0119sto sprawdza\u0107 drzewo - czy chcemy przechodzi\u0107 przez nie za ka\u017cdym razem, czy tylko wtedy, gdy jeden z warunk\u00f3w si\u0119 zmieni? Jak przechowywa\u0107 stan odnosz\u0105cy si\u0119 do w\u0119z\u0142\u00f3w - jak dowiedzie\u0107 si\u0119, kiedy byli\u015bmy w stanie Idling przez 10 sekund lub jak dowiedzie\u0107 si\u0119, kt\u00f3re w\u0119z\u0142y by\u0142y wykonywane ostatnio, aby prawid\u0142owo obs\u0142ugiwa\u0107 sekwencj\u0119?<\/p>\n<p>Dlatego istnieje wiele r\u00f3\u017cnych implementacji. Na przyk\u0142ad w niekt\u00f3rych systemach w\u0119z\u0142y dekoratora zast\u0119puj\u0105 wbudowane dekoratory. Powtarzaj\u0105 one ocen\u0119 drzewa w momencie zmiany warunk\u00f3w dekoratora, pomagaj\u0105 \u0142\u0105czy\u0107 w\u0119z\u0142y i zapewniaj\u0105 okresowe aktualizacje.<\/p>\n<h3>System oparty na u\u017cyteczno\u015bci<\/h3>\n<p>\nW niekt\u00f3rych grach wyst\u0119puje wiele r\u00f3\u017cnych mechanik. Po\u017c\u0105dane jest, aby wszystkie skorzysta\u0142y z prostych i og\u00f3lnych zasad przej\u015b\u0107, ale niekoniecznie w formie pe\u0142nego drzewa zachowa\u0144. Zamiast mie\u0107 wyra\u017any zestaw wybor\u00f3w lub drzewo mo\u017cliwych dzia\u0142a\u0144, \u0142atwiej jest zbada\u0107 wszystkie dzia\u0142ania i wybra\u0107 najbardziej odpowiednie w danym momencie.<\/p>\n<p>System oparty na u\u017cyteczno\u015bci pomo\u017ce w tym. To system, w kt\u00f3rym agent ma wiele dzia\u0142a\u0144 i sam decyduje, kt\u00f3re wykona\u0107, opieraj\u0105c si\u0119 na wzgl\u0119dnej u\u017cyteczno\u015bci ka\u017cdego z nich. U\u017cyteczno\u015b\u0107 to dowolna miara tego, jak wa\u017cne lub po\u017c\u0105dane jest wykonanie tego dzia\u0142ania przez agenta. <\/p>\n<p>Obliczon\u0105 u\u017cyteczno\u015b\u0107 dzia\u0142ania na podstawie aktualnego stanu i \u015brodowiska agent mo\u017ce sprawdzi\u0107 i wybra\u0107 najbardziej odpowiedni inny stan w dowolnym momencie. Jest to podobne do FSM, z wyj\u0105tkiem tego, \u017ce przej\u015bcia s\u0105 okre\u015blane przez ocen\u0119 dla ka\u017cdego potencjalnego stanu, w tym aktualnego. Nale\u017cy zauwa\u017cy\u0107, \u017ce wybieramy najbardziej u\u017cyteczne dzia\u0142anie do przej\u015bcia (lub pozostajemy w tym samym stanie, je\u015bli ju\u017c je wykonali\u015bmy). Dla wi\u0119kszej r\u00f3\u017cnorodno\u015bci mo\u017ce to by\u0107 wa\u017cony, ale przypadkowy wyb\u00f3r z ma\u0142ej listy.<\/p>\n<p>System przydziela dowolny zakres warto\u015bci u\u017cyteczno\u015bci \u2014 na przyk\u0142ad od 0 (zupe\u0142nie niepo\u017c\u0105dane) do 100 (ca\u0142kowicie po\u017c\u0105dane). Ka\u017cde dzia\u0142anie ma szereg parametr\u00f3w wp\u0142ywaj\u0105cych na obliczenie tej warto\u015bci. Wracaj\u0105c do naszego przyk\u0142adu z stra\u017cnikiem:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/085fb2c197bde93d78455d18e63c9c25.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nPrzej\u015bcia mi\u0119dzy dzia\u0142aniami s\u0105 niejednoznaczne \u2014 dowolny stan mo\u017ce nast\u0119powa\u0107 po ka\u017cdym innym. Priorytety dzia\u0142a\u0144 s\u0105 ustalane na podstawie zwracanych warto\u015bci u\u017cyteczno\u015bci. Je\u015bli wr\u00f3g jest widoczny, a ten wr\u00f3g jest silny, a zdrowie postaci jest niskie, zar\u00f3wno Fleeing, jak i FindingHelp zwr\u00f3c\u0105 wysokie warto\u015bci r\u00f3\u017cne od zera. Jednak FindingHelp zawsze b\u0119dzie wy\u017csze. Podobnie, dzia\u0142ania niewalcz\u0105ce nigdy nie zwracaj\u0105 wi\u0119cej ni\u017c 50, dlatego zawsze b\u0119d\u0105 ni\u017csze od dzia\u0142a\u0144 walcz\u0105cych. Nale\u017cy wzi\u0105\u0107 to pod uwag\u0119 przy tworzeniu dzia\u0142a\u0144 i obliczaniu ich u\u017cyteczno\u015bci.<\/p>\n<p>W naszym przyk\u0142adzie dzia\u0142ania zwracaj\u0105 albo sta\u0142\u0105, niezmienn\u0105 warto\u015b\u0107, albo jedn\u0105 z dw\u00f3ch sta\u0142ych warto\u015bci. Bardziej realistyczny system zak\u0142ada zwrot oceny w nieprzerwanym zakresie warto\u015bci. Na przyk\u0142ad dzia\u0142anie Fleeing zwraca wy\u017csze warto\u015bci u\u017cyteczno\u015bci, gdy zdrowie agenta jest niskie, natomiast dzia\u0142anie Attacking zwraca ni\u017csze warto\u015bci, gdy wr\u00f3g jest zbyt silny. Z tego powodu dzia\u0142anie Fleeing ma priorytet nad Attacking w ka\u017cdej sytuacji, gdy agent czuje, \u017ce nie ma wystarczaj\u0105co du\u017co zdrowia, aby pokona\u0107 przeciwnika. To pozwala na zmian\u0119 priorytet\u00f3w dzia\u0142a\u0144 na podstawie r\u00f3\u017cnych kryteri\u00f3w, co czyni takie podej\u015bcie bardziej elastycznym i zmiennym ni\u017c drzewo behawioralne czy FSM.<\/p>\n<p>Ka\u017cde dzia\u0142anie ma wiele warunk\u00f3w do obliczenia programu. Mo\u017cna je zapisa\u0107 w j\u0119zyku skryptowym lub w postaci serii formu\u0142 matematycznych. W The Sims, kt\u00f3ry modeluje codzienny rozk\u0142ad dnia postaci, dodawany jest dodatkowy poziom oblicze\u0144 \u2014 agent otrzymuje szereg \u201emotywacji\u201d, kt\u00f3re wp\u0142ywaj\u0105 na oceny u\u017cyteczno\u015bci. Je\u015bli posta\u0107 jest g\u0142odna, to z czasem b\u0119dzie g\u0142odniejsza, a wynik u\u017cyteczno\u015bci dzia\u0142ania EatFood b\u0119dzie r\u00f3s\u0142, a\u017c posta\u0107 je, zmniejszaj\u0105c poziom g\u0142odu i przywracaj\u0105c warto\u015b\u0107 EatFood do zera. <\/p>\n<p>Idea wyboru dzia\u0142a\u0144 na podstawie systemu ocen jest do\u015b\u0107 prosta, dlatego systemy oparte na u\u017cyteczno\u015bci mo\u017cna stosowa\u0107 jako cz\u0119\u015b\u0107 proces\u00f3w podejmowania decyzji AI, a nie jako ich ca\u0142kowit\u0105 alternatyw\u0119. Drzewo decyzyjne mo\u017ce za\u017c\u0105da\u0107 oceny u\u017cyteczno\u015bci dw\u00f3ch w\u0119z\u0142\u00f3w podrz\u0119dnych i wybra\u0107 wy\u017csz\u0105. Podobnie drzewo behawioralne mo\u017ce mie\u0107 z\u0142o\u017cony w\u0119ze\u0142 Utility do oceny u\u017cyteczno\u015bci dzia\u0142a\u0144 w celu podj\u0119cia decyzji, kt\u00f3ry element podrz\u0119dny zrealizowa\u0107.<\/p>\n<h2>Ruch i nawigacja<\/h2>\n<p>\nW poprzednich przyk\u0142adach mieli\u015bmy platform\u0119, kt\u00f3r\u0105 poruszali\u015bmy w lewo lub w prawo, oraz stra\u017cnika, kt\u00f3ry patrolowa\u0142 lub atakowa\u0142. Jak jednak dok\u0142adnie przetwarzamy ruch agenta w okre\u015blonym czasie? Jak ustalamy pr\u0119dko\u015b\u0107, jak omijamy przeszkody i jak planujemy tras\u0119, je\u015bli dotarcie do celu jest trudniejsze ni\u017c po prostu poruszanie si\u0119 w linii prostej? Przyjrzyjmy si\u0119 temu.<\/p>\n<h3>Zarz\u0105dzanie<\/h3>\n<p>\nNa pocz\u0105tkowym etapie mo\u017cemy za\u0142o\u017cy\u0107, \u017ce ka\u017cdy agent ma warto\u015b\u0107 pr\u0119dko\u015bci, kt\u00f3ra obejmuje, jak szybko si\u0119 porusza i w jakim kierunku. Mo\u017ce by\u0107 mierzona w metrach na sekund\u0119, kilometrach na godzin\u0119, pikselach na sekund\u0119 itd. Przypominaj\u0105c cykl Sense\/Tink\/Act, mo\u017cemy wyobrazi\u0107 sobie, \u017ce cz\u0119\u015b\u0107 Think wybiera pr\u0119dko\u015b\u0107, a cz\u0119\u015b\u0107 Act stosuje t\u0119 pr\u0119dko\u015b\u0107 do agenta. Zwykle w grach istnieje system fizyki, kt\u00f3ry wykonuje to zadanie za ciebie, badaj\u0105c warto\u015b\u0107 pr\u0119dko\u015bci ka\u017cdego obiektu i reguluj\u0105c j\u0105. Dlatego mo\u017cna pozostawi\u0107 AI z jednym zadaniem \u2014 zdecydowa\u0107, jak\u0105 pr\u0119dko\u015b\u0107 powinien mie\u0107 agent. Je\u015bli wiadomo, gdzie agent ma by\u0107, nale\u017cy przenie\u015b\u0107 go w odpowiednim kierunku z ustalon\u0105 pr\u0119dko\u015bci\u0105. Bardzo trywialne r\u00f3wnanie:<\/p>\n<p><i>desired_travel = destination_position \u2013 agent_position<\/i><\/p>\n<p>Wyobra\u017a sobie \u015bwiat 2D. Agent znajduje si\u0119 w punkcie (-2,-2), a punkt docelowy znajduje si\u0119 gdzie\u015b na p\u00f3\u0142nocnym-wschodzie w punkcie (30, 20), a wymagany ruch, aby agent m\u00f3g\u0142 si\u0119 tam znale\u017a\u0107, wynosi (32, 22). Za\u0142\u00f3\u017cmy, \u017ce te pozycje s\u0105 mierzone w metrach \u2014 je\u015bli przyjmiemy pr\u0119dko\u015b\u0107 agenta na poziomie 5 metr\u00f3w na sekund\u0119, to b\u0119dziemy skalowa\u0107 nasz wektor przemieszczenia i uzyskamy pr\u0119dko\u015b\u0107 oko\u0142o (4.12, 2.83). Przy takich parametrach agent dotar\u0142by do miejsca przeznaczenia prawie po 8 sekundach.<\/p>\n<p>Warto\u015bci mo\u017cna przeliczy\u0107 w dowolnym momencie. Je\u015bli agent by\u0142 w po\u0142owie drogi do celu, przemieszczenie wynosi\u0142oby po\u0142ow\u0119 d\u0142ugo\u015bci, ale poniewa\u017c maksymalna pr\u0119dko\u015b\u0107 agenta wynosi 5 m\/s (to ustalili\u015bmy wcze\u015bniej), pr\u0119dko\u015b\u0107 b\u0119dzie taka sama. Dzia\u0142a to r\u00f3wnie\u017c dla ruchomych cel\u00f3w, pozwalaj\u0105c agentowi na wprowadzenie drobnych zmian podczas ich poruszania si\u0119.<\/p>\n<p>Ale chcemy wi\u0119kszej zmienno\u015bci \u2014 na przyk\u0142ad powoli zwi\u0119ksza\u0107 pr\u0119dko\u015b\u0107, aby symulowa\u0107 posta\u0107, kt\u00f3ra przechodzi z pozycji stoj\u0105cej do biegu. To samo mo\u017cna zrobi\u0107 na ko\u0144cu przed zatrzymaniem. Te funkcje s\u0105 znane jako zachowania steruj\u0105ce, z kt\u00f3rych ka\u017cde ma swoje specyficzne nazwy: Seek (szukanie), Flee (ucieczka), Arrival (przybycie) itd. Idea polega na tym, \u017ce si\u0142y przyspieszenia mog\u0105 by\u0107 stosowane do pr\u0119dko\u015bci agenta, na podstawie por\u00f3wnania pozycji agenta i jego aktualnej pr\u0119dko\u015bci z punktem docelowym, aby zastosowa\u0107 r\u00f3\u017cne sposoby poruszania si\u0119 w kierunku celu.<\/p>\n<p>Ka\u017cde zachowanie ma nieco inny cel. Seek i Arrival to sposoby na przemieszczenie agenta do punktu docelowego. Obstacle Avoidance (omijanie przeszk\u00f3d) i Separation (separacja) koryguj\u0105 ruch agenta, aby unika\u0107 przeszk\u00f3d na drodze do celu. Alignment (wsp\u00f3\u0142dzia\u0142anie) i Cohesion (sp\u00f3jno\u015b\u0107) utrzymuj\u0105 agent\u00f3w w ruchu razem. Dowolna liczba r\u00f3\u017cnych zachowa\u0144 steruj\u0105cych mo\u017ce by\u0107 sumowana, aby uzyska\u0107 jeden wektor \u015bcie\u017cki, uwzgl\u0119dniaj\u0105cy wszystkie czynniki. Agent u\u017cywa zachowa\u0144 Arrival, Separation i Obstacle Avoidance, aby trzyma\u0107 si\u0119 z dala od \u015bcian i innych agent\u00f3w. To podej\u015bcie dobrze dzia\u0142a w otwartych lokalizacjach bez zb\u0119dnych szczeg\u00f3\u0142\u00f3w. <\/p>\n<p>W trudniejszych warunkach, sumowanie r\u00f3\u017cnych zachowa\u0144 dzia\u0142a gorzej - na przyk\u0142ad, agent mo\u017ce utkn\u0105\u0107 w \u015bcianie z powodu konfliktu Arrival i Obstacle Avoidance. Dlatego nale\u017cy rozwa\u017cy\u0107 opcje, kt\u00f3re s\u0105 bardziej skomplikowane ni\u017c tylko sumowanie wszystkich warto\u015bci. Taki spos\u00f3b: zamiast sumowania wynik\u00f3w ka\u017cdego zachowania, mo\u017cna rozwa\u017cy\u0107 ruch w r\u00f3\u017cnych kierunkach i wybra\u0107 najlepsz\u0105 opcj\u0119. <\/p>\n<p>Jednak w skomplikowanym \u015brodowisku z zau\u0142kami i wyborem kierunku, w jak\u0105 stron\u0119 i\u015b\u0107, potrzebujemy czego\u015b jeszcze bardziej zaawansowanego.<\/p>\n<h3>Wyszukiwanie \u015bcie\u017cki<\/h3>\n<p>\nZachowania steruj\u0105ce doskonale nadaj\u0105 si\u0119 do prostego poruszania si\u0119 na otwartej przestrzeni (boisko pi\u0142karskie lub arena), gdzie dotarcie od A do B to bezpo\u015brednia droga z niewielkimi odchyleniami przy omijaniu przeszk\u00f3d. Dla skomplikowanych tras potrzebujemy pathfinding (wyszukiwania \u015bcie\u017cki), kt\u00f3ry jest sposobem na zg\u0142\u0119bianie \u015bwiata i podejmowanie decyzji dotycz\u0105cych trasy przez niego.<\/p>\n<p>Najprostszy spos\u00f3b to na\u0142o\u017cenie siatki na ka\u017cdy kwadrat obok agenta i ocena, w kt\u00f3rych z nich mo\u017cna si\u0119 porusza\u0107. Je\u015bli kt\u00f3rykolwiek z nich jest celem, to pod\u0105\u017caj za nim z ka\u017cdego kwadratu do poprzedniego, a\u017c dojdziesz do pocz\u0105tku. To jest trasa. W przeciwnym razie powtarzaj proces z najbli\u017cszymi innymi kwadratami, a\u017c znajdziesz miejsce docelowe lub sko\u0144cz\u0105 si\u0119 kwadraty (co oznacza, \u017ce nie ma mo\u017cliwej trasy). To, co formalnie znane jest jako przeszukiwanie wszerz (Breadth-First Search, BFS). Na ka\u017cdym kroku patrzy we wszystkich kierunkach (st\u0105d breadth, \"szeroko\u015b\u0107\"). Przestrze\u0144 przeszukiwania przypomina fal\u0119, kt\u00f3ra porusza si\u0119, a\u017c dotrze do miejsca, kt\u00f3re jest szukane \u2014 obszar przeszukiwania rozszerza si\u0119 z ka\u017cdym krokiem, a\u017c dotrze do punktu ko\u0144cowego, po czym mo\u017cna \u015bledzi\u0107 drog\u0119 do pocz\u0105tku.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/d367e62bc53033b05388538649853a41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW rezultacie otrzymasz list\u0119 kwadrat\u00f3w, wed\u0142ug kt\u00f3rych zostanie stworzona potrzebna trasa. To jest \u015bcie\u017cka (st\u0105d pathfinding) \u2014 lista miejsc, kt\u00f3re agent odwiedzi, pod\u0105\u017caj\u0105c do celu.<\/p>\n<p>Maj\u0105c na uwadze, \u017ce znamy po\u0142o\u017cenie ka\u017cdego kwadratu w \u015bwiecie, mo\u017cemy u\u017cy\u0107 zachowa\u0144 steruj\u0105cych, aby porusza\u0107 si\u0119 po \u015bcie\u017cce \u2014 od w\u0119z\u0142a 1 do w\u0119z\u0142a 2, nast\u0119pnie od w\u0119z\u0142a 2 do w\u0119z\u0142a 3 i tak dalej. Najprostsza opcja to skierowanie si\u0119 do \u015brodka nast\u0119pnego kwadratu, ale jeszcze lepszym pomys\u0142em jest zatrzymanie si\u0119 na \u015brodku kraw\u0119dzi mi\u0119dzy bie\u017c\u0105cym kwadratem a nast\u0119pnym. Dzi\u0119ki temu agent b\u0119dzie m\u00f3g\u0142 skraca\u0107 zakr\u0119ty na ostrych zakr\u0119tach.<\/p>\n<p>Algorytm BFS ma te\u017c swoje wady \u2014 bada tyle samo kwadrat\u00f3w w \"niew\u0142a\u015bciwym\" kierunku, ile w \"w\u0142a\u015bciwym\". Tutaj pojawia si\u0119 bardziej zaawansowany algorytm nazwany A* (A star). Dzia\u0142a on podobnie, ale zamiast \u015blepo bada\u0107 s\u0105siednie kwadraty (potem s\u0105siad\u00f3w s\u0105siad\u00f3w, potem s\u0105siad\u00f3w s\u0105siad\u00f3w s\u0105siad\u00f3w itd.), zbiera w\u0119z\u0142y na li\u015bcie i sortuje je tak, \u017ce nast\u0119pny badany w\u0119ze\u0142 jest zawsze tym, kt\u00f3ry poprowadzi do najkr\u00f3tszej trasy. W\u0119z\u0142y s\u0105 sortowane na podstawie heurystyki, kt\u00f3ra bierze pod uwag\u0119 dwie rzeczy \u2014 \"koszt\" hipotetycznej trasy do docelowego kwadratu (w tym wszelkie koszty przemieszczania si\u0119) oraz ocen\u0119, jak daleko ten kwadrat znajduje si\u0119 od miejsca docelowego (przesuwaj\u0105c przeszukiwanie w odpowiednim kierunku).<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/1cab4f53fa5af6b31d352c7bcf453d7e.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nW tym przyk\u0142adzie agent bada jeden kwadrat na raz, za ka\u017cdym razem wybieraj\u0105c najbli\u017cszy, kt\u00f3ry jest najbardziej obiecuj\u0105cy. Otrzymana \u015bcie\u017cka jest taka sama jak w przypadku BFS, ale w procesie rozwa\u017cono mniej kwadrat\u00f3w \u2014 co ma ogromne znaczenie dla wydajno\u015bci gry.<\/p>\n<h3>Ruch bez siatki<\/h3>\n<p>\nJednak wi\u0119kszo\u015b\u0107 gier nie jest osadzona w siatce i cz\u0119sto nie mo\u017cna jej stworzy\u0107 bez utraty realizmu. Wymagana jest r\u00f3wnowaga. Jakie powinny by\u0107 rozmiary kwadrat\u00f3w? Zbyt du\u017ce \u2014 nie b\u0119d\u0105 w stanie odpowiednio przedstawi\u0107 ma\u0142ych korytarzy czy zakr\u0119t\u00f3w, zbyt ma\u0142e \u2014 b\u0119dzie zbyt wiele kwadrat\u00f3w do przeszukania, co ostatecznie zajmie mn\u00f3stwo czasu.<\/p>\n<p>Pierwsze, co nale\u017cy zrozumie\u0107 \u2014 siatka daje nam graf powi\u0105zanych w\u0119z\u0142\u00f3w. Algorytmy A* i BFS faktycznie dzia\u0142aj\u0105 na grafach i w og\u00f3le nie interesuje je nasza siatka. Mogliby\u015bmy umie\u015bci\u0107 w\u0119z\u0142y w dowolnych miejscach \u015bwiata gry: przy istnieniu po\u0142\u0105czenia mi\u0119dzy dowolnymi dwoma po\u0142\u0105czonymi w\u0119z\u0142ami, a tak\u017ce mi\u0119dzy punktem pocz\u0105tkowym i ko\u0144cowym oraz przynajmniej jednym z w\u0119z\u0142\u00f3w \u2014 algorytm b\u0119dzie dzia\u0142a\u0142 tak samo dobrze jak wcze\u015bniej. Cz\u0119sto nazywa si\u0119 to systemem punkt\u00f3w kontrolnych (waypoint), poniewa\u017c ka\u017cdy w\u0119ze\u0142 reprezentuje znacz\u0105c\u0105 pozycj\u0119 w \u015bwiecie, kt\u00f3ra mo\u017ce by\u0107 cz\u0119\u015bci\u0105 dowolnej liczby hipotetycznych \u015bcie\u017cek.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/d87e9d4bb2a2fc713d32abc158506eaa.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Przyk\u0142ad 1: w\u0119ze\u0142 w ka\u017cdym kwadracie. Wyszukiwanie zaczyna si\u0119 od w\u0119z\u0142a, w kt\u00f3rym znajduje si\u0119 agent, i ko\u0144czy w w\u0119\u017ale \u017c\u0105danego kwadratu.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/b535a5db805efdc427d7c5724b866982.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Przyk\u0142ad 2: mniejszy zestaw w\u0119z\u0142\u00f3w (punkt\u00f3w kontrolnych). Wyszukiwanie zaczyna si\u0119 w kwadracie z agentem, przechodzi przez odpowiedni\u0105 liczb\u0119 w\u0119z\u0142\u00f3w, a nast\u0119pnie kontynuuje do miejsca docelowego.<\/i><\/p>\n<p>To do\u015b\u0107 elastyczny i pot\u0119\u017cny system. Ale wymagana jest ostro\u017cno\u015b\u0107 w decyzjach, gdzie i jak umie\u015bci\u0107 waypoint, w przeciwnym razie agenci mog\u0105 po prostu nie zobaczy\u0107 najbli\u017cszego punktu i nie b\u0119d\u0105 mogli rozpocz\u0105\u0107 drogi. By\u0142oby \u0142atwiej, gdyby\u015bmy mogli automatycznie ustawi\u0107 punkty kontrolne w oparciu o geometri\u0119 \u015bwiata.<\/p>\n<p>Tutaj wchodzi do gry siatka nawigacyjna lub navmesh. Jest to zazwyczaj 2D-mapa tr\u00f3jk\u0105t\u00f3w, kt\u00f3ra nak\u0142ada si\u0119 na geometri\u0119 \u015bwiata \u2014 wsz\u0119dzie tam, gdzie agent ma prawo chodzi\u0107. Ka\u017cdy z tr\u00f3jk\u0105t\u00f3w w siatce staje si\u0119 w\u0119z\u0142em w grafie i ma do trzech s\u0105siednich tr\u00f3jk\u0105t\u00f3w, kt\u00f3re staj\u0105 si\u0119 s\u0105siednimi w\u0119z\u0142ami w grafie. <\/p>\n<p>Ten obraz jest przyk\u0142adem z silnika Unity \u2014 przeanalizowa\u0142 on geometri\u0119 w \u015bwiecie i stworzy\u0142 navmesh (na zrzucie ekranu w jasnoniebieskim kolorze). Ka\u017cdy poligon w navmesh to obszar, na kt\u00f3rym agent mo\u017ce sta\u0107 lub porusza\u0107 si\u0119 z jednego poligonu do drugiego. W tym przyk\u0142adzie poligony s\u0105 mniejsze ni\u017c pi\u0119tra, na kt\u00f3rych si\u0119 znajduj\u0105 \u2014 zrobiono to, aby uwzgl\u0119dni\u0107 rozmiary agenta, kt\u00f3re b\u0119d\u0105 wychodzi\u0142y poza jego nominalne po\u0142o\u017cenie.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/845705ba7b9a9d469203aedf7942da41.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMo\u017cemy szuka\u0107 trasy przez t\u0119 siatk\u0119, ponownie korzystaj\u0105c z algorytmu A*. Da nam to praktycznie idealn\u0105 tras\u0119 w \u015bwiecie, kt\u00f3ry uwzgl\u0119dnia ca\u0142\u0105 geometri\u0119 i nie wymaga dodatkowych w\u0119z\u0142\u00f3w ani tworzenia punkt\u00f3w kontrolnych.<\/p>\n<p>Zagadnienie pathfindingu jest zbyt obszerne, by zmie\u015bci\u0107 si\u0119 w jednym rozdziale artyku\u0142u. Je\u015bli chcesz zg\u0142\u0119bi\u0107 ten temat, pomo\u017ce w tym <noindex><a rel=\"nofollow\" href=\"https:\/\/www.redblobgames.com\/pathfinding\/a-star\/introduction.html\">strona Amita Patela<\/a><\/noindex>.<\/p>\n<h2>Planowanie<\/h2>\n<p>\nPrzekonali\u015bmy si\u0119, \u017ce czasami wystarczy nie tylko wybra\u0107 kierunek i i\u015b\u0107 \u2014 musimy wybra\u0107 tras\u0119 i wykona\u0107 kilka zwrot\u00f3w, aby dotrze\u0107 do celu. Mo\u017cemy uog\u00f3lni\u0107 t\u0119 my\u015bl: osi\u0105gni\u0119cie celu to nie tylko nast\u0119pny krok, ale ca\u0142a sekwencja, gdzie czasem trzeba zajrze\u0107 do przodu na kilka krok\u00f3w, aby dowiedzie\u0107 si\u0119, jaki powinien by\u0107 pierwszy. Nazywa si\u0119 to planowaniem. Pathfinding mo\u017cna traktowa\u0107 jako jedno z wielu uzupe\u0142nie\u0144 planowania. Z perspektywy naszego cyklu Sense\/Think\/Act, to jest to miejsce, gdzie cz\u0119\u015b\u0107 Think planuje kilka cz\u0119\u015bci Act na przysz\u0142o\u015b\u0107.<\/p>\n<p>Zanotujmy to na przyk\u0142adzie gry planszowej Magic: The Gathering. Zaczynamy maj\u0105c nast\u0119puj\u0105cy zestaw kart w r\u0119ku:<\/p>\n<ul>\n<li>Swamp \u2014 daje 1 czarn\u0105 man\u0119 (karta ziemi).<\/li>\n<li>Forest \u2014 daje 1 zielon\u0105 man\u0119 (karta ziemi).<\/li>\n<li>Fugitive Wizard \u2014 wymaga 1 niebieskiej many do przywo\u0142ania.<\/li>\n<li>Elvish Mystic \u2014 wymaga 1 zielonej many do przywo\u0142ania.<\/li>\n<\/ul>\n<p>\nIgnorujemy trzy pozosta\u0142e karty dla uproszczenia. Zgodnie z zasadami gracz mo\u017ce zagra\u0107 1 kart\u0119 ziemi w swojej turze, mo\u017ce 'tapn\u0105\u0107' t\u0119 kart\u0119, aby uzyska\u0107 man\u0119, a nast\u0119pnie u\u017cy\u0107 zakl\u0119\u0107 (w tym przywo\u0142ania stworzenia) zgodnie z ilo\u015bci\u0105 uzyskanej many. W tej sytuacji gracz-ludzki wie, \u017ce powinien zagra\u0107 Forest, 'tapn\u0105\u0107' 1 zielon\u0105 man\u0119, a nast\u0119pnie przywo\u0142a\u0107 Elvish Mystic. Ale jak ma to odgadn\u0105\u0107 sztuczna inteligencja gry?<\/p>\n<h3>Proste planowanie<\/h3>\n<p>\nTradycyjnego podej\u015bcia \u2014 pr\u00f3bowa\u0107 ka\u017cde dzia\u0142anie po kolei, a\u017c nie pozostan\u0105 odpowiednie. Patrz\u0105c na karty, AI widzi, \u017ce mo\u017ce zagra\u0107 Swamp. I gra go. Czy s\u0105 inne akcje w tej turze? Nie mo\u017ce zagra\u0107 ani Elvish Mystic, ani Fugitive Wizard, poniewa\u017c ich zagraniu potrzebna jest odpowiednio zielona i niebieska mana, a Swamp daje tylko czarn\u0105 man\u0119. I ju\u017c nie mo\u017ce zagra\u0107 Forest, bo ju\u017c zagra\u0142 Swamp. Tak wi\u0119c, AI zagra\u0142 zgodnie z zasadami, ale zrobi\u0142 to \u017ale. Mo\u017cna to poprawi\u0107.<\/p>\n<p>Planowanie mo\u017ce znale\u017a\u0107 list\u0119 dzia\u0142a\u0144, kt\u00f3re prowadz\u0105 do po\u017c\u0105danego stanu gry. Tak jak ka\u017cda kwadrat na \u015bcie\u017cce mia\u0142a s\u0105siad\u00f3w (w pathfinding), ka\u017cda akcja w planie ma r\u00f3wnie\u017c s\u0105siad\u00f3w lub nast\u0119pc\u00f3w. Mo\u017cemy wyszukiwa\u0107 te dzia\u0142ania i nast\u0119pne, a\u017c osi\u0105gniemy po\u017c\u0105dany stan.<\/p>\n<p>W naszym przyk\u0142adzie, po\u017c\u0105dany wynik to \u201ewezwa\u0107 stworzenie, je\u015bli to mo\u017cliwe\u201d. Na pocz\u0105tku tury widzimy tylko dwa mo\u017cliwe dzia\u0142ania, dozwolone przez zasady gry:<\/p>\n<p><i>1. Zagra\u0107 Swamp (wynik: Swamp w grze)<br \/>\n2. Zagra\u0107 Forest (wynik: Forest w grze)<\/i><\/p>\n<p>Ka\u017cde podj\u0119te dzia\u0142anie mo\u017ce prowadzi\u0107 do dalszych dzia\u0142a\u0144 i zablokowa\u0107 inne, znowu w zale\u017cno\u015bci od zasad gry. Wyobra\u017a sobie, \u017ce zagrali\u015bmy Swamp \u2014 to usunie Swamp jako nast\u0119pny krok (ju\u017c go zagrali\u015bmy), a tak\u017ce usunie Forest (poniewa\u017c wed\u0142ug zasad mo\u017cna zagra\u0107 jedn\u0105 kart\u0119 l\u0105d\u00f3w na tur\u0119). Nast\u0119pnie AI dodaje jako nast\u0119pny krok \u2014 otrzymanie 1 czarnej many, poniewa\u017c nie ma innych opcji. Je\u015bli p\u00f3jdzie dalej i zdecyduje si\u0119 na Tap the Swamp, otrzyma 1 jednostk\u0119 czarnej many i nic z ni\u0105 nie b\u0119dzie m\u00f3g\u0142 zrobi\u0107.<\/p>\n<p><i>1. Zagra\u0107 Swamp (wynik: Swamp w grze)<br \/>\n 1.1 \u201eT\u0430\u043f\u043d\u0443\u0442\u044c\u201d Swamp (wynik: Swamp \u201et\u0430\u043f\u043d\u0443\u0442\u0430\u201d, +1 jednostka czarnej many)<br \/>\n Brak dost\u0119pnych dzia\u0142a\u0144 \u2013 KONIEC<br \/>\n2. Zagra\u0107 Forest (wynik: Forest w grze)<\/i><\/p>\n<p>Lista dzia\u0142a\u0144 okaza\u0142a si\u0119 kr\u00f3tka, utkn\u0119li\u015bmy w martwym punkcie. Powtarzamy proces dla nast\u0119pnego dzia\u0142ania. Gramy Forest, otwieramy dzia\u0142anie \u201eotrzyma\u0107 1 zielon\u0105 man\u0119\u201d, kt\u00f3re z kolei otworzy trzeci krok \u2014 wezwanie Elvish Mystic.<\/p>\n<p><i>1. Zagra\u0107 Swamp (wynik: Swamp w grze)<br \/>\n 1.1 \u201eT\u0430\u043f\u043d\u0443\u0442\u044c\u201d Swamp (wynik: Swamp \u201et\u0430\u043f\u043d\u0443\u0442\u0430\u201d, +1 jednostka czarnej many)<br \/>\n Brak dost\u0119pnych dzia\u0142a\u0144 \u2013 KONIEC<br \/>\n2. Zagra\u0107 Forest (wynik: Forest w grze)<br \/>\n 2.1 \u201eT\u0430\u043f\u043d\u0443\u0442\u044c\u201d Forest (wynik: Forest \u201et\u0430\u043f\u043d\u0443\u0442\u0430\u201d, +1 jednostka zielonej many)<br \/>\n 2.1.1 Wezwa\u0107 Elvish Mystic (wynik: Elvish Mystic w grze, -1 jednostka zielonej many)<br \/>\n Brak dost\u0119pnych dzia\u0142a\u0144 \u2013 KONIEC<\/i><\/p>\n<p>W ko\u0144cu zbadali\u015bmy wszystkie mo\u017cliwe dzia\u0142ania i znale\u017ali\u015bmy plan wzywaj\u0105cy stworzenie.<\/p>\n<p>To bardzo uproszczony przyk\u0142ad. Najlepiej wybiera\u0107 najlepszy mo\u017cliwy plan, a nie byle jaki, kt\u00f3ry spe\u0142nia jakie\u015b kryteria. Zazwyczaj mo\u017cna oceni\u0107 potencjalne plany na podstawie ostatecznego wyniku lub ca\u0142kowitych korzy\u015bci z ich realizacji. Mo\u017cna zdoby\u0107 1 punkt za zagrane pole ziemi i 3 punkty za przywo\u0142anie istoty. Zagrana Swamp da\u0142aby 1 punkt. A zagranie Forest \u2192 Taping Forest \u2192 przywo\u0142uj\u0105c Elvish Mystic \u2014 od razu da\u0142oby 4 punkty. <\/p>\n<p>Tak dzia\u0142a planowanie w Magic: The Gathering, ale ta sama logika stosuje si\u0119 r\u00f3wnie\u017c w innych sytuacjach. Na przyk\u0142ad przesuni\u0119cie piona, aby zrobi\u0107 miejsce dla ruchu go\u0144ca w szachach. Lub schowanie si\u0119 za \u015bcian\u0105, aby bezpiecznie strzela\u0107 w XCOM. W skr\u00f3cie, rozumiesz o co chodzi.<\/p>\n<h3>Ulepszone planowanie<\/h3>\n<p>\nCzasami jest zbyt wiele potencjalnych dzia\u0142a\u0144, aby rozwa\u017ca\u0107 ka\u017cd\u0105 mo\u017cliw\u0105 opcj\u0119. Wracaj\u0105c do przyk\u0142adu z Magic: The Gathering: powiedzmy, \u017ce w grze masz kilka kart ziemi i istot \u2014 ilo\u015b\u0107 mo\u017cliwych kombinacji ruch\u00f3w mo\u017ce si\u0119ga\u0107 dziesi\u0105tek. Istnieje kilka rozwi\u0105za\u0144 tego problemu.<\/p>\n<p>Pierwszy spos\u00f3b \u2014 backwards chaining (wsteczne formowanie \u0142a\u0144cucha). Zamiast przeszukiwa\u0107 wszystkie kombinacje, lepiej zacz\u0105\u0107 od ostatecznego wyniku i pr\u00f3bowa\u0107 znale\u017a\u0107 bezpo\u015bredni\u0105 tras\u0119. Zamiast przechodzi\u0107 od korzenia drzewa do okre\u015blonego li\u015bcia, poruszamy si\u0119 w przeciwnym kierunku \u2014 od li\u015bcia do korzenia. Ten spos\u00f3b jest prostszy i szybszy.<\/p>\n<p>Je\u015bli przeciwnik ma 1 punkt zdrowia, mo\u017cesz znale\u017a\u0107 plan \u201ezada\u0107 1 lub wi\u0119cej punkt\u00f3w obra\u017ce\u0144\u201d. Aby to osi\u0105gn\u0105\u0107, musisz spe\u0142ni\u0107 szereg warunk\u00f3w: <\/p>\n<p>1. Obra\u017cenia mog\u0105 zada\u0107 czary \u2014 musz\u0105 by\u0107 w r\u0119ce.<br \/>\n2. Aby zagra\u0107 czar \u2014 potrzebna jest mana.<br \/>\n3. Aby uzyska\u0107 man\u0119 \u2014 musisz zagra\u0107 kart\u0119 ziemi.<br \/>\n4. Aby zagra\u0107 kart\u0119 ziemi \u2014 musisz mie\u0107 j\u0105 w r\u0119ce.<\/p>\n<p>Inny spos\u00f3b \u2014 best-first search (najlepsze pierwsze wyszukiwanie). Zamiast przeszukiwa\u0107 wszystkie \u015bcie\u017cki, wybieramy najodpowiedniejszy. Najcz\u0119\u015bciej ten spos\u00f3b daje optymalny plan bez zb\u0119dnych koszt\u00f3w na poszukiwania. A* \u2014 to forma najlepszego pierwszego wyszukiwania \u2014 badaj\u0105c najbardziej obiecuj\u0105ce trasy od samego pocz\u0105tku, mo\u017ce ju\u017c znale\u017a\u0107 najlepsz\u0105 drog\u0119 bez potrzeby sprawdzania pozosta\u0142ych opcji.<\/p>\n<p>Interesuj\u0105c\u0105 i coraz bardziej popularn\u0105 opcj\u0105 wyszukiwania best-first jest Monte Carlo Tree Search. Zamiast zgadywania, kt\u00f3re plany s\u0105 lepsze od innych przy wyborze ka\u017cdego kolejnego dzia\u0142ania, algorytm wybiera losowych nast\u0119pc\u00f3w na ka\u017cdym kroku, a\u017c dojdzie do ko\u0144ca (gdy plan prowadzi do zwyci\u0119stwa lub pora\u017cki). Nast\u0119pnie ostateczny wynik jest u\u017cywany do zwi\u0119kszenia lub zmniejszenia oceny \u201ewagi\u201d wcze\u015bniejszych opcji. Powtarzaj\u0105c ten proces wielokrotnie, algorytm dostarcza dobrego oszacowania tego, jaki nast\u0119pny krok b\u0119dzie najlepszy, nawet je\u015bli sytuacja si\u0119 zmieni (je\u015bli przeciwnik podejmie dzia\u0142ania, aby przeszkodzi\u0107 graczowi). <\/p>\n<p>W opowie\u015bci o planowaniu w grach nie mo\u017cna pomin\u0105\u0107 Goal-Oriented Action Planning lub GOAP (planowanie dzia\u0142a\u0144 zorientowane na cel). To szeroko stosowana i omawiana metoda, ale opr\u00f3cz kilku wyr\u00f3\u017cniaj\u0105cych si\u0119 detali jest to w\u0142a\u015bciwie metoda backwards chaining, o kt\u00f3rej rozmawiali\u015bmy wcze\u015bniej. Je\u015bli zadanie brzmi \u201ezniszczy\u0107 gracza\u201d, a gracz znajduje si\u0119 za os\u0142on\u0105, plan mo\u017ce wygl\u0105da\u0107 nast\u0119puj\u0105co: zniszcz granatami \u2192 we\u017a je \u2192 rzu\u0107.<\/p>\n<p>Zwykle istnieje kilka cel\u00f3w, z kt\u00f3rych ka\u017cdy ma sw\u00f3j priorytet. Je\u015bli cel o najwy\u017cszym priorytecie nie mo\u017ce by\u0107 zrealizowany (\u017cadna kombinacja dzia\u0142a\u0144 nie tworzy planu \u201ezniszczy\u0107 gracza\u201d, poniewa\u017c gracz jest niewidoczny), AI wr\u00f3ci do cel\u00f3w o ni\u017cszym priorytecie.<\/p>\n<h2>Uczenie si\u0119 i adaptacja<\/h2>\n<p>\nJu\u017c wcze\u015bniej wspomnieli\u015bmy, \u017ce AI w grach zazwyczaj nie korzysta z uczenia maszynowego, poniewa\u017c nie nadaje si\u0119 to do zarz\u0105dzania agentami w czasie rzeczywistym. Ale to nie znaczy, \u017ce nie mo\u017cna niczego po\u017cyczy\u0107 z tej dziedziny. Chcemy, aby nasz przeciwnik w strzelance m\u00f3g\u0142 si\u0119 czego\u015b nauczy\u0107. Na przyk\u0142ad dowiedzie\u0107 si\u0119 o najlepszych pozycjach na mapie. Lub przeciwnik w bijatyce, kt\u00f3ry blokowa\u0142by cz\u0119sto u\u017cywane przez gracza kombinacje, motywuj\u0105c do u\u017cywania innych. Tak wi\u0119c uczenie maszynowe w takich sytuacjach mo\u017ce by\u0107 bardzo przydatne.<\/p>\n<h3>Statystyka i prawdopodobie\u0144stwa<\/h3>\n<p>\nZanim przejdziemy do bardziej z\u0142o\u017conych przyk\u0142ad\u00f3w, przyjrzyjmy si\u0119, jak daleko mo\u017cemy zaj\u015b\u0107, bior\u0105c kilka prostych pomiar\u00f3w i wykorzystuj\u0105c je do podejmowania decyzji. Na przyk\u0142ad, strategia w czasie rzeczywistym \u2014 jak mo\u017cemy okre\u015bli\u0107, czy gracz b\u0119dzie m\u00f3g\u0142 rozpocz\u0105\u0107 atak w pierwszych minutach gry i jak przygotowa\u0107 obron\u0119 przeciwko temu? Mo\u017cemy zbada\u0107 wcze\u015bniejsze do\u015bwiadczenia gracza, aby zrozumie\u0107, jak mo\u017ce wygl\u0105da\u0107 jego przysz\u0142a reakcja. Zaczniemy od tego, \u017ce nie mamy takich danych wyj\u015bciowych, ale mo\u017cemy je zebra\u0107 \u2014 za ka\u017cdym razem, gdy AI gra przeciwko cz\u0142owiekowi, mo\u017ce zapisywa\u0107 czas pierwszego ataku. Po kilku sesjach uzyskamy \u015bredni\u0105 warto\u015b\u0107 czasu, po kt\u00f3rym gracz zaatakuje w przysz\u0142o\u015bci.<\/p>\n<p>\u015arednie warto\u015bci maj\u0105 tak\u017ce swoj\u0105 wad\u0119: je\u015bli gracz 20 razy atakowa\u0142 szybko, a 20 razy gra\u0142 wolno, to potrzebne warto\u015bci b\u0119d\u0105 gdzie\u015b po\u015brodku, a to nam nie pomo\u017ce. Jednym z rozwi\u0105za\u0144 jest ograniczenie danych wej\u015bciowych \u2014 mo\u017cemy uwzgl\u0119dni\u0107 ostatnie 20 przypadk\u00f3w.<\/p>\n<p>Podobne podej\u015bcie jest stosowane przy ocenie prawdopodobie\u0144stwa okre\u015blonych dzia\u0142a\u0144, zak\u0142adaj\u0105c, \u017ce wcze\u015bniejsze preferencje gracza b\u0119d\u0105 takie same w przysz\u0142o\u015bci. Je\u015bli gracz atakowa\u0142 nas pi\u0119\u0107 razy kul\u0105 ognia, dwa razy b\u0142yskawic\u0105 i jeden raz w walce wr\u0119cz, to oczywiste, \u017ce preferuje on kul\u0119 ognia. Ekstrapoluj\u0105c, widzimy prawdopodobie\u0144stwo u\u017cycia r\u00f3\u017cnych rodzaj\u00f3w broni: kula ognia = 62,5%, b\u0142yskawica = 25% i walka wr\u0119cz = 12,5%. Nasze graj\u0105ce AI musi przygotowa\u0107 si\u0119 na obron\u0119 przed ogniem.<\/p>\n<p>Inn\u0105 interesuj\u0105c\u0105 metod\u0105 jest u\u017cycie Naive Bayes Classifier (naivnego klasyfikatora Bayesa) do analizy du\u017cych zbior\u00f3w danych wej\u015bciowych i klasyfikowania sytuacji, aby AI reagowa\u0142o w odpowiedni spos\u00f3b. Klasyfikatory Bayesa s\u0105 najbardziej znane z zastosowania w filtrach spamowych poczty elektronicznej. Tam analizuj\u0105 s\u0142owa, por\u00f3wnuj\u0105 je z tym, gdzie te s\u0142owa pojawia\u0142y si\u0119 wcze\u015bniej (w spamie czy nie), a nast\u0119pnie wyci\u0105gaj\u0105 wnioski na temat nadchodz\u0105cych wiadomo\u015bci. Mo\u017cemy zrobi\u0107 to samo nawet przy mniejszej ilo\u015bci danych wej\u015bciowych. Na podstawie wszystkich u\u017cytecznych informacji, kt\u00f3re widzi AI (np. jakie jednostki wroga zosta\u0142y stworzone, jakie zakl\u0119cia s\u0105 u\u017cywane lub jakie technologie zosta\u0142y zbadane) oraz wyniku ko\u0144cowego (wojna czy pok\u00f3j, \u201eatakowa\u0107\u201d czy broni\u0107 si\u0119 itd.) \u2014 wybierzemy odpowiednie zachowanie AI.<\/p>\n<p>Wszystkie te metody uczenia s\u0105 wystarczaj\u0105ce, ale najlepiej stosowa\u0107 je na podstawie danych z test\u00f3w. AI nauczy si\u0119 dostosowywa\u0107 do r\u00f3\u017cnych strategii, kt\u00f3re stosowali twoi testerzy gry. AI, kt\u00f3re dostosowuje si\u0119 do gracza po premierze, mo\u017ce sta\u0107 si\u0119 zbyt przewidywalne lub odwrotnie \u2014 zbyt trudne do pokonania.<\/p>\n<h3>Dostosowanie na podstawie warto\u015bci<\/h3>\n<p>\nBior\u0105c pod uwag\u0119 zawarto\u015b\u0107 naszego \u015bwiata gry i zasady, mo\u017cemy zmieni\u0107 zestaw warto\u015bci, kt\u00f3re wp\u0142ywaj\u0105 na podejmowanie decyzji, a nie tylko u\u017cywa\u0107 danych wej\u015bciowych. Robimy to w ten spos\u00f3b:<\/p>\n<ul>\n<li>Niech AI zbiera dane o stanie \u015bwiata i kluczowych wydarzeniach w trakcie gry (jak wspomniano powy\u017cej).<\/li>\n<li>Zmienimy kilka wa\u017cnych warto\u015bci na podstawie tych danych.<\/li>\n<li>Wdra\u017camy nasze decyzje, oparte na przetwarzaniu lub ocenie tych warto\u015bci.<\/li>\n<\/ul>\n<p>\nNa przyk\u0142ad, agent ma kilka pokoi do wyboru na mapie strzelanki z pierwszej osoby. Ka\u017cdy pok\u00f3j ma swoj\u0105 warto\u015b\u0107, kt\u00f3ra okre\u015bla, jak bardzo jest po\u017c\u0105dany do odwiedzenia. AI losowo wybiera, do kt\u00f3rego pokoju p\u00f3j\u015b\u0107, bazuj\u0105c na warto\u015bci. Nast\u0119pnie agent zapami\u0119tuje, w kt\u00f3rym pokoju zosta\u0142 zabity i zmniejsza jego warto\u015b\u0107 (prawdopodobie\u0144stwo, \u017ce tam wr\u00f3ci). Podobnie w przypadku odwrotnej sytuacji \u2014 je\u015bli agent zabije wielu przeciwnik\u00f3w, warto\u015b\u0107 pokoju wzrasta.<\/p>\n<h3>Model Markowa<\/h3>\n<p>\nCo je\u015bli u\u017cyjemy zebranych danych do prognozowania? Je\u015bli zapami\u0119tamy ka\u017cdy pok\u00f3j, w kt\u00f3rym widzimy gracza przez okre\u015blony czas, b\u0119dziemy mogli przewidzie\u0107, do kt\u00f3rego pokoju gracz mo\u017ce przej\u015b\u0107. \u015aledz\u0105c i zapisuj\u0105c ruchy gracza po pokojach (warto\u015bci), mo\u017cemy je prognozowa\u0107.<\/p>\n<p>We\u017amy trzy pokoje: czerwony, zielony i niebieski. A tak\u017ce obserwacje, kt\u00f3re zapisali\u015bmy podczas ogl\u0105dania sesji gry:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/6e90a365b72a176c36c9a14213baaafc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nLiczba obserwacji dla ka\u017cdego pokoju jest prawie r\u00f3wna \u2014 jeszcze nie wiemy, gdzie stworzy\u0107 dobre miejsce do zasadzki. Zbieranie statystyk jest r\u00f3wnie\u017c utrudnione przez respawn graczy, kt\u00f3rzy pojawiaj\u0105 si\u0119 r\u00f3wnomiernie na ca\u0142ej mapie. Ale dane o nast\u0119pnym pokoju, do kt\u00f3rego wchodz\u0105 po pojawieniu si\u0119 na mapie, s\u0105 ju\u017c przydatne.<\/p>\n<p>Wida\u0107, \u017ce zielony pok\u00f3j zadowala graczy - wi\u0119kszo\u015b\u0107 os\u00f3b z czerwonego przechodzi do niego, z czego 50% pozostaje tam d\u0142u\u017cej. Niebieski pok\u00f3j z kolei nie cieszy si\u0119 popularno\u015bci\u0105, prawie nikt do niego nie chodzi, a je\u015bli ju\u017c, to nie zatrzymuje si\u0119 tam. <\/p>\n<p>Jednak dane m\u00f3wi\u0105 nam co\u015b bardziej istotnego - gdy gracz znajduj\u0119 si\u0119 w niebieskim pokoju, nast\u0119pny pok\u00f3j, w kt\u00f3rym najprawdopodobniej go zobaczymy, b\u0119dzie czerwony, a nie zielony. Pomimo \u017ce zielony pok\u00f3j jest bardziej popularny ni\u017c czerwony, sytuacja si\u0119 zmienia, gdy gracz znajduje si\u0119 w niebieskim. Nast\u0119pny stan (czyli pok\u00f3j, do kt\u00f3rego gracz przejdzie) zale\u017cy od poprzedniego stanu (czyli pokoju, w kt\u00f3rym gracz obecnie si\u0119 znajduje). Dzi\u0119ki badaniu zale\u017cno\u015bci b\u0119dziemy w stanie przewidywa\u0107 dok\u0142adniej, ni\u017c gdyby\u015bmy po prostu liczyli obserwacje niezale\u017cnie od siebie.<\/p>\n<p>Przewidywanie przysz\u0142ego stanu na podstawie danych z przesz\u0142ego stanu nazywa si\u0119 modelem Markowa (Markov model), a takie przyk\u0142ady (z pokojami) nazywane s\u0105 \u0142a\u0144cuchami Markowa. Poniewa\u017c modele przedstawiaj\u0105 prawdopodobie\u0144stwo zmian mi\u0119dzy kolejnymi stanami, wizualizuje si\u0119 je w postaci FSM z prawdopodobie\u0144stwem przy ka\u017cdym przej\u015bciu. Wcze\u015bniej u\u017cywali\u015bmy FSM do przedstawienia stanu behawioralnego, w kt\u00f3rym znajdowa\u0142 si\u0119 agent, ale ta koncepcja rozci\u0105ga si\u0119 na ka\u017cdy stan, niezale\u017cnie od tego, czy jest zwi\u0105zany z agentem, czy nie. W tym przypadku stany reprezentuj\u0105 pok\u00f3j, kt\u00f3ry zajmuje agent:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/edb32dff7a3298b19c3fa4d66f48e9f4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo prosty spos\u00f3b przedstawienia wzgl\u0119dnego prawdopodobie\u0144stwa zmian stan\u00f3w, daj\u0105cy SI pewn\u0105 mo\u017cliwo\u015b\u0107 przewidywania nast\u0119pnego stanu. Mo\u017cna przewidywa\u0107 kilka krok\u00f3w naprz\u00f3d.<\/p>\n<p>Je\u015bli gracz jest w zielonym pokoju, istnieje 50% szans, \u017ce tam zostanie przy nast\u0119pnej obserwacji. Ale jakie jest prawdopodobie\u0144stwo, \u017ce nadal tam b\u0119dzie nawet p\u00f3\u017aniej? Istnieje nie tylko szansa, \u017ce gracz pozosta\u0142 w zielonym pokoju po dw\u00f3ch obserwacjach, ale r\u00f3wnie\u017c szansa, \u017ce odszed\u0142 i wr\u00f3ci\u0142. Oto nowa tabela uwzgl\u0119dniaj\u0105ca nowe dane:<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/f87afff68b066a879661e37f68654ae2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nZ niej wynika, \u017ce szansa na zobaczenie gracza w zielonym pokoju po dw\u00f3ch obserwacjach wyniesie 51% - 21% szans, \u017ce przyb\u0119dzie z czerwonego pokoju, 5% z nich, \u017ce gracz odwiedzi\u0142 niebieski pok\u00f3j pomi\u0119dzy nimi, oraz 25%, \u017ce gracz w og\u00f3le nie opu\u015bci\u0142 zielonego pokoju.<\/p>\n<p>Tabela \u2014 to po prostu czytelne narz\u0119dzie \u2014 proces wymaga tylko mno\u017cenia prawdopodobie\u0144stw na ka\u017cdym kroku. Oznacza to, \u017ce mo\u017cesz zajrze\u0107 daleko w przysz\u0142o\u015b\u0107, z jednym zastrze\u017ceniem: zak\u0142adamy, \u017ce szansa na wej\u015bcie do pokoju w pe\u0142ni zale\u017cy od aktualnego pokoju. Nazywa si\u0119 to w\u0142a\u015bciwo\u015bci\u0105 Markowa (Markov Property) \u2014 przysz\u0142y stan zale\u017cy tylko od tera\u017aniejszo\u015bci. Ale nie jest to w 100% pewne. Gracze mog\u0105 zmienia\u0107 decyzje w zale\u017cno\u015bci od innych czynnik\u00f3w: poziom zdrowia lub ilo\u015b\u0107 amunicji. Poniewa\u017c nie rejestrujemy tych warto\u015bci, nasze prognozy b\u0119d\u0105 mniej dok\u0142adne.<\/p>\n<h3>N-Gramy<\/h3>\n<p>\nA co z przyk\u0142adem walki i przewidywaniem kombinacji ruch\u00f3w gracza? To to samo! Ale zamiast jednego stanu lub zdarzenia b\u0119dziemy bada\u0107 ca\u0142e sekwencje, z kt\u00f3rych sk\u0142ada si\u0119 kombinasja cios\u00f3w.<\/p>\n<p>Jednym ze sposob\u00f3w, aby to zrobi\u0107, jest przechowywanie ka\u017cdego wej\u015bcia (np. Kick, Punch lub Block) w buforze i zapisanie ca\u0142ego bufora jako zdarzenie. Gracz wielokrotnie naciska Kick, Kick, Punch, aby u\u017cy\u0107 ataku SuperDeathFist, system AI przechowuje wszystkie wej\u015bcia w buforze i zapami\u0119tuje ostatnie trzy, u\u017cywane na ka\u017cdym kroku.<\/p>\n<p><img decoding=\"async\" alt=\"Jak stworzy\u0107 AI w grach: przewodnik dla pocz\u0105tkuj\u0105cych\" src=\"\/wp-content\/uploads\/2019\/11\/9a95226ae155dca5e45a66d4440f3cd4.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(Pogrubione linie, gdy gracz uruchamia atak SuperDeathFist.)<\/p>\n<p>AI zobaczy wszystkie mo\u017cliwo\u015bci, gdy gracz wybra\u0142 Kick, nast\u0119pnie kolejny Kick, a potem zauwa\u017cy, \u017ce nast\u0119pne wej\u015bcie to zawsze Punch. To pozwoli agentowi przewidzie\u0107 kombinacj\u0119 SuperDeathFist i zablokowa\u0107 j\u0105, je\u015bli to mo\u017cliwe.<\/p>\n<p>Te sekwencje zdarze\u0144 nazywaj\u0105 si\u0119 N-gramami (N-grams), gdzie N to liczba przechowywanych element\u00f3w. W poprzednim przyk\u0142adzie by\u0142a to 3-grama (trigram), co oznacza: pierwsze dwa zapisy s\u0105 u\u017cywane do przewidywania trzeciego. Odpowiednio w 5-gramie pierwsze cztery zapisy przewiduj\u0105 pi\u0105t\u0105 i tak dalej.<\/p>\n<p>Programista musi starannie dobiera\u0107 rozmiar N-gram\u00f3w. Mniejsza liczba N wymaga mniej pami\u0119ci, ale przechowuje mniejsz\u0105 histori\u0119. Na przyk\u0142ad 2-gram (bigram) zapisze Kick, Kick lub Kick, Punch, ale nie b\u0119dzie w stanie przechowa\u0107 Kick, Kick, Punch, dlatego AI nie zareaguje na kombinacj\u0119 SuperDeathFist.<\/p>\n<p>Z drugiej strony, wi\u0119ksze liczby wymagaj\u0105 wi\u0119cej pami\u0119ci i AI b\u0119dzie trudniej si\u0119 nauczy\u0107, poniewa\u017c pojawi si\u0119 znacznie wi\u0119cej mo\u017cliwych wariant\u00f3w. Je\u015bli masz trzy mo\u017cliwe wej\u015bcia Kick, Punch lub Block, a u\u017cywali\u015bmy 10-gramy, to powstanie oko\u0142o 60 tysi\u0119cy r\u00f3\u017cnych wariant\u00f3w.<\/p>\n<p>Model bigramy to prosta \u0142a\u0144cuch Markowa \u2014 ka\u017cda para \u201estan przesz\u0142y\/stanu obecnego\u201d jest bigramem i mo\u017cna przewidzie\u0107 drugi stan na podstawie pierwszego. 3-gramy i wi\u0119ksze N-gramy r\u00f3wnie\u017c mo\u017cna traktowa\u0107 jako \u0142a\u0144cuchy Markowa, gdzie wszystkie elementy (z wyj\u0105tkiem ostatniego w N-gramie) wsp\u00f3lnie tworz\u0105 pierwszy stan, a ostatni element \u2014 drugi. Przyk\u0142ad z walk\u0105 pokazuje szans\u0119 przej\u015bcia od stanu Kick i Kick do stanu Kick i Punch. Rozpatruj\u0105c wiele zapis\u00f3w historii wej\u015bciowej jako jedn\u0105 jednostk\u0119, zasadniczo przekszta\u0142camy sekwencj\u0119 wej\u015bciow\u0105 w cz\u0119\u015b\u0107 ca\u0142ego stanu. Daje nam to w\u0142a\u015bciwo\u015b\u0107 Markowa, kt\u00f3ra pozwala na u\u017cycie \u0142a\u0144cuch\u00f3w Markowa do przewidywania nast\u0119pnego wej\u015bcia i zgadywania, jaki ruch combo b\u0119dzie nast\u0119pny.<\/p>\n<h2>Podsumowanie<\/h2>\n<p>\nOm\u00f3wili\u015bmy najcz\u0119\u015bciej u\u017cywane narz\u0119dzia i podej\u015bcia w rozwijaniu sztucznej inteligencji. Przeanalizowali\u015bmy tak\u017ce sytuacje, w kt\u00f3rych nale\u017cy je stosowa\u0107 i gdzie s\u0105 one szczeg\u00f3lnie przydatne. <\/p>\n<p>To powinno wystarczy\u0107 do zrozumienia podstawowych rzeczy w AI w grach. Oczywi\u015bcie to nie wszystkie metody. Do mniej popularnych, ale wci\u0105\u017c skutecznych zaliczaj\u0105 si\u0119:<\/p>\n<ul>\n<li>algorytmy optymalizacji, w tym wspinaczka po wzg\u00f3rzach, spadek gradientowy i algorytmy genetyczne<\/li>\n<li>konkurencyjne algorytmy wyszukiwania\/planningu (minimax i przycinanie alpha-beta)<\/li>\n<li>metody klasyfikacji (perceptrony, sieci neuronowe i maszyny wektor\u00f3w no\u015bnych)<\/li>\n<li>systemy do przetwarzania percepcji i pami\u0119ci agent\u00f3w<\/li>\n<li>architektoniczne podej\u015bcia do AI (systemy hybrydowe, podzbiory architektur i inne sposoby nak\u0142adania system\u00f3w AI)<\/li>\n<li>narz\u0119dzia animacji (planowanie i synchronizacja ruchu)<\/li>\n<li>czynniki wydajno\u015bci (poziom szczeg\u00f3\u0142owo\u015bci, algorytmy anytime i timeslicing)<\/li>\n<\/ul>\n<p>\nZasoby internetowe na ten temat:<\/p>\n<p>1. Na GameDev.net znajduje si\u0119 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gamedev.net\/articles\/programming\/artificial-intelligence\/\">sekcja z artyku\u0142ami i samouczkami na temat AI<\/a><\/noindex>, a tak\u017ce <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> zawiera wiele prezentacji i artyku\u0142\u00f3w na szeroki zakres temat\u00f3w zwi\u0105zanych z rozwojem AI w grach.<br \/>\n3. <noindex><a rel=\"nofollow\" href=\"https:\/\/www.gdcvault.com\/\">The GDC Vault<\/a><\/noindex> zawiera tematy z szczytu GDC AI, z kt\u00f3rych wiele dost\u0119pnych jest za darmo.<br \/>\n4. Przydatne materia\u0142y mo\u017cna r\u00f3wnie\u017c znale\u017a\u0107 na stronie <noindex><a rel=\"nofollow\" href=\"http:\/\/gameai.com\/\">AI Game Programmers Guild<\/a><\/noindex>.<br \/>\n5. Tommy Thompson, badacz AI i deweloper gier, publikuje filmy na YouTube-\u043a\u0430\u043d\u0430\u043b\u0435 <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/user\/tthompso\">AI and Games<\/a><\/noindex> z wyja\u015bnieniami i badaniami AI w komercyjnych grach.<\/p>\n<p>Ksi\u0105\u017cki na ten temat:<\/p>\n<p>1. Seria ksi\u0105\u017cek Game AI Pro to zbiory kr\u00f3tkich artyku\u0142\u00f3w, wyja\u015bniaj\u0105cych, jak wdra\u017ca\u0107 konkretne funkcje lub jak rozwi\u0105zywa\u0107 specyficzne problemy.<\/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: Zgromadzona m\u0105dro\u015b\u0107 profesjonalist\u00f3w AI w grach<\/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: Zgromadzona m\u0105dro\u015b\u0107 profesjonalist\u00f3w AI w grach<\/a><\/noindex><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/amzn.to\/2KF4irS\">Game AI Pro 3: Zgromadzona m\u0105dro\u015b\u0107 profesjonalist\u00f3w AI w grach<\/a><\/noindex><\/p>\n<p>2. Seria AI Game Programming Wisdom to poprzednik serii Game AI Pro. Zawiera starsze metody, ale niemal wszystkie s\u0105 aktualne nawet dzisiaj.<\/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\">Sztuczna inteligencja: nowoczesne podej\u015bcie<\/a><\/noindex> \u2014 to jedna z podstawowych ksi\u0105\u017cek dla wszystkich, kt\u00f3rzy chc\u0105 zrozumie\u0107 og\u00f3ln\u0105 dziedzin\u0119 sztucznej inteligencji. To ksi\u0105\u017cka, kt\u00f3ra nie dotyczy tworzenia gier, a naucza podstawowych zasad AI.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <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.1.1 - 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\/pl\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\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\/pl\/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\udd47Jak stworzy\u0107 AI w grze: przewodnik dla pocz\u0105tkuj\u0105cych | ProHoster","description":"Natkn\u0105\u0142em si\u0119 na interesuj\u0105cy materia\u0142 o.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/news\/kak-sozdat-igrovoj-ii-gajd-dlya-nachinayushhih","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","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\/pl\/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\/pl\/wp-json\/wp\/v2\/posts\/52118","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=52118"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/52118\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=52118"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=52118"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=52118"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}