View Full Version : the Diamondcrush Artificial Player, aka A.I.
jappilas
11-07-2006, 16:40
Dopo aver esposto alcune idee ad alcuni degli amici del team in privato, e aver mostrato ad alcuni di questi un prototipo di codice , mi decido ad aprire un thread apposito per discutere quella che rischia di essere un' aggunta importante per diamonds, al tempo stesso utile (per certe persone che non mi chiedono altro , "vitale") e di non banale implementazione
cioè un "agente" che generi le mosse al posto del secondo giocatore
ora, avrei buttato giù qualche idea nel file di testo allegato (in cui certe parti in effetti abbisognano di completamento e revisione . cosa che faro' asap), in cui è descritta, più che la vera e propria implementazione, una possibile "pipeline" delle operazioni che un "giocatore artificiale" potrebbe fare
e a seconda di tale strutturazione, quali parti e come si prestano ad espansioni e parametrizzazioni (i nomi dei possibili "profili" sono solo a titolo esemplificativo, come è esemplificativo il codice "c" di alcuni passaggi )
sostanzialmente la mia idea sarebbe :
impiegare un oggetto proxy MiniGrid/VirtualGrid, composto di un array statico di celle, con delle flag occupied e un id del tipo di droppable contenuta nella poszione omologa di Grid
quando l' agente ha il controllo sulla gempair, potrebbe o valutare le (4) mosse a disposizione e applicare quella "migliore" o controllare tutte le possibili posizioni target della gempair sulla griglia per poi cercare di "raggiungere" quella ottimale: queste sono le possibili "configurazioni" della pipeline di calcolo , una più semplice, l' altra più complessa e (forse) più "intelligente", ma con maggiore costo computazionale e di sviluppo
per trovare la mossa migliore si userebbe una funzione di valutazione ricorsiva che itererebbe sulla miniGrid/VirtualGrid e restituirebbe dei valori di "vantaggio" , questi verrebbero usati (opzionalmente pesati da coefficienti variabili a seconda dello stato del gioco) per calcolare il "punteggio" della mossa esaminata, tramite quella che è a tutti gli effetti una funzione di ottimalità (ricerca operativa rulez :D)
per chi volesse visionarlo l' accrocchio non testato e poco OO che al momento (NON) gira sulla mia macchina, verrà inviato sotto forma di file rar :D
aspetto commenti e idee :O
ps: ho iniziato a buttare giù del codice perchè avevo inizialmente l' intenzione di impegnarmi in uno spike apposito... ma non sono certo di avere suff tempo e risorse per dedicarmici nei prossimi giorni :(
Bellissima idea...
...ma non ci sarebbe prima altro?? :fiufiu:
Non so se ti, vi, ci siamo accorti che il progetto ha praticamente il tracciato piatto e che forse nemmeno le features di base saranno implementate?!?
:read: :read:
Bellissima idea...
...ma non ci sarebbe prima altro?? :fiufiu:
Non so se ti, vi, ci siamo accorti che il progetto ha praticamente il tracciato piatto e che forse nemmeno le features di base saranno implementate?!?
:read: :read:
sono d'accordo.
Sono convinto che il progetto rimarrà in questo stato fino a settembre(ritorno delle vancanze, etc etc). In questo periodo, piu che scrivere codice o feature grosse(come ia e il multiplayer), sarebbe meglio fare il punto della situazione, contarci e vedere che fare, stabilire delle propietà.
La cosa che mi piacerebbe piu sapere, e se il game designer(aka jocchan) sia ancora disponibile a segurci. Perche il codice si puo anche scrivere in 2 mesi, o 4 mesi o un anno, ma le idee sul gioco, le feature da mettere, non si inventano su 2 piedi.
Anche perche altrimenti, serve qualcuno(o qualcuni) che prenda la responsabilita, l'onere e l'onore di prendere le decisioni.
sempre ovviamente se a qualcuno viene voglia di tornare...
ps.per l'ia...
se dovessi scegliere dove impiegare piu energie, fra ia e multiplayer, voterei la seconda tutta la vita.
Cio non toglie che non si possano sviluppare parallelamente, oppure prima una e poi l'altra.
jappilas
11-07-2006, 21:04
Bellissima idea...
...ma non ci sarebbe prima altro?? :fiufiu:
Non so se ti, vi, ci siamo accorti che il progetto ha praticamente il tracciato piatto e che forse nemmeno le features di base saranno implementate?!?
:read: :read:
hai esattamente ragione però c'è da considerare che, per quanto mi riguarda, mettere le mani nelle parti "calde" del codice di DC è una cosa che ultimamente non riesco a fare :(
non perchè non voglia, tutt' altro, ma perchè in mancanza di una precisa coordinazione ho paura di combinare disastri in codice su cui già sta lavorando qualcun altro , ed anche perchè da qualche tempo trovo molto più difficile di prima, raccapezzarmi in coidce scritto da altri :fagiano:
quindi il mio modo di rendermi utile al progetto ora come ora è studiare fattibilità, eventuali algoritmi, abbozzo di codice eccetera di una sezione del motore di gioco che ancora non è stata valutata
e visto che finora mancano critiche sul tema, continuo con il mio spike sulla funzione di valutazione ricorsiva :D
ps.per l'ia...
se dovessi scegliere dove impiegare piu energie, fra ia e multiplayer, voterei la seconda tutta la vita.
sinceramente preferisco il singleplayer con l' Artificial player a occupersi della seconda griglia per un semplice motivo
tenendo due mani sulla tastiera e gli occhi su due griglie, non riesco a fare le prove giocando come vorrei, e finisco per non divertirmi assolutamente :O
Cio non toglie che non si possano sviluppare parallelamente, oppure prima una e poi l'altra.
è quello che spero :)
hai esattamente ragione però c'è da considerare che, per quanto mi riguarda, mettere le mani nelle parti "calde" del codice di DC è una cosa che ultimamente non riesco a fare :(
non perchè non voglia, tutt' altro, ma perchè in mancanza di una precisa coordinazione ho paura di combinare disastri in codice su cui già sta lavorando qualcun altro , ed anche perchè da qualche tempo trovo molto più difficile di prima, raccapezzarmi in coidce scritto da altri :fagiano:
quindi il mio modo di rendermi utile al progetto ora come ora è studiare fattibilità, eventuali algoritmi, abbozzo di codice eccetera di una sezione del motore di gioco che ancora non è stata valutata
e visto che finora mancano critiche sul tema, continuo con il mio spike sulla funzione di valutazione ricorsiva :D
sinceramente preferisco il singleplayer con l' Artificial player a occupersi della seconda griglia per un semplice motivo
tenendo due mani sulla tastiera e gli occhi su due griglie, non riesco a fare le prove giocando come vorrei, e finisco per non divertirmi assolutamente :O
è quello che spero :)
per il singleplayer avevo gia proposto di rendere il gioco come era prima. Cioè se una griglia va in game over, l'altra continua. In questa maniera si potrebbero fare piu prove(sarebbe ancora piu carina la possibilita di bloccare una griglia e continuare con l'altra, per testare anche le stone ;) ).
Ok.
Vedo che non avete capito la forza con cui ho scritto quel che ho scritto.
Lo sviluppo del gioco è morto! :ncomment:
Ovvero lo sviluppo si è fermato.
Qui non è più questione di cosa ci piacerebbe fare, è questione di fare e nessuno (compreso il sottoscritto) sta facendo.
Ora come ora l'obiettivo è uno e uno solo: dimezzare il codice del gioco.
Ovvero finchè jappy non riuscirà con scioltezza a lavorare con codice altrui bisognerà continuare a semplificare.
Ecco come potresti essere utile jappy: dire sul forum i punti del codice che non capisci e poi, utilizzando il forum per coordinarci, cercare la soluzione più chiare e semplice per tutti.
Non so come altro dirlo: Fek, Joch, Ufo e altri sono spariti...totolamente spariti!!!
E non penso per menefreghismo, anzi spero che ogni tanto un salto per leggere lo facciano, ma perchè non vedevano più possibile andare avanti.
Bene...finchè non si riuscirà a far vedere che si può andare avanti...bhè...non si andrà avanti!!!
(Ostia...che bella frase marzulliana :asd: :asd: :asd: )
Ora torno ai mie BTB e TLB, per non parlare di GDT e LDT.
jappilas
11-07-2006, 23:43
tutto corretto, tranne che Ufo, AFAIK non se n'è andato definitivamente, ma è scappato in vacanza in Polonia ;)
però questo thread non voleva essere una copia di quello "Chiusura del Progetto", che ho già letto, e un ripetere le considerazioni già fatte sullo stato del progetto, che già conosco...
avrei potuto non aprirlo e tenere riservata ogni mia considerazione e riga di codice e pseudocodice fino al momento in cui avrei fatto trovare direttamente nel repository il package finito funzionante e testato al 100%...
ho aperto il thread come "cantiere" dedicato a una funzione che probabilmente si dovrà implementare in ogni caso prima della release di dicembre (mancano 5 mesi, può ancora succedere di tutto) e a cui quindi qualcuno avrebbe dovuto mettere mano
quindi pregherei di rispondere a questo thread solo per quanto riguarda l' argomento ...
critiche costruttive al mio algoritmo e alla mia concezione di "generatore di mosse" sono ben accette,
suggerimenti su come semplificare la funzione di valutazione, sulla struttura delle entità coinvolte, pseudo codice, condizioni che l' AP e la sua classe compagna devono soddisfare (su cui modellare est per il TDD) eccetera, ancora meglio
anzi, esorto esplicitamente chiunque legga e abbia delle idee brillanti in proposito, a esporle: tral' altro per come è inteso ora l' AP ha pochi punti di dipendenza dal resto del codice (*)
(*)
una simbiosi tra un oggetto "agente" e un' oggetto MiniGrid, che lo disaccoppia dal resto
l' acoppiata emette coppie <muovi/ruota, sinistra/destra> che verranno solo in seguito convertite in eventi effettivi
quindi non serve una conoscenza approfondita della code base di DC per contribuire idee e algoritmi qui ;);)
;)
cdimauro
12-07-2006, 09:53
Se Marco non si sente per adesso di partecipare al progetto buttandosi in mezzo a rifattorizzazioni & co. per semplificare il codice (lo sappiamo tutti che è parecchio incasinato, e c'è gente che non vuole cimentarsi proprio per questo motivo), non vedo nulla di male se si dedica a qualcosa di utile per Diamonds: servirà a lui per "farsi le ossa" con Diamonds e la TDD (altrimenti ti spIezziamo le ditine :D) e al progetto che guadagnerà qualche utile funzionalità.
Ne ho già avuto modo di discutere con lui in forma privata, per cui non mi dilungo. I punti chiave, IMHO, sono:
- sviluppo in TDD (più si utilizza questo modello, più si entra nell'ottica di scrivere codice in un certo modo; ed è quello che vogliamo / pretendiamo per il codice di Diamonds);
- utilizzo di OOP per eliminare catene di if e quindi codice "getType like" (Alberto, tu che odii visceralmente if & switch, potresti dargli qualche utile consiglio :p).
Per il resto, direi di partire da un'IA molto semplice (quella che nel documento viene chiamata "Naive"), che non faccia quindi uso della simulazione dell'evolversi dello stato della griglia, perché diventerebbe troppo oneroso computazionalmente, ma soprattutto complicherebbe il codice (specialmente a questo stadio, senza test che possano evidenziare l'introduzione di eventuali bug nel codice a causa di qualche modifica).
Consiglio a chi può di leggersi il documento ed esprimere, eventualmente, le proprie idee: facciamo diventare questo thread un cantiere in cui scambiare informazioni utili a far proseguire Marco nella stesura del codice, aiutandolo nel prendere maggior confidenza col modello TDD.
Il codice direi di tenerlo separato dal progetto, in assenza di test. Introdurre nuove funzionalità nel codice è possibile e non sono contrario, purché nel pieno rispetto e rigore che ci siamo imposti, che ci consente di tenere sotto controllo il comportamento del codice.
P.S. Forse al momento si potrebbe usare la Grid anziché la miniGrid, non essendo necessaria una simulazione dell'evolversi dello stato della griglia, ma è da valutare: se serve aggiungere altre informazioni oltre a quelle contenute nella griglia, è meglio usarne un "duplicato" per il momento. Non si sa mai. ;)
Le idee sono molto buone. Personalmente vorrei vedere implementata la versione avanzata che sia anche in grado di "vedere" griglia, gems pair e altre info dell'avversario. In questo modo si potrebbero implementare altri modificatori un po' più aggressivi.
Ad esempio sapendo che la griglia dell'avevrsario è quasi piena potrebbe decidere di finirlo con una crush... "fatality" :asd:. Oppure se le stone stanno per trasformarsi in gemme e nel box della prossima gemspair ci sono dei chest di quel colore decidere di fare un crush per mandare stone e ostacolare l'avversario.
Inoltre non mi pare di aver visto cenni al fatto che le stone dovranno cadere seguendo un pattern prestabilito. L'agente dovrebbe conoscere questo pattern per decidere meglio come disporre le varie gemme in caso di caduta di stone mandate dall'avevrsario.
ciao ;)
cdimauro
12-07-2006, 11:02
Via e-mail avevo già parlato con Marco della possibilità di leggere la griglia dell'avversario, quindi considerando il suo stato per valutare le azioni dell'IA.
Buona l'idea di considerare le stone.
Comunque di idee da mettere in cantiere per l'IA ce ne sono tante, ma IMHO sarebbe meglio procedere per piccoli passi, cominciando dall'implementazione più semplice, per poi estendere man mano il modello aggiungendo altri requisiti / funzionalità.
Specialmente nell'ottica di uno sviluppo TD, che dovrebbe seguire Marco, penso che sia la soluzione migliore. ;)
jappilas
12-07-2006, 11:07
servirà a lui per "farsi le ossa" con Diamonds e la TDD (altrimenti ti spIezziamo le ditine :D) e al progetto che guadagnerà qualche utile funzionalità.
tranqui, ci tengo alle mie ditine ;)
- sviluppo in TDD (più si utilizza questo modello, più si entra nell'ottica di scrivere codice in un certo modo; ed è quello che vogliamo / pretendiamo per il codice di Diamonds);
stanotte ( :D) mi sono balenate delle possibili test list , perlomeno riguardanti la minigrid e i passi di valutazione ...
- utilizzo di OOP per eliminare catene di if e quindi codice "getType like" (Alberto, tu che odii visceralmente if & switch, potresti dargli qualche utile consiglio :p).
... insieme a un' idea su come ridurre il numero di if attraverso interfaccie MoveSupplier e EvaluateIteration :)
appena ho tempo, provo a implementarle
Per il resto, direi di partire da un'IA molto semplice (quella che nel documento viene chiamata "Naive"), che non faccia quindi uso della simulazione dell'evolversi dello stato della griglia, perché diventerebbe troppo oneroso computazionalmente, ma soprattutto complicherebbe il codice (specialmente a questo stadio, senza test che possano evidenziare l'introduzione di eventuali bug nel codice a causa di qualche modifica).
ehm, sto scoprendo che il naive agent non e' poi cosi' naive :D
si' che esplora un subset delle posizioni target e la sua pipeline e' un po' meno versatile mancando il disaccoppiamento tra mossa valutata e mossa da eseguire, ma le problematiche in fase di valutazione (dare un "punteggio" alla mossa, in base a possibilita' di crush , vicinanza tra gemme di stesso colore ecc) sono piu' o meno le stesse ;)
certo, per ora posso prendere in esame solo un subset dei possibili casi e ad es non effettuare simulazione delle crush (posso pero' vedere se il piu' prossimo "vicino" superiore e' tale da innescare una crush, cioe' chest contro chest o gem contro chest)
;)
l' alternativa davvero piu' naive (e anche la meno prevedibile :mbe:) esarebbe un generatore casuale di mosse :D
Consiglio a chi può di leggersi il documento ed esprimere, eventualmente, le proprie idee: facciamo diventare questo thread un cantiere in cui scambiare informazioni utili a far proseguire Marco nella stesura del codice, aiutandolo nel prendere maggior confidenza col modello TDD.
la mia difficolta' era essenzialmente capire come modellare dei test formali per qualcosa che all' esterno apparirebbe come una scatola nera euristica
ma mi sono reso conto che si dovrebbe poter fare strutturando il piu' possibile l' accrocchio per "mattoncini" ciascuno testabile e controllabile per conto suo
Il codice direi di tenerlo separato dal progetto, in assenza di test. Introdurre nuove funzionalità nel codice è possibile e non sono contrario, purché nel pieno rispetto e rigore che ci siamo imposti, che ci consente di tenere sotto controllo il comportamento del codice.
I test comunque arriveranno asap , appena usciro' dallo spike mode (e dagli esami :stordita: ) per entrare in official mode ;)
P.S. Forse al momento si potrebbe usare la Grid anziché la miniGrid, non essendo necessaria una simulazione dell'evolversi dello stato della griglia, ma è da valutare: se serve aggiungere altre informazioni oltre a quelle contenute nella griglia, è meglio usarne un "duplicato" per il momento. Non si sa mai. ;)
piu' che altro, l' oggetto proxy mi viene bene perche' posso dotarlo di metodi di utilita' che Grid non ha, come getNearestAboveNeighBour(MiniGridCell visitedCell) e getNeighbourTriad(MiniGridCell visitedCell) e, usando un array statico di elelemti <type, isOccupied> mantenere al tempo stesso basso il costo computazionale rispetto a quello che si avrebbe se dovessi iterare la DroppableList di Grid per ad es trovare i vicini di una cella...
per me e' piu' semplice lavorare in qs modo, (anche perche' si riducono i punti di contatto tra l' agente e il codice attuale) ma capisco per un altro possa essere diverso... :stordita:
jappilas
12-07-2006, 11:25
Ad esempio sapendo che la griglia dell'avevrsario è quasi piena potrebbe decidere di finirlo con una crush... "fatality" :asd:.
griglia avversaria quasi piena = desperation move available (per l' avversario) ;)
quando ci saranno le desperation move, basta notificare al player /agent avversario che la DP e' attiva, questo potra' reagire con un priority shift tipo "max_damage + acceleratedDrop" :D
Oppure se le stone stanno per trasformarsi in gemme e nel box della prossima gemspair ci sono dei chest di quel colore decidere di fare un crush per mandare stone e ostacolare l'avversario.
per adesso prendo in esame stone contro chest e aumento il sub parametro MoveScore.retardedDamageScore... per fare una cosa raffinata si puo' aumentare questo parametro di un valore non fisso ma variabile in base allo stone turn ;)
Inoltre non mi pare di aver visto cenni al fatto che le stone dovranno cadere seguendo un pattern prestabilito. L'agente dovrebbe conoscere questo pattern per decidere meglio come disporre le varie gemme in caso di caduta di stone mandate dall'avevrsario.
forse non e' indispensabile, basta avere un priority shift quando si attiva la "danger box" .. tieni conto che tanto le stones verranno "ricampionate" nella MiniGrid al turno successivo la loro caduta ;)
griglia avversaria quasi piena = desperation move available (per l' avversario) ;)
quando ci saranno le desperation move, basta notificare al player /agent avversario che la DP e' attiva, questo potra' reagire con un priority shift tipo "max_damage + acceleratedDrop" :D
Non sono del tutto convinto. Demandare all'avversario la notifica richiede l'implementazione di un qualche algoritmo nella grid normale che decida quando un giocatore umano è in difficolta, perché non possiamo pretedendere che il giocatore spinga un tasto per inviare il messaggio. Inoltre non vorrei vedere del codice che riguarda l'ai all'interno di Grid, non è il suo posto.
Se invece è l'ia a stimare quando il suo avevrsario è in difficolta e puo finirlo possiamo avere il controllo sulla precisione con cui riesce a uccidere il nemico in base al livello di difficolta.
forse non e' indispensabile, basta avere un priority shift quando si attiva la "danger box" .. tieni conto che tanto le stones verranno "ricampionate" nella MiniGrid al turno successivo la loro caduta ;)
La mia era solo un idea per far replicare una mia abitudine. Sia con spf2t che con dc mi sono imparato i vari pattern con cui cadono le stone. Quando dispongo le gemme normali e i chest tengo in considerazione i colori che cadranno in futuro cosi da avvantaggiarmi anche delle stone quando si trasformeranno in gemme.
ciao ;)
Sia con spf2t che con dc mi sono imparato i vari pattern con cui cadono le stone. Quando dispongo le gemme normali e i chest tengo in considerazione i colori che cadranno in futuro cosi da avvantaggiarmi anche delle stone quando si trasformeranno in gemme.
ciao ;)
OT
non sarebbe carino far resettare il pattern se non ci sono stone nella griglia?
Anche se il ricordarsi il pattern potrebbe essere considerata una skill ;)
Scusate.
Non volevo assolutamente offenedere o attacare nessuno.
Quoto semplicemente me stesso:
Bellissima idea...
...ma non ci sarebbe prima altro?? :fiufiu:
Ovvero: la cose è BELLISSIMA e mi ci vorrei buttare a capo fitto pure io se non fossi sotto esami.
Ma purtroppo ora come ora il progetto ha delle priorità e non so quanto sia saggio "consumare" energie per attività a bassa priorità.
Quindi, ottimo spike ma se ho tempo di codare su Diamonds lavoro sulle parti che bloccano il progetto.
Tutto qui...
Non mi picchiate :ave:
P.S.: ripeto...non voglio offendere nessuno ;)
jappilas
12-07-2006, 15:22
P.S.: ripeto...non voglio offendere nessuno ;)
tranquillo nessuno si offende ;)
dicevo solo che per quanto mi riguarda preferivo tenere questo thread più pulito possibile per tenerlo come punto di riferimento per lo sviluppo di questo "sottosistema" del gioco
e che, poichè ora come ora, non riesco a imbarcarmi nei refactoring necessari di cui gli altri si stanno occupando (mi occorrerebbe ristudiarmi le parti di test e codice relative, cosa che non riesco a fare) aggiungere quando posso idee e righe di codice a questa parte di programma, per "fissarle" prima di dimenticarmene, è il mio modo di essere utile a diamonds... mal che vada, quando il progetto tornerà a regime e l' AI sarà implementata in pompa magna , non si dovrà partire da "zero"...
per quello dicevo, chi ha idee, test, pseudocodice, specifiche, algoritmi, whatever, esponga qui... appena ho un momento prima di essere teletrasportato via, provo ad aggungere
cmq per ora sono alla funzione di esplorazione ricorsiva, prima si finisce quella poi è tutta discesa :D
jappilas
12-07-2006, 15:26
Non sono del tutto convinto. Demandare all'avversario la notifica richiede l'implementazione di un qualche algoritmo nella grid normale
....
ciao ;)
ti g' ha rason, non l' avevo considerato ;)
forse si potrebbe agguingere una seconda minigrid e valutare l' array delle "altezze delle prime celle disponibili" anche su quella dell' avversario a ogni turno :)
cdimauro
13-07-2006, 08:30
ehm, sto scoprendo che il naive agent non e' poi cosi' naive :D
si' che esplora un subset delle posizioni target e la sua pipeline e' un po' meno versatile mancando il disaccoppiamento tra mossa valutata e mossa da eseguire, ma le problematiche in fase di valutazione (dare un "punteggio" alla mossa, in base a possibilita' di crush , vicinanza tra gemme di stesso colore ecc) sono piu' o meno le stesse ;)
certo, per ora posso prendere in esame solo un subset dei possibili casi e ad es non effettuare simulazione delle crush (posso pero' vedere se il piu' prossimo "vicino" superiore e' tale da innescare una crush, cioe' chest contro chest o gem contro chest)
;)
E' una buona soluzione.
l' alternativa davvero piu' naive (e anche la meno prevedibile :mbe:) esarebbe un generatore casuale di mosse :D
Meglio di no: non cambierebbe poi tanto dalla situazione attuale. :p
la mia difficolta' era essenzialmente capire come modellare dei test formali per qualcosa che all' esterno apparirebbe come una scatola nera euristica ma mi sono reso conto che si dovrebbe poter fare strutturando il piu' possibile l' accrocchio per "mattoncini" ciascuno testabile e controllabile per conto suo
Se per "mattoncini" intendi dei pezzi di codice / funzionalità, va benissimo.
I test comunque arriveranno asap , appena usciro' dallo spike mode (e dagli esami :stordita: ) per entrare in official mode ;)
Anche perché l'official mode prevede l'introduzione di codice testato (anzi, prima i test e poi il codice :p), pena la fustigazione. :D
piu' che altro, l' oggetto proxy mi viene bene perche' posso dotarlo di metodi di utilita' che Grid non ha, come getNearestAboveNeighBour(MiniGridCell visitedCell) e getNeighbourTriad(MiniGridCell visitedCell) e, usando un array statico di elelemti <type, isOccupied> mantenere al tempo stesso basso il costo computazionale rispetto a quello che si avrebbe se dovessi iterare la DroppableList di Grid per ad es trovare i vicini di una cella...
per me e' piu' semplice lavorare in qs modo, (anche perche' si riducono i punti di contatto tra l' agente e il codice attuale) ma capisco per un altro possa essere diverso... :stordita:
No guarda, non c'è problema: di estendere la griglia al momento non se ne parla, per cui se ritieni che ti servano degli strumenti migliori, la soluzione della miniGrid AI-oriented è ottima. ;)
cdimauro
13-07-2006, 08:36
Ovvero: la cose è BELLISSIMA e mi ci vorrei buttare a capo fitto pure io se non fossi sotto esami.
Ma purtroppo ora come ora il progetto ha delle priorità e non so quanto sia saggio "consumare" energie per attività a bassa priorità.
Quindi, ottimo spike ma se ho tempo di codare su Diamonds lavoro sulle parti che bloccano il progetto.
Tranquillo Valerio: nessuno ti ha chiesto di partecipare attivamente alla stesura del codice dell'IA. :)
Questo thread è nato per dare semplicemente dei suggerimenti a Marco per implementare una prima forma di IA per Diamonds.
Le uniche energie richieste sono quelle della lettura del thread ed eventuali indicazioni che possono essere utili ai fini dell'implementazione del codice.
So bene che per adesso abbiamo altre priorità, ma Marco può procedere anche da solo.
Anche perché, come lui stesso ha affermato, per il momento non si sente di partecipare a rifattorizzazioni et similia, ma visto che tiene al progetto e vuol partecipare in qualche modo, lasciamolo lavorare a qualcosa che per lui è più abbordabile, e che gli permetterà di "farsi le ossa" con TDD & co.
Così più avanti potrà partecipare ai task come tutti gli altri. ;)
Tranquillo Valerio: nessuno ti ha chiesto di partecipare attivamente alla stesura del codice dell'IA. :)
Questo thread è nato per dare semplicemente dei suggerimenti a Marco per implementare una prima forma di IA per Diamonds.
Le uniche energie richieste sono quelle della lettura del thread ed eventuali indicazioni che possono essere utili ai fini dell'implementazione del codice.
So bene che per adesso abbiamo altre priorità, ma Marco può procedere anche da solo.
Anche perché, come lui stesso ha affermato, per il momento non si sente di partecipare a rifattorizzazioni et similia, ma visto che tiene al progetto e vuol partecipare in qualche modo, lasciamolo lavorare a qualcosa che per lui è più abbordabile, e che gli permetterà di "farsi le ossa" con TDD & co.
Così più avanti potrà partecipare ai task come tutti gli altri. ;)
L'io era nel senso di voi :sofico: :sofico:
In ogni caso hia ragion e...Marco può e deve fare tutto quello che3 ritiene utile per diamonds in tutti i modi che può.
Ora mi guardo il codice e vedo cosa posso suggerire.
In ogni caso, essendo un gioco tra 2 persone a "carte scoperte", direi che si potrebbe usare l'algoritmo MinMax per determinare la mossa migliore ;)
(finalmente l'esame di Intelligenza artificiale viene utile :D )
jappilas
13-07-2006, 12:02
Ora mi guardo il codice e vedo cosa posso suggerire.
per adesso sto rifattorizzando l' accrocchio dalla prima versione che Cesare notava essere una lunga catena di if, e la funzione di valutazione e' ora incapsulata in un' interfaccia
quindi l' oggetto EvaluationIteration corrente, o meglio il suo metodo doEvaluation() , se trova le condizioni per alterare la griglia, esegue MiniGrid newGrid = miniGrid.replicate()
applica le modifiche alla nuova istanza (ad es newGrid.remove(originalMiniGrid.getColorRegion(xPosition, yPosition)) )
istanzia nextEvaluationInteration = new DefaultEvaluationIteration(newGrid, xPosition, yPosition.... )
e si chiama nextEvaluationIteration.doEvaluation()
altrimenti chiama this.doEvaluation passando la stessa miniGrid originale e le coordinate del vicino da visitare
...
e' inoltre in fase di scrittura un "subagente" che fornisca la mossa successiva (<move/quarter rotation>, <left/right>) da valutare a seconda dello stato interno
se vuoi ti mando il package in un rar quando torno a casa ;)
In ogni caso, essendo un gioco tra 2 persone a "carte scoperte", direi che si potrebbe usare l'algoritmo MinMax per determinare la mossa migliore ;)
(finalmente l'esame di Intelligenza artificiale viene utile :D )
mumble mumble, posto che per adesso l' AP valuta "solo" l' effetto della sua mossa sulla propria griglia, come si potrebbe introdurre la valutazione della mossa dell' avversario sulla sua ? :)
mumble mumble, posto che per adesso l' AP valuta "solo" l' effetto della sua mossa sulla propria griglia, come si potrebbe introdurre la valutazione della mossa dell' avversario sulla sua ? :)
Il problema di MinMax è definire lo stato della griglia e valutarlo.
Direi che già una valutazione potrebbe essere la media delle altezze delle colonne della griglia.
Infatti in questo modo:
- se la media è alta -> si sta per perdere
- se la media è bassa -> posso giocare ancora per un po'.
In questo modo si va a valutare lo stato ottenuto applicando le modfiche.
A questo punto vdendo come varia il mio punteggio e il suo cercerò la mossa che minimizza il mio stato e massimizza quello avversario.
Ovvero la mia griglia è vutoa quella dell'avversario è piena :D :D
Ovviamente la qualità dell'AI dipende da come si valuta lo stato. Infatti con la valutazione che ho appena proposto l'avversario viene considerato spacciato anche se ha la griglia piena di dimananti e sta per arrivare un chest_diamond ( :eek: )
P.S.: ora che ci penso però il gioco non è a turni...quindi non so se Min Max funzia. :wtf:
jappilas
13-07-2006, 21:32
Il problema di MinMax è definire lo stato della griglia e valutarlo. Direi che già una valutazione potrebbe essere la media delle altezze delle colonne della griglia.
Infatti in questo modo:
- se la media è alta -> si sta per perdere
- se la media è bassa -> posso giocare ancora per un po'.
interessante, anche perchè non sarebbe di difficile implementazione, una volta che l' implementazione base è finita: infatti per ora uso un array int[8] per memorizzare le altezze delle prime celle libere, mi serve per "proiettare" sulla griglia la pivot e la gem della pair in arrivo
In questo modo si va a valutare lo stato ottenuto applicando le modifiche - per adesso solo sulla propria griglia però.
A questo punto vedendo come varia il mio punteggio e il suo cercerò la mossa che minimizza il mio stato e massimizza quello avversario.
Ovvero la mia griglia è vuoto quella dell'avversario è piena :D :D
tieni anche conto di come calcolo il punteggio: ho una classe per il risultato delle valutazioni
public class EvaluationResult
{
public int flashCrushChainValue = 0;
public int chestCrushChainValue = 0;
public int uncrushedDroppablesValue = 0;
public int retardedDamageValue = 0;
}
in cui ad ogni iterazione aumento il campo corrispondente al caso esaminato (e qui gli if, mi spiace ma credo che non si potranno togliere in quanto fisiologici a questo livello...), e una struttura di altrettanti pesi corrispondenti, per ottenere il costo finale
Alla fine, se ne potrebbe aggiungere uno, per correlare (in modo pesato a seconda del "profilo" o dello stato dell' AI) l' altezza media della griglia avversaria
P.S.: ora che ci penso però il gioco non è a turni...quindi non so se Min Max funzia. :wtf:
il gioco non è a turni, ma l' AI / AP "ragiona" a turni ;)
Considera turno il ritorno a un nuovo GemsPairOnControlState, l' immissione di una nuova gemspair da controllare e,
nel caso dell' "advanced agent" la conseguente iterazione per trovare la migliore posizione target e la generazione delle mosse necessarie per ottenerla,
nel caso del naive agent un loop di generazione di mosse che via via migliorino il "valore" della gemspair unita alla griglia, finchè non se ne perde il controllo
:)
Si potrebbe considerare il "turno asincrono" campionando la grid E la pair dell' avversario al momento dell' inizio del turno dell' AP ;)
EDIT: dopo aver letto sul problema del minmax , ho capito che prob ti riferivi al fatto che, tranne che all' inizio, non si ha la certezza di poter giocare a "turni sincronizzati" : cioè applicare uno stesso range di mosse su delle gempair uguali per ambo i giocatori
tra l'altro avevo iniziato a implementare in quel modo l' AP pensando al fatto che in effetti, ogni giocatore gioca per sè al proprio ritmo, e considerando che le uniche interazioni tra le due griglie avvengono quando uno invia o subisce dele stone... da qui l' idea di isolare l' AI il più possibile
non sarebbe impossibile valutare, invece dell' effetto della mossa attuale sulla propria grid e basta, l' effetto della mossa attuale sulla grid correlata all' effetto dell' ultima mossa dell' avversario sulla sua griglia
... ma per ora tengo da parte per una versione advanced agent v2 o Uber Agent :asd:
PS: notare che per adesso nulla di quel che riguarda l' interazione concreta con il resto del gioco è implementato,
Per ora l' idea è di focalizzarmi sulla funzione di valutazione cercando di farla funzionare
:sofico:
e al tempo stesso strutturando l' AP il più possibile come una "scatola nera" a cui basterà fornire una Grid, e dire come trasformare le "mosse" generate ad ogni "turno" in KeyEvent, per incastonarla nel gioco ;)
Già tale incastonamento però verrà in seguito e magari non sarò nemmeno io a farlo (per ora il mio obiettivo è il motore di generazione delle mosse, e quando già i suoi componenti saranno dotati di test esaustivi sarò felice, integrarlo in DC a quel punto dovrebbe essere semplice), espansioni all 'AP stesso verranno ancora dopo ;)
jappilas
15-07-2006, 10:21
il package "ap" contiene ora codice sia per il naive agent, sia per un advanced agent realizzato come da documento preliminare
cioè con un "move tree" implementato come "array di fattiblità" delle <posizioni target della slave rispetto alla pivot>, che può essere selezionato al volo da tre possibili, e con una funzione di aggiornamento dei "pesi" della funzione di guadagno
quindi, quel che rimane TODO è:
- i test :sofico: finora lasciati da parte per lo spike, ma cmq fondamentali (urgenti)
- rivedere il code path per la valutazione normale (correggere NormalEvaluationStep.doEvaluation()) (ASAP)
- integrazione con l' environment, con il gridController e la Grid (sostituire i commenti con comandi effettivi per generare KeyEvent) (meno urgente)
- aggiunta di valutazioni più sofisticate, ad es sulla griglia avversaria (in futuro)
per chi volesse vedere in che forma ho accrocchiato le idee che mi giravano in testa, c'è un archivio allegato... fustigatemi pure :D
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.