Forum MUGENATION: Architettura dei comandi - Forum MUGENATION

Salta al contenuto

Pagina 1 di 1
  • Non puoi iniziare una nuova discussione
  • Non puoi rispondere a questa discussione

Architettura dei comandi Orientata alla Chemical Artificial Intelligence

#1 L   puffolotti 

  • Kohai
  • PuntoPunto
  • Gruppo: Membro
  • Messaggi: 267
  • Iscritto: 18-February 08

Inviato 16 February 2010 - 00:17

Ora, un personaggio MUGEN é prima di ogni altra cosa uno sprite a cui possono essere impartiti dei comandi che gli fanno fare delle cose.

Tipo sferrare pugni o calci, ad esempio.

Il problema sta nel fatto che un gioco deve proporre una sfida, cioé l´avversario deve restituirle.

Quindi ci vogliono delle istruzioni che dicono al personaggio guidato dal computer come combattere.

Il metodo che ho sviluppato per Eclisse dei sentimenti si basa interamente sul trigger "Ailevel" che restituisce il livello di intelligenza artificiale del computer.

Partiamo da un richiamo al funzionamento del file CMD, dove ci sono i comandi per far agire il personaggio.

-Nozioni pratiche si trovano nel mio intervento successivo

Per utenti principianti:

Il computer ragiona a scatti di un sessantesimo di secondo, e ad ogni scatto valuta tutto quello che sta succedendo nel programma, e stabilisce cosa disegnare e che suoni eseguire.

Quando arriva a leggere il file CMD, lo legge dall´alto in basso, e ad ogni comando controlla se puó eseguirlo.

Per quanto riguarda l´essere umano il problema é che se una mossa contiene in sé l´esecuzione di una mossa successiva, impedirá alla successiva di essere eseguita da un essere umano, in quanto quando il computer osserverá che é stata eseguita la precedente, interromperá la lettura del file CMD.

Per quanto riguarda l´intelligenza artificiale bisogna pensare a questi due estremi:

un combattente che cerca di creare l´occasione per piazzare colpi devastanti
un combattente che si affida solo a colpi di disturbo per non scoprirsi troppo.

Siccome apparirá che il computer preferisce usare i colpi che stanno in cima nel file CMD, si puó creare sfumature di queste due psicologie semplicemente scegliendo l´ordine in cui mettere i comandi, ricordando che due comandi eseguiti con tasti di attacco diversi non si tapperanno mai a vicenda.

Lo stesso vale per la preferenza fra calci e pugni...

Ad esempio si puó fare una serie

pugno pesante / calcio pesante /pugno medio / calcio medio / pugno leggero / calcio leggero
Per un personaggio che andrá a preferire i pugni ai calci, i pesanti ai leggeri.

Oppure un militare europeo che predilige calci leggeri per piazzare pugni potenti, ma se non vede l´occasione preferisce disturbare.

calcio leggero / pugno pesante / pugno leggero / pugno medio / calcio pesante / calcio medio

Per utenti esperti:

Ora, con lo strumento AIlevel di ogni mossa si dovrebbe definire quando va usata e quando non va usata.

Prendiamo questa:

Quote

;jab accovacciato
[State -1, Crouching Light Punch]
type = ChangeState
value = 400
triggerall = command = "x"
trigger1 = statetype = C
trigger1 = ctrl


Ora, dobbiamo stabilire quali triggers sono comuni al computer e all´umano. In questo caso non ci interessa che il computer emuli la pressione di un pulsante. Anzi, vogliamo impedire che tale richiesta alteri la nostra mappatura.

Quote

;jab accovacciato
[State -1, Crouching Light Punch]
type = ChangeState
value = 400
triggerall = statetype = C
triggerall = ctrl


Questo va bene sia per il computer sia per l´essere umano, ora vediamo di distinguere fra i due.

Quote

;jab accovacciato
[State -1, Crouching Light Punch]
type = ChangeState
value = 400
triggerall = statetype = C
triggerall = ctrl

;N-up
trigger1 = Ailevel = 0 ; Specifica che lo sta guidando l´umano.
trigger1 = command = "x"

;CPU
trigger2 = Ailevel = 0 ; Specifica che lo sta guidando l´umano.
trigger2 = P2bodydist X < ([distanza utile del colpo] +16) - (Ailevel *2)
trigger2 = P2bodydist Y < 140 - (Ailevel*20) ;Ai livelli 7 ed 8 non la proverá mai contro un avversario in aria
trigger2 = random < ailevel ; fino allo 0,8% di probabilitá ogni sessantesimo di secondo.


Questo é un esempio a caso in cui il computer esegue la mossa a seconda della distanza dall´avversario, in accordo alla propria intelligenza.

La stringa evidenziata é estremamente importante, se omessa il computer eseguirá la mossa appena il trigger2 é soddisfatto, senza considerare le mosse successive nel file CMD.

Per utenti avanzati

trigger2 = random < ailevel
significa:piú il computer é intelligente maggiori sono le probabilitá che la provi

