Eh eh, finalmente ho cominciato a capirci qualcosa :)
Lo so che ci ho messo parecchio, ma ultimamente, ringraziando il cielo, ho tanto lavoro, per cui il tempo scarseggia ;)
Avevo fatto, tempo fa, un programmi scemo per imparare a usare Gambas. Il programma si "inventava" tre numeri a caso e una ruota, e mi proponeva un bel terno (non ne ho mai azzeccato uno, ma ho imparato il codice RND :D)
Il programma, così com'era, non mi piaceva perché estraendo a caso tre numeri capitava che mi desse dei duplicati, visto che non c'era controllo.
Allora l'ho ripreso e l'ho modificato aggiungendo una classe "sacchetto", configurata cosi:
PROPERTY READ numeri AS Integer[]
PUBLIC FUNCTION riempi(numeri AS Integer[]) AS Integer[]
DIM estratto AS Integer
FOR estratto = 1 TO 90
numeri[estratto - 1] = estratto
NEXT
END
PUBLIC FUNCTION mescola(numeri AS Integer[]) AS Integer[]
DIM quale AS Integer
DIM estratti AS Integer
DIM memory AS Integer
' Mescolo i numeri
FOR estratti = 0 TO 89
quale = Rnd(0, 89)
memory = numeri[estratti]
numeri[estratti] = numeri[quale]
numeri[quale] = memory
NEXT
END
Poi nel programma mi limito a fare
DIM ruote AS String[11]
DIM estratti AS Integer[6]
DIM estrazione AS Integer
DIM numeri AS Integer[90]
DIM Sacchetto AS Sacchetto
Sacchetto = NEW Sacchetto
'Riempio il sacchetto e mescolo
Sacchetto.riempi(numeri)
Sacchetto.mescola(numeri)
'Estraggo i sei numeri
FOR estrazione = 0 TO 5
estratti[estrazione] = numeri[estrazione]
NEXT
(più altra roba, ovviamente)
Quindi prendo, come vedete, i primi sei numeri.
In questo modo sono sicuro di prendere una e una sola volta ogni numero. Non potrò mai avere un duplicato :)
Un miglioramento potrebbe essere il prendere non i primi sei, ma sei posizioni a caso.
Anche il rimescolamento mi pare abbastanza semplice ed efficace: in pratica per ogni posizione da 1 a 90, decido un'altra posizione a caso, e scambio i due numeri.
Cosa ne pensate? La logica degli oggetti è correttamente utilizzata? :)
Più avanti mi piacerebbe fare un altro programmino con la stessa classe, che mi faccia vedere un bel tabellone a video con i 90 numeri, e che mi faccia un'estrazione di un numero per volta, mettendo un segnaposto sul tabellone.
Si, insomma: il gioco della tombola versione "non devo mettere a posto alla fine" :D
Ciao. La mia risposta non c'entra niente con il discorso della logica ad oggetti, ma per estrarre 6 numeri unici a caso basta:
DIM ariNumeriEstratti AS NEW Integer[]
DIM unNumero AS Integer
RANDOMIZE
DO
unNumero = Int(Rnd(1, 91))
IF ariNumeriEstratti.Find(unNumero) = -1 THEN
ariNumeriEstratti.Add(unNumero)
ENDIF
IF ariNumeriEstratti.Count = 6 THEN BREAK
LOOP
FOR EACH unNumero IN ariNumeriEstratti
PRINT unNumero; " ";
NEXT
Ciao.
Ci sarebbe un'altra soluzione.
Utilizzare il metodo Resize sull'array.
Si dovrebbe cioè:
1) riempire un array Sacchetto[] con i 90 numeri a caso;
2) iniziare il prelievo togliendo sempre l'ultimo (vale a dire quello nella 90° posizione);
3) ridimensionare l'array togliendo 1 posto (da documentazione, il Resize taglia l'array in fondo).
Diciamo che in codice potrebbe essere:
DIM estratti AS NEW Integer[6]
Sacchetto.riempi(numeri)
Sacchetto.mescola(numeri)
FOR i = 0 to 5
estratti[i] = numeri[numeri.leght-1]
numeri.Resize(numeri.lenght-1)
NEXT
END
Così non hai bisogno di puntatori o di doppi array. Per Ripartire, basta riespandere i numeri a 90 e ripetere Sacchetto.riempi e .mescola.