Zitat von
mimi:
ach ? kannst du dazu mal ein kleines beispiel machen ?
Bei einem Spiel währe das bestimmt nicht besonder schlimm kommt aber auf das Spiel an.
mir ist aufgefallen wenn man Random in einem Timer aufruft zählt er nur hoch...... .
@mimi:
Gern, siehe weiter unten.
Zitat von
alzaimar:
Nun ja. Dann verwendet man aber eben nicht den Delphi-PRG, sondern einen etwas sicherererern, z.B. den Twister..
@alzaimar:
Ich will dir ja nicht zu nahe treten, aber die ursprüngliche Frage war nicht, welchen Random-Generator man verwenden sollte,
sondern, ob man Randomize nur einmal aufrufen sollte.
Zitat von
Neotracer64:
Vielleicht ist es ja für einige interessant. :)
Hab das gerade mit OllyDbg rausgefunden.
Zumindest ist das so bei Delphi 7 Enterprise. (Build 4.453)
Delphi-Quellcode:
function PredictNextRandom(RSeed: PInteger; Range: Integer): Integer;
begin
result := RSeed^ * $8088405 + 1;
asm
PUSH EDX
MOV EAX, Range
MUL result
MOV result, EDX
POP EDX
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
ShowMessage(IntToStr(PredictNextRandom(@RandSeed,10)) + '
== '+ IntToStr(Random(10)));
end;
Zitat:
Das ist gut, weil man sonst (wenn Randomize nur einmal aufgerufen wird) unter bestimmten Voraussetzungen ohne große Probleme vorhersagen kann, welches die nächste "Zufallszahl" ist, wenn die ersten paar "Zufallszahlen" bekannt sind.
PredictNextRandom, sagt die nächste Pseudozufallszahl IMMER voraus, egal wie häufig Randomize aufgerufen wurde. :D
Also im Prinzip egal, bzw. eher überflüssig Randomize häufiger aufzurufen.
@Neotracer64:
Das ist doch keine Vorhersage.
Im Prinzip macht ihr doch nichts Anderes als zum Beispiel
var oldrs:integer;
oldrs:=randseed;
ShowMessage(IntToStr(Random(range));
randseed:=oldrs;
Was ich in meinem Kommentar weiter oben meinte, ist daß die nächsten "Zufallszahlen" vorhergesagt werden können
ohne daß der aktuelle Wert von Randseed bekannt ist.
Die "bestimmten" Bedingungen, von denen ich sprach sind
1) Es wird die Random Funktion aus System benutzt, die auch in PredictNextRandom simuliert wird.
2) Der Algorithmus, mit dem der von Random gelieferte Wert in eine "Zufallszahl" umgewandelt wird, muß bekannt sein.
3) Zwischen den einzelnen Aufrufen von Random wird nicht Randomize aufgerufen.
Der unter (2) angesprochene Algorithmus, der eine Zahl im Bereich min bis max zurückgibt, könnte zum Beispiel so aussehen:
Delphi-Quellcode:
FUNCTION RandomNumber(min,max:integer):integer
begin
result:=Random(max-min+1)+min;
end;
Wenn wir zum Beispiel "Zufallszahlen" im Bereich 10 bis 60 brauchen können wir dann die "Zufallszahlen" mit
ShowMessage(IntToStr(RandomNumber(10,60)))
ausgeben.
Ich behaupte nun, daß ich, wenn eine bestimmte Anzahl nacheinander erzeugter Zufallszahlen (in der Reihenfolge der Erzeugung) vorliegen, die nächsten Zahlen vorhersagen kann,
ohne daß mir RandSeed bekannt ist.
Die Anzahl der Zahlen, die mindestens bekannt sein müssen ergibt sich zum Beispiel für Zahlen im Bereich 10 bis 60 mit
min:=10;
max:=60;
range:=max-min+1
count:=Trunc(LogN(range,$100000000))+1; // = 6
Ihr könnt mich gern testen.
1) Legt min und max fest. Beide müssen im Byte Bereich sein also 0 bis 255.
2) Notiert euch den Wert von RandSeed vor Erzeugung der ersten Zufallszahl (damit das später reproduzierbar ist)
3) Erzeugt mit der o.g. Funktion RandomNumber count+1 Zahlen (zur Sicherheit eine mehr als minimal erforderlich. (ich blamiere mich nicht so gern)
4) Stellt die count+1 Zahlen in die
DP, aber bitte nicht den notierten Wert von RandSeed. Der Witz an der Sache ist ja gerade, daß ich den nicht brauche.
Und ich brauche dann ein paar Minuten um die nächsten Zahlen zu nennen.
Die Beschränkung, daß min und max im Byte Bereich liegen müssen ist, keine grundsätzliche Beschränkung.
Ich habe, wie es der Zufall so will, gerade vor ein paar Tagen begonnen, mich mit diesem Thema auseinanderzusetzen, und das Programm, daß die Vorhersage macht ist noch in der Entwicklung und deshalb (noch) auf den Byte Bereich beschränkt.
Bei Interesse schreibe ich gern einen kleinen Aufsatz, wie das funktioniert und stelle dann auch gern das Programm mit Source-Code in die
DP. Das alles ist übrigens kein Hexenwerk, sondern eigentlich ganz simpel.