Oppure

Loading
22/03/14 21:39
Fear
Salve, sto ragionando su un algoritmo ricorsivo che permetta di giocare a tris contro un computer
questo è più o meno l'idea che ho buttato giù, però non riesco a capire se può andare perché mi si sta intrecciando il cervello

PSEUDOCODICE:
int valuta (Sym, Pos, GRIGLIA){
   inserisci in GRIGLIA il simbolo Sym, alla posizione Pos;
   if (controlla_se_ho_fatto_tris == true)
      return 1;
   else
   if (griglia_is_piena)
      return 0;
   else{
      nPos = -1;      
      c = numCaselleLibereNellaGriglia; //metto dentro a c il numero totale di caselle vuote rimanenti
      while (c > 0){
         nPos = trovaLaPrimaCasellaVuotaAPartireDa(nPos+1); // ipotiziamo che le celle della griglia siano numerate in modo crescente da 0 a 8
         avversario = opposto(Sym); //se Sym è X, avversario sarà O
         x = valuta(avversario,nPos,GRIGLIA);
         if (x >= 0) //significa che il mio avversario ha fatto filetto e quindi non è un bene per me
            c--; //quindi non faccio niente e continuo il while
         else
            return -x;
      }
      return -1;
   }
}



mi sapreste dire se secondo voi può andare? mi sa che il return finale dopo la chiusura del while non va bene, ma non so come sistemare
aaa
24/03/14 14:33
pierotofy
Non si capisce bene il tuo ragionamento...

Ti consiglierei di scrivere in italiano (niente codice) la logica del tuo algoritmo. Magari cosi' ti si puo' dare qualche suggerimento.
Il mio blog: piero.dev
24/03/14 15:40
Fear
funzione ricorsiva valuta che accetta 3 parametri:
- Sym che è Il simbolo da inserire nella griglia che può essere O oppure X (saranno rappresentati da 0 o 1, oppure da true e false.. è indifferente, per ora consideriamoli astrattamente O e X)
- Pos che è la posizione in cui inserire il simbolo nella griglia
- GRIGLIA, che è la griglia su cui andiamo a lavorare

Come prima cosa si effettua l'operazione di inserimento del simbolo passato come parametro nella posizione pos della griglia GRIGLIA. (riga 2 dello pseudocodice sopra)

Come seconda cosa (riga 3) eseguiamo il controllo per vedere se ho fatto tris (richiameremo una funzione che si occuperà di questo controllando righe colonne e diagonali). A noi basta sapere che questa funzione ritorna true se dentro la griglia GRIGLIA c'è un tris del simbolo Sym, false altrimenti.
Se effettivamente c'è un tris la funzione valuta ritorna 1 (primo caso base della funz ricorsiva)
Altrimenti se non c'è un tris, controlliamo se può essere uno stato di patta.
E' una patta solo se con l'ultima mossa non si ha fatto tris E se la griglia è ormai piena, quindi la riga 6 richiama un'altra ipotetica funzione "griglia_is_piena" che ritorna true se GRIGLIA è piena.
In tal caso la funzione "valuta" entra nel secondo caso base, ritornando 0 come valore.

ALTRIMENTI (riga8)
entriamo nell'else che eseguirà la ricorsione.
Se arriviamo qui significa che inserendo il simbolo non si ha fatto tris e non si è riempita la griglia, quindi dobbiamo continuare fino a che non accade una delle due cose precedenti.
Come prima cosa guardo quante caselle libere mi rimangono nella GRIGLIA e metto questo valore dentro a c.
Questo valore mi serve per far partire il while (cioè so quante volte devo eseguirlo)
Per ogni casella libera faccio quindi partire la ricorsione di "valuta", così da provare tutte le strade possibili.
quindi metto dentro ad x (riga 14) il risultato della funzione "valuta" passandogli come input avversario (che è semplicemente l'opposto del simbolo attuale.. in altre parole se ora il simbolo valutato è O, avversario sarà X, e viceversa), nPos (che è, di ciclo in ciclo, una delle posizioni libere della griglia--> il while ciclerà tutte le posizioni libere)

se il valore ritornato è > 0, significa che la funzione "valuta" ha ritornato 1. E come abbiamo visto prima, ritorna 1 se il simbolo passatogli in input ha fatto filetto. Ciò significa che se x>0 è un male per me, perché l'avversario ha fatto filetto, quindi semplicemente ignoro questa strada e passo al ciclo successivo, semplicemente decremento c e non faccio altro.
Altrimenti (riga 17), se la funzione ha ritornato un valore < 0, ritorno l'opposto (perché se è un male per il mio avversario, sarà un bene per me)

Se arrivo fuori dal while, significa che non ho trovato nessuna strada che mi permettere di vincere o pareggiare, per cui ritorno -1 (riga 20)


Non son sicuro dell'ultimo punto però.......


P.s.
spero di averlo spiegato meglio rispetto a prima, in caso chiedi pure
Ultima modifica effettuata da Fear 24/03/14 15:41
aaa
24/03/14 16:47
pierotofy
Trovo che l'impostazione della funzione sia sbagliata; lo scopo della funzione e' di suggerire una mossa (possibilmente che massimizzi le probabilita' di vincita).

Al momento ritorni 1 se la partita e' vinta/persa, 0 se e' patta, e qualche altro numero praticamente casuale a questo punto negli altri casi.

In nessuna parte c'e' una ricerca per massimizzare le probabilita' di vincita. Semplicemente chiamare la funzione valuta in maniera ricorsiva non ti dara' questo risultato, assumendo che l'impostazione sia corretta - che non lo e' - ti dara' la prima mossa che non ti porta vicino alla perdita.

Ti suggerirei di leggere l'implementazione dell'algoritmo minimax ( it.wikipedia.org/wiki/… ) e di vedere come e' impostata la procedura ricorsiva li'.
Il mio blog: piero.dev
24/03/14 17:17
Fear
La funzione "valuta" ritorna sempre e solo 1, 0 o al più -1. Nessun altro valore.
Quello che vorrei fare è che
Quando ritorna 1 so che il mio avversario vince con la prossima mossa, quindi dovrei ritornare al mio chiamante una notifica che lo informa che non è la strada giusta da prendere e procedere con un altra strada....

Ho visto l'esempio su wikipedia, ma non riesco a svilupparne lo pseudocodice che c'è li...
aaa