trigger2 = random > ailevel
significa: piú il computer é stupido maggiori sono le probabilitá che la provi

Quindi ogni mossa dovrebbe avere 4 gruppi di triggers, messi in questo ordine.:

1 triggerall richiesto sia a umani sia a CPU + Eventuali triggers per mosse che partono da piú situazioni

1 trigger1 solo per umani

Dopodiché

1 gruppo di triggers che dice quando é stupido o inutile farla (e dovrebbero vietarla agli ultimi 2-3 livelli)

1 gruppo di triggers che dice quando é intelligente farla. Questo gruppo di trigger puó semplicemente essere costituito dalla negazione dei parametri di cui al gruppo precedente seguito da una espressione casuale.
0

#2 L   puffolotti 

  • Kohai
  • PuntoPunto
  • Gruppo: Membro
  • Messaggi: 267
  • Iscritto: 18-February 08

Inviato 17 February 2010 - 00:31

Premessa: Questo intervento si occupa di metalinguaggio.
Intendo integrarlo con paragrafi di codice pratici che ancora non ho scritto.
I paragrafi di codice verranno aggiunti in seguito, eventualmente su suggerimento di altri sviluppatori.


Cos´é un attacco?
Un attacco, in un combattimento puó essere, in via esemplificativa ma non esaustiva:

Un tentativo di danneggiare strutturalmente, neurologicamente, psicologicamente l´avversario.
Un´azione di deterrenza, per scoraggiare l´avversario dall´attaccarci con una tecnica pericolosa.
Un´azione di disturbo che ha per scopo l´interrompere un attacco avversario giá in corso, ecc. ecc.

Sopra abbiamo parlato dei triggers dedicati all´intelligenza artificiale, e fin qui sappiamo che possiamo usare una funzione pseudo-continua per rendere reale la definizione di "Intelligenza artificiale".

Ancora abbiamo ben poco in mano, costruire un´intelligenza artificiale in questo modo appare terribilmente oneroso.
Quello che lo rende nebuloso é il fatto che la mente prosegue nell´affrontare il problema con la logica dei moduli.

Un piccolo salto con la creativitá e vediamo cosa ci offre la logica dei frammenti.

Dunque, l´avversario ci sta venendo addosso, le tre possibili soluzioni sono:

1) levarsi di mezzo,
2) aspettare e vedere che si inventa,
3) tirargliene una migliore.

Di un avversario che ci sta venendo addosso dobbiamo sapere una cosa, che ci aiuta nella scelta:


X) sta attaccando
Y) non sta attaccando ma potrebbe farlo
Z) non sta attaccando e non potrebbe farlo.


Evidenzio in blu questa classe di eventualitá perché... dio mi salvi se non mi ricordano qualcosa...

Vado nella cartella "DOCS" della mia distro di MUGEN e apro " trigger.htm "

Quote

MoveType gives the player's move-type. Refer to the section on StateDef in the CNS documentation for more details on MoveType. Useful for "move interrupts" in the CMD file.

Format:
MoveType [oper] move_type

Arguments:
[oper]
=, != (other operators not valid)

move_type (char)
A, I, H
Attack, Idle and GetHit move-types respectively.
Return type:
boolean int (1 or 0)
Error conditions:
none


Bene, questo mi permette di chiedere al MUGEN : che ***** sta combinando il grosso tipo con cui sto facendo a pugni?

Abbiamo quindi queste stringhe:

trigger[N] = enemynear, movetype = A ; Il pagliaccio sta attaccando.

trigger[N] = enemynear, movetype = I ; il pagliaccio non sta attaccando ma puó farlo.

trigger[N] = enemynear, movetype = H ; Il pagliaccio é esattamente dove serve per prendersene una buona. (per la serie: " Oooh!!, allora vienimi in braccio!")

Allora, come possiamo usare questa stringa?

Diciamo che la prima individua l´occasione per le mosse di disturbo (pugni leggeri, ad esempio)

La seconda individua l´occasione per mosse di attacco a sorpresa (mosse speciali che partono coperte)

La terza individua l´occasione per le punizioni triviali.

Ora, la domanda fondamentale per sapere se un colpo connetterá é: dove ***** si trova il pagliaccio?

Quindi possiamo distinguere le mosse in: antiaeree, alte, medie, basse.

Dunque, le antiaeree vanno bene quando l´avversario é distante da terra.

Trigger[N] = P2bodydistance Y > 81 - (Ailevel * 10) ; Piú il computer é intelligente prima si accorgerá che l´avversario non si trova al suolo.

Trigger[N] = P2bodydistance Y > 179 - (Ailevel * 20) ; Allo stesso modo si puó differenziare un personaggio da un altro in ogni aspetto, questi valori si adattano ad un eroinomane all´ultimo stadio...

Le mosse alte andrebbero usate quando l´avversario sta in piedi, quindi il trigger da usare potrebbe essere

trigger[N] = enemynear, Statetype != C

