• Nenhum resultado encontrado

Modul singleplayer și aplicarea tehnicilor de inteligență artificială

Într-un sens larg, cele mai multe jocuri încorporează o anumită formă de inteligență artificială (IA), adică nu este acea formă academică, ci mai degrabă un amestec de tehnici care în principal sunt preocupate de crearea iluziei de inteligență artificială.

De exemplu, dezvoltatorii s-au folosit de inteligența artificială ani de zile, pentru a da aparent inteligență nenumăratelor caractere de joc, de la fantomele din clasicul joc Pac-Man până la boții4 din jocul de acțiune cu împușcături Counter-Strike.

Unii dezvoltatori consideră că sarcinile cum ar fi căutarea unui traseu aparțin de inteligența artificială a jocului. Steven Woodcok a raportat în “2003 Game Developer’s Conference AI Roundtable Moderator’s Report” că unii dezvolatori cred că și detectarea de coliziune face parte din inteligența artificială a unui joc, ceea ce arată că sunt o mulțime de interpretări exagerate.

Vom merge pe ideea că inteligența artificială în jocuri include totul, de la simpla urmărire și evadare, la modelul de mișcare și multe altele.

4 Este un jucător controlat de calculator folosind inteligența artificială.

32

Ciclu de decizii al caracterului non-jucător (en: non-player character) execută trei pași în mod constant:(10)

percepe - acceptă informații despre mediul înconjurător, hartă, inamic;

gândește - evaluează informațiile percepute și plănuiește conform regulilor;

acționează – execută planul;

Alții ar putea argumenta că această abordare este mult prea simplă și prin urmare ar putea fi nepotrivită pentru crearea unei experiențe de joc plăcută, dar nu este așa. De fapt, jocurile video nu au nevoie de caractere non-jucător care sunt la fel de sofisticate și capabile ca și jucătorii umani care joacă. Jocurile sunt menite să fie distractive, iar sistemul de inteligență artificială nu ar trebui să fie prea bun, asta ar face jocul imposibil de câștigat. În schimb, ar trebui să permită jucătorului să câștige jocul în moduri interesante și provocatoare.

În general tehnicile de comportament în inteligența artificială pentru jocuri sunt de două feluri: deterministe și nedeterministe.(11)

Determinist

Comportamentul determinist este specific și previzibil. Nu există nici o incertitudine. Un exemplu simplu de comportament determinist este un algoritm simplu de urmărire. Se poate programa un caracter non-jucător să se îndrepte spre un anumit punct țintă prin avansarea de-a lungul axelor x și y până când coordonatele caracterului x și y coincid cu locația țintă.

Nedeterminist

Comportamentul nedeterminist este opusul comportamentului determinist, deoarece are un grad de incertitudine și este oarecum imprevizibil. Un exemplu de comportament nedeterminist este un caracter non-jucător care învață să se adapteze la tactică de luptă a unui jucător. O astfel de învățare ar putea folosi o rețea neuronală, tehnică Bayesion sau un algoritm genetic.

În inteligența artificială tehnicile deterministe sunt cele mai folosite în devoltarea unui joc.

Aceste tehnici sunt previzibile, ușor și rapid de implementat, înțeles și testat. Deși sunt foarte utilizate, metodele deterministe plasează sarcina de a anticipa și de a programa toate scenariile explicite pe umerii dezvoltatorilor.

33

Metodele deterministe nu facilitează învățarea sau evoluția și după ce joci puțin, aceste comportamente tind să devină previzibile. Acest lucru limitează perioada în care un joc este distractiv și începe să devină plictisitor.

Probabil cea mai utilizată tehnică ce este folosită la scară largă în inteligența artificială este trișarea. De exemplu, într-un joc ca al meu, calculatorul are acces la toate informațiile despre tancul meu, de la poziția lui, tipul tancului, cât mai am din viață și până la direcția în care mă îndrept și cu ce viteză. Trișarea în acest mod îl ajută pe caracterul non-jucător să aibă un avantaj în fața inteligenței jucătorului uman, dar aceasta poate fi și ceva rău. Dacă este prea evidentă pentru jucătorul uman această trișare, atunci el va crede că eforturile lui sunt zadarnice și își va pierde interesul. Așa cum am explicat și mai sus, sistemul de inteligență artificială nu trebuie să fie prea bun și acest mod de trișare pentru caracterele non-jucător trebuie să fie echilibrat destul cât să creeze o suficientă provocare pentru jucător, dar îndeajuns cât să păstreze jocul interesant și distractiv.

Clasicul joc Pac-Man îl face pe jucător să creadă că inamicii îl vânează, că fantomele sunt un grup inteligent. De fapt, această percepție de grup inteligent este doar o iluzie. Pentru a fi siguri că fantomele nu urmează toate același drum prin labirint și pentru a le oferi o personalitate individuală, fiecăreia îi este oferită o variație ușor diferită a aceluiași algoritm, care este o selecție foarte simplă de direcție de fiecare data când fantomele ajung la o intersecție în labirint.

