Albi89
15-05-2008, 22:12
Ciao a tutti!
Sto creando un semplice gioco del mastermind per tenermi in esercizio in vista dell'apertura della finestra d'esami.
Per i pochi che non conoscono questo gioco, consiste nell'indovinare un codice segreto: ad ogni turno, il giocatore compone un tentativo e l'altro (nel mio caso il computer) lo confronta con il codice segreto e compone un "feedback" composto dal numero di "cifre" (o pioli) corrette in posizione corretta e di cifre corrette ma in posizione errata.
Mentre la maggior parte degli algoritmi di cui ho avuto bisogno sono molto banali, quello per determinare le cifre corrette in posizione errata mi sta dando dei grattacapi.
Per iniziare, avevo adottato un algoritmo di questo tipo (sia N il numero richiesto):
1. Crea un array delle singole occorrenze numeriche nel codice segreto
2. Scorri gli elementi di questo array
'-> Confronta ogni elemento con tutti gli elementi del codice segreto
'-> se gli elementi sono uguali e la posizione diversa, incrementa N
Questo algoritmo ha un chiaro problema: mettiamo il caso che il nostro codice segreto sia 2 4 5 2 e il tentativo del giocatore 2 2 2 2.
L'algoritmo dirà che sono presenti 2 pioli corretti in posizione errata (i due 2 "centrali").
Ma questo non è corretto! Infatti i 2 che servono a comporre il codice sono soltanto... due! E sono quelli già correttamente posizionati ai bordi.
Dunque l'algoritmo dovrebbe restituire un N uguale a 0.
Ho allora perfezionato l'algoritmo calcolando, anzitutto, per ogni singola occorrenza numerica il numero di volte che appare nel codice segreto (sia OCC_NUM), e dunque calcolando il numero di volte in cui il piolo appare, nel codice, in posizione corretta (sia NUM_FOUND).
Il valore massimo che potrà assumere il nostro caro N è dunque (OCC_NUM - NUM_FOUND), che chiameremo MAX.
Il mio nuovo algoritmo funziona dunque così:
1. Crea un array delle singole occorrenze numeriche nel codice segreto
2. Scorri gli elementi di questo array
|-> Calcola MAX per il valore corrente come spiegato sopra
'-> Confronta ogni elemento con tutti gli elementi del codice segreto
'-> se gli elementi sono uguali e la posizione diversa, e inoltre
N non è stato incrementato più di MAX volte per l'elemento
corrente, incrementa N
Purtroppo anche questo algoritmo, sebbene più affidabile, non funziona perfettamente in tutte le occasioni, e non riesco a capire se l'errore è concettuale o di implementazione.
Spero che qualcuno di voi mi sappia dare qualche dritta, in particolare sarei contento se qualcuno mi rassicurasse sulla correttezza dell'algoritmo per permettermi di concentrarmi solo sui dettagli dell'implementazione che potrebbe contenere degli errori: così lavoro "su due fronti" e mi trovo un po' in difficoltà.
Grazie a tutti per l'aiuto! =)
Sto creando un semplice gioco del mastermind per tenermi in esercizio in vista dell'apertura della finestra d'esami.
Per i pochi che non conoscono questo gioco, consiste nell'indovinare un codice segreto: ad ogni turno, il giocatore compone un tentativo e l'altro (nel mio caso il computer) lo confronta con il codice segreto e compone un "feedback" composto dal numero di "cifre" (o pioli) corrette in posizione corretta e di cifre corrette ma in posizione errata.
Mentre la maggior parte degli algoritmi di cui ho avuto bisogno sono molto banali, quello per determinare le cifre corrette in posizione errata mi sta dando dei grattacapi.
Per iniziare, avevo adottato un algoritmo di questo tipo (sia N il numero richiesto):
1. Crea un array delle singole occorrenze numeriche nel codice segreto
2. Scorri gli elementi di questo array
'-> Confronta ogni elemento con tutti gli elementi del codice segreto
'-> se gli elementi sono uguali e la posizione diversa, incrementa N
Questo algoritmo ha un chiaro problema: mettiamo il caso che il nostro codice segreto sia 2 4 5 2 e il tentativo del giocatore 2 2 2 2.
L'algoritmo dirà che sono presenti 2 pioli corretti in posizione errata (i due 2 "centrali").
Ma questo non è corretto! Infatti i 2 che servono a comporre il codice sono soltanto... due! E sono quelli già correttamente posizionati ai bordi.
Dunque l'algoritmo dovrebbe restituire un N uguale a 0.
Ho allora perfezionato l'algoritmo calcolando, anzitutto, per ogni singola occorrenza numerica il numero di volte che appare nel codice segreto (sia OCC_NUM), e dunque calcolando il numero di volte in cui il piolo appare, nel codice, in posizione corretta (sia NUM_FOUND).
Il valore massimo che potrà assumere il nostro caro N è dunque (OCC_NUM - NUM_FOUND), che chiameremo MAX.
Il mio nuovo algoritmo funziona dunque così:
1. Crea un array delle singole occorrenze numeriche nel codice segreto
2. Scorri gli elementi di questo array
|-> Calcola MAX per il valore corrente come spiegato sopra
'-> Confronta ogni elemento con tutti gli elementi del codice segreto
'-> se gli elementi sono uguali e la posizione diversa, e inoltre
N non è stato incrementato più di MAX volte per l'elemento
corrente, incrementa N
Purtroppo anche questo algoritmo, sebbene più affidabile, non funziona perfettamente in tutte le occasioni, e non riesco a capire se l'errore è concettuale o di implementazione.
Spero che qualcuno di voi mi sappia dare qualche dritta, in particolare sarei contento se qualcuno mi rassicurasse sulla correttezza dell'algoritmo per permettermi di concentrarmi solo sui dettagli dell'implementazione che potrebbe contenere degli errori: così lavoro "su due fronti" e mi trovo un po' in difficoltà.
Grazie a tutti per l'aiuto! =)