Oppure

Loading
27/03/10 13:22
a_butta
Ciao a tutti. Sto cercando di costruire il gioco del quindici in pascal (in realtà in delphi però quello che mi serve è più un procedimento pascal) e mi sono bloccato nel mescolare i numeri.

Io ho 16 pannelli che hanno name 'P' e :

1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16

e all'inizio tutti hanno caption corrispondente al loro numero tranne il 16 che ha caption ''
io devo avere una procedura che generi un array da 1 a 16 (mettiamo v[1..16] of integer) al cui interno ogni posizione ha un numero casuale compreso tra 1 e 15, ma ogni volta che viene assegnati un numero, esso non deve riapparire. Mi spiego: se ho l'array v[1] a cui è stato assegnato per random il numero 3, questo numero tre non dovrà essere riassegnato.

Come faccio?
Spero di essermi spiegato.

PS: non mi interessa tanto il codice pascal, quanto proprio il ragionamento per arrivarci.

grazie a tutti
saluti

aaa
27/03/10 14:20
Poggi Marco
Ciao!
Ho letto il tuo quesito, e ti propongo il seguente metodo:

- Crea un array ordinato in modo cresscente es.: a=[1,2,3...15]

- Imposta un ciclo decrescente (da 2 a 15) dove sgneri un numero casuale compreso tra 1
e l'indice del ciclo.

- Scambia i numeri dell' array che hanno come posizione l' indice del ciclo, e il numero
casuale
aaa
27/03/10 14:44
a_butta
Funziona alla grande: ecco il codice:
randomize;
for i:= 1 to 15 do a[i]:=i;

for i:= 2 to 15 do
 begin
   x:= random(i)+1;
   passo:= a[i];
   a[i]:= a[x];
   a[x]:= passo;
 end;

for i:= 1 to 15 do writeln(a[i]);
readln;


Grazie mille PoggiMarco.
Devo anche ringraziare manvb.net che mi ha fornito una soluzione alternativa; posto il codice:
var
x,i,y:byte;
barray: array[1..15] of boolean;
begin
for i:= 1 to 15 do barray[i] := false;
while y<=100 do
begin
repeat
x := random(15)+1;
if barray[x] = false then
begin
writeln(x);
barray[x] := true;
end;
until barray[x] = true;
y:= y+1;
end;
readln;
end.


Grazie mille a entrambi! Gentilissimi!

aaa
27/03/10 17:40
Poggi Marco
Ho letto i sorgeti, e ho trovato alcune imperfezioni.

Nel primo:

L' idea e quella di impostare un ceclo, che ad ogni iterazione, generi un numero casuale nell' array, e questo non venga più toccato.

Faccio due esempi per spiegarmi:

;)
for i:= 1 to (15-1) do 
begin 
   x:= random(15-i+1)+i; 
   passo:= a[i]; 
   a[i]:= a[x]; 
   a[x]:= passo; 
end; 

;)
for i:= 15 dowto 2 do 
begin 
   x:= random(i)+1; 
   passo:= a[i]; 
   a[i]:= a[x]; 
   a[x]:= passo; 
end; 


Nel secondo:

Come mai imposti l' uscita dal ciclo esterno " while y <= 100 do " ?


Ultima modifica effettuata da Poggi Marco 27/03/10 17:54
aaa
27/03/10 23:47
a_butta
Postato originariamente da Poggi Marco:

Ho letto i sorgeti, e ho trovato alcune imperfezioni.

Nel primo:

L' idea e quella di impostare un ceclo, che ad ogni iterazione, generi un numero casuale nell' array, e questo non venga più toccato.

Nel secondo:

Come mai imposti l' uscita dal ciclo esterno " while y <= 100 do " ?


Ti rispondo: nel primo non so: ho messo quel codice che secondo me è logicamente giusto e ti dico che funziona alla perfezione :asd:
Secondo: ho provato ad esempio a mettere 15 cicli soltanto ma mi butta fuori solo 10 numeri non quindici, forse perchè ogni volta che trova un true in realtà "brucia" un ciclo, così mettendo 100 è quasi sicuro:asd:... mi sono spiegato?

Comunque, in definitiva funzionano :D questo è quello che importa!
grazie mille!!
aaa
28/03/10 9:44
Poggi Marco
Di nulla!

Per quanto riguarda il secondo caso, puoi incrementare y all' interno del ciclo repeat, in modo da conteggiare i numeri effettivamente estratti.

Ho fatto un breve test, e ho concluso che mediamente servono 50 iterazioni.
Solo per l' 1.5% dei casi, servono più di 100 cicli.
aaa