În cazul în care se ajunge la o intersecție, fantoma trebuie să decidă dacă ar trebui să schimbe direcția sau nu. Uneori fantoma își schimbă direcția ca să se miște spre jucătorul uman, altădată alege o direcție aleatorie. Pentru a realiza acest comportament ușor diferit pentru fiecare dintre fantomele create este folosit un sistem aleatoriu ce utilizează factori de ponderare unici pentru fiecare dintre ele.

Astfel o fantomă se poate deplasa într-o direcție aleatorie 75% din timp și în direcția jucătorului în celelalte 25% din cazuri, atunci când aceasta ajunge la o intersecție. O altă fantomă ar avea alegerea aleatorie a direcției cu o pondere de 50% din timp și așa mai departe.

Rezultatul acestei metode simple este o personificare a fiecărei fantome de către jucător (prin proiecție de subconștient) și va percepe comportamentul unei fantome ca cel al unui jucător inteligent.

34

Diferența dintre mișcarea fantomelor în jocul Pac-Man nu este foarte mare față de tancurile non-jucător din WarTank și am încercat deasemenea să le ofer câte o personalitate diferită pentru a creea iluzia de inteligență.

Deoarece hărțile nu sunt sub forma unui labirint și tancurile au spațiu de mișcare mai mare, direcția nu se poate schimba doar la întâlnirea unei intersecții, așa că am decis ca fiecare tanc să aleagă o perioadă de timp aleatorie în care să verifice dacă să schimbe direcția sau nu. Așadar, la fiecare schimbare de direcție, tancul își alege în mod aleatoriu un nou interval de timp din cele 4 intervale predefinite: 1000, 1500, 2000 și 2500 de milisecunde.

La alegerea direcției de mers am folosit un algoritm simplu de urmărire. Utilizând tehnica de trișare, în care calculatorul știe poziția mea, am programat tancurile inamice să se îndrepte spre mine prin avansarea de-a lungul axelor x și y până când una dintre axe este egală cu una din axele mele. În acel moment tancul non-jucător se va opri, își va schimba direcția spre tancul cu jucător uman și va continua să tragă până când tancul jucător se va mișca și nici una dintre axe x și y nu va mai coincide.

Totuși am preferat că tehnica de trișare prin care calculatorul știe poziția mea să nu fie prea evidentă, așa că în funcție de cadranul în care se află tancul jucătorului am decis să aleagă una din cele două direcții și nu pe cea mai rapidă.

Figura 14: Cele patru cadrane ale unui sistem de coordonate carteziene

De fiecare dată când se alege o nouă direcție se verifică să nu fie blocată de un obstacol, iar dacă este blocată, se verifică altă direcție până când se găsește una care nu este blocată de nici un obstacol.

35

Se mai verifică de fiecare dată când este apelată funcția update(), adica de aproape 60 de ori pe secundă, dacă tancul non-jucător este pe aceeași axă x sau y cu tancul jucătorului uman, indiferent dacă timpul aleatoriu nu a trecut pentru o reverificare a direcției, tancul se oprește, se îndreaptă spre tancul jucătorului uman și trage.

Tank.prototype.updateAIEnemyTank = function (playerTank) { var directions, tankSpeed = this.tankSettings.speed;

this.game.physics.arcade.collide(this.tank, this.map.obstacles, this.tankHitObstacle, null, this);

this.game.physics.arcade.overlap(this.projectiles, this.map.obstacles, this.projectileHitObstacle, null, this);

this.tankMapLocation = this.map.spriteLocationOnMap(this.tank);

if(playerTank) {

directions = this.map.directionFromOneTankToAnother(this.tankMapLocation, playerTank.tankMapLocation)

} else {

directions = [this.game.rnd.pick(['right', 'left', 'up', 'down']), this.game.rnd.pick(['right', 'left', 'up', 'down'])];

}

if (this.game.time.now > this.enemyData.nextCheckDirection) {

this.enemyData.nextCheckDirection = this.game.time.now + this.game.rnd.pick([1000, 1500, 2000, 2500]);

this.tankDirection = this.map.checkAndGetDirections(directions, this.tankMapLocation);

this.tank.angle = this.tankAngleByDirection[this.tankDirection];

} else {

if(directions.length == 1){

this.tankDirection = directions[0];

this.tank.angle = this.tankAngleByDirection[this.tankDirection];

tankSpeed = 0;

} }

this.tank.body.velocity.x = 0;

this.tank.body.velocity.y = 0;

if (this.tankDirection == 'left') {

this.tank.body.velocity.x = -tankSpeed;

}

else if (this.tankDirection == 'right') { this.tank.body.velocity.x = tankSpeed;

}

else if (this.tankDirection == 'up') { this.tank.body.velocity.y = -tankSpeed;

}

else if (this.tankDirection == 'down') { this.tank.body.velocity.y = tankSpeed;

}

if(this.tank.alive){

this.fireProjectile();

} }

Secțiune de cod 11: Codul pentru mișcarea tancurilor controlate de calculator

36