Oibó, ma lo stesso vale per le mosse basse, quindi per le mosse basse possiamo dire: una mossa bassa non é un´antiaerea.

Trigger[N] != P2bodydistance Y > 81 - (Ailevel * 10)

Tornando alle antiaeree, ci serve sapere un´altra cosa: se l´avversario sta cercando il crossup, per prenderci alle spalle mentre siamo scoperti

Trigger[N] = p2bodydist X > 0 A meno ché la mossa non colpisca anche alle nostre spalle, come ad esempio l´elettricitá di blanka.


Ma nasce un problema: dove cavolo li troviamo i triggers per infrangere la parata? sarebbe intelligente colpire medio quando l´avversario para basso, basso quando para alto, alto quando non puó parare.

Questo non é difficile, Prendiamo un paragrafo di tipo "Hitdef"

[State 210, 2]
type = HitDef
trigger1 = AnimElem = 3
attr = S, NA
animtype = Medium
damage = 57
guardflag = MA
[blah blah blah]

Guardflag... come vogliamo l´avversario.

Quote

StateType gives the player's state-type. Refer to the section on StateDef in the CNS documentation for more details on StateType. Useful for "move interrupts" in the CMD file.

Format:
StateType [oper] state_type

Arguments:
[oper]
=, != (other operators not valid)

state_type (char)
S, C, A
Stand, Crouch and Air state-types.

Return type:
boolean int (1 or 0)

Error conditions:
none


Bene, ora abbiamo un casino inestricabile :wacko:, grazie tanto logica dei frammenti direte voi.

Ma ora che abbiamo visto cosa ci offre la logica dei frammenti, torniamo a quella dei moduli.

Non dobbiamo chiederci: "quali attributi ha questa mossa?" (e quali no)

Dobbiamo invece chiederci "Questo attributo si applica a questa mossa?" (oppure no?)

Cosí ci faremo un elenco di mosse in base alla posizione relativa dell´avversario, in base al suo stato,

Questo immaginando che sia alla distanza giusta.

Allora, avremo:

;Antiaerea frontale.
trigger[N] = é alla distanza giusta?
trigger[N] = é in aria?
trigger[N] = é dietro di me?
trigger[N] = Quanto mi piace usare la mossa?


;Antiaerea avanti-dietro: qui dobbiamo togliere l´interrogazione sul fatto che l´avversario sia dietro di noi.
trigger[N] = é alla distanza giusta?
trigger[N] = é in aria?
;trigger[N] = é dietro di me?
trigger[N] = Quanto mi piace usare la mossa?


Alta, media, bassa,

Ma, ohibó: che veggo? abbiamo distanze massime e minime.

In quest´ottica é irrilevante la posizione del nostro personaggio, e difficilmente un attacco apparterrá a piú di 2 categorie per altezza.

Quindi possiamo prepararci questo bel paragrafino:

Trigger§ = P2bodydist X < ([allungo della mossa] + 16 + enemynear, velX*[ticks fino all´ hitdef]) -Ailevel * 2
Trigger§ = P2bodydist X = [allungo della mossa] + 16 -Ailevel * 2

Piú il computer é intelligente meglio la misurerá.
Il lasso di tempo dall´inizio dell´animazione alla connessione del colpo, in questo modo si prevede dove sará l´avversario al momento dell´esplosione del colpo.

Trigger§ = enemynear, movetype = ; I se é un disturbo, A se é una contromossa, H... ORA E SEMPRE!!!
Trigger§ = enemynear, statetype = ; quello che la mia mossa puó colpire, da rimuovere per le antiaeree
Trigger§ = random < Ailevel * [quanto mi piace usare questa mossa] ; (1 va benissimo nella maggior parte dei casi)

Impostiamo quindi la mossa come se dovessimo spiegarla ad un amico che ci chiede come si usa quel personaggio, prendiamo ad esempio lo shoryuken.

;in generale:
triggerall = ryu deve avere il controllo
triggerall = ryu deve trovarsi al suolo.

;Per il giocatore
trigger1 = non deve essere guidato dal computer.
trigger1 = bisogna eseguire il comando "dragon punch"

trigger2 = deve essere guidato dal computer
trigger2 = non deve eseguirla quando l´avversario é in aria e troppo vicino
trigger2 = comunque se sei stupido, falla anche in quel caso.
;possono esserci altri trigger paralleli per la cretinata.

trigger3 = quando l´avversario é vicino o si sta avvicinando
trigger3 = specialmente se sta attaccando
trigger3 = puniscilo in base all´intelligenza che si aspetta tu abbia.
;possono esserci altri trigger paralleli per la punizione.

trigger4 = se non c´é pericolo concreto... usala per confondere le idee all´avversario.
trigger4 = fino a diciamo il livello 6.

Ci sono domande o obbiezioni??
0

Condividi questa discussione:


Pagina 1 di 1
  • Non puoi iniziare una nuova discussione
  • Non puoi rispondere a questa discussione

1 utenti stanno leggendo questa discussione
0 utenti, 1 ospiti, 0 utenti anonimi