L'intelligenza artificiale nei videogames: il learning engine, Parte IV

Dopo aver capito come l'algoritmo intelligente acquisisce dati, il passo successivo è la comprensione del processo che identifica una meccanica del gioco.

speciale L'intelligenza artificiale nei videogames: il learning engine, Parte IV
Articolo a cura di

Nei precedenti articoli abbiamo capito cosa vuol dire creare una AI in un videogame, la differenza tra un'AI che deve capire come giocare e una che deve dedurre tutte le meccaniche del gioco e come fanno delle linee di codice ad identificare un personaggio o un oggetto su uno schermo fatto di pixel. Ora andiamo ad analizzare il sistema che impara il funzionamento del game engine, elencando prima tutte le nozioni che i programmatori hanno considerato basilari e che hanno implementato nel codice, così che possa derivare una struttura più complessa: un po' come insegnare l'alfabeto ad un bambino (gli sprite dei personaggi), le regole della grammatica italiana (i concetti di posizione, velocità e collisione) e aspettare che il resto lo capisca da solo lasciandogli il tempo di imparare dalle situazioni della vita quotidiana (video di gameplay fatti da altri giocatori). Se avete capito tutto quello che vi abbiamo spiegato nei precedenti speciali, potete proseguire con la lettura per scoprire come prende vita il learning engine.

I concetti basilari che vanno insegnati all'algoritmo

Oltre agli sprite dei personaggi e degli oggetti che compaiono su schermo, all'AI servono dei concetti basilari per capire il game engine. In primo luogo deve sapere cos'è un'animazione, fornendole la successione di sprite che compaiono su schermo non appena viene attivata. L'immagine mostra la sequenza che comparirà su schermo non appena viene azionata un'animazione: in questo modo il codice capirà sempre dove si trova Mario, perché conosce tutti i suoi movimenti possibili tramite queste sequenze di pixel. Oltre all'animazione, chiaramente l'algoritmo deve sapere cosa vuole dire ‘posizione', identificabile con le coordinate (ascissa X e ordinata Y) nonché la relazione di limite tra un oggetto e l'altro: in un frame del gioco dovrà registrare la posizione di uno sprite1, sapere quanto spazio occupa sugli assi X e Y, la distanza fra questo e un eventuale sprite2 e quanto occupa quest'ultimo sugli assi X e Y. Grazie alla cognizione dello spazio il learning engine può capire subito quando la velocità di Mario si azzera durante una corsa: se il suo ultimo pixel arriva in prossimità di un ostacolo (un mattoncino, lo sprite2), allora dovrà immediatamente fermarsi. Questo serve ad evitare che il sistema crei collisioni ambigue come la sovrapposizione di più pixel appartenenti a sprite diversi.

Abbiamo inoltre dato per scontato che la velocità deve essere presente fra le nozioni note all'AI, sia sull'asse X che sull'asse Y: identificando Mario in una posizione nel frame 1 e in un'altra nel frame 2, sarà molto semplice stabilire qual è la sua velocità, generalmente espressa come spazio percorso (pixel percorsi) su tempo trascorso (frame trascorsi). In ultimo luogo servirà insegnare al codice che la telecamera si sposta, perché in Super Mario Bros. l'inquadratura su schermo scorre in avanti mentre Mario avanza, rivelando nuovi oggetti a destra e nascondendone altri a sinistra. In questo modo il learning engine capisce perché alcuni oggetti sono troncati ai bordi dello schermo e perché compaiono e scompaiono.

Il learning engine

Siamo finalmente giunti al punto cruciale, quello che definisce un algoritmo di Machine Learning e lo distingue dagli altri algoritmi più ‘statici': prevedere un cambiamento in base a quello che ha osservato l'AI nella sua esperienza. Qui entriamo con entrambi i piedi nel campo della statistica, che cerca di fare una previsione del dato che verrà basandosi sui dati di cui dispone. L'obiettivo è capire il game engine, un insieme di regole dominate da funzioni IF (se) - THEN (allora) dove IF rappresenta un insieme di fatti che sono le condizioni che azionano il THEN, che rappresenta invece un cambiamento di quello che accade su schermo. Ad esempio ipotizziamo che Mario inizialmente si muova solo in orizzontale: se (IF) la posizione di Mario (inizialmente fermo) cambia di 10 pixels in pochi frame, allora (THEN) la sua velocità è aumentata. Se l'AI identifica sempre le stesse condizioni che fanno variare la velocità di Mario da 0 a 5, allora potrà estrapolare una regola del game engine. Se ogni volta che Mario sta correndo si ferma (la sua velocità arriva a zero) in corrispondenza di un blocco, allora l'AI può prevedere con esattezza quando si fermerà ogni volta che vede un ostacolo. Una volta che l'algoritmo capisce una regola deve comunque verificarla di volta in volta per assicurarsi che sia vera sempre. Statisticamente non fa altro che controllare che l'errore sia inferiore ad una certa soglia variando dei parametri, cioè cerca l'ipotesi migliore di una regola affinché la predizione sia esatta: se Mario si ferma ogni volta che incontra un ostacolo, la regola sarà vera e l'algoritmo calcolerà un errore nullo nella sua predizione. Se però Mario salta poco prima di andare addosso all'ostacolo, allora l'algoritmo si accorgerà che c'è un errore nella sua predizione (che fino ad ora è sempre stata "la velocità di Mario va a zero in corrispondenza dell'ostacolo").

In quel caso l'AI deve trovare un'altra regola per effettuare una predizione migliore e in questo caso sarà indispensabile l'analisi dei nuovi parametri, ovvero il salto in verticale (non previsto, perché abbiamo ipotizzato che fino ad ora Mario si è mosso solo in orizzontale). Quindi ci sono due algoritmi distinguibili nell'AI: uno che cerca nuove meccaniche nei frame e un altro che verifica che queste meccaniche predette siano accurate, così che il codice non smetta di imparare dopo aver ipotizzato una regola. In un certo senso il secondo algoritmo mette in discussione quel che dice il primo algoritmo, così da non dare mai una regola per scontata e cercarne di nuove dai dati che continua ad acquisire (quindi dai nuovi frame che analizza). La predizione del primo algoritmo consiste nello stabilire quali saranno i pixel dei prossimi frame prima che gli vengano mostrati: il secondo algoritmo li analizza, li paragona a quanto predetto e conta quelli sbagliati. Da lì cercherà di derivare nuove regole per far sì che quell'errore (i pixel sbagliati) siano il meno possibile.

Abbiamo finalmente capito come impara un'AI in modo del tutto generico, ma per chi mastica un po' di programmazione non è difficile capire come verrà implementato il codice finale. Si basa tutto sul controllo delle variabili in un certo istante e la somiglianza tra queste in corrispondenza di un evento (Mario cade, si ferma, salta, e via dicendo) che fa nascere una nuova regola del game engine. Da lì si valuta l'errore commesso nel prevedere nuove situazioni dalle regole dedotte, cercando di farlo tendere il più possibile a zero migliorando queste regole. Nel prossimo articolo continueremo ad approfondire il learning engine con altri esempi semplici ed intuitivi.