hedgewars/uRandom.pas
changeset 105 e7cb9bb4a9de
parent 102 c45643d3fd78
child 107 b08ce0293a51
equal deleted inserted replaced
104:e647d0589bff 105:e7cb9bb4a9de
    37 procedure SetRandomSeed(Seed: shortstring);
    37 procedure SetRandomSeed(Seed: shortstring);
    38 function  GetRandom: real; overload;
    38 function  GetRandom: real; overload;
    39 function  GetRandom(m: LongWord): LongWord; overload;
    39 function  GetRandom(m: LongWord): LongWord; overload;
    40 
    40 
    41 implementation
    41 implementation
    42 const rndM = 2147483578;
       
    43 var cirbuf: array[0..63] of Longword;
    42 var cirbuf: array[0..63] of Longword;
    44     n: byte;
    43     n: byte;
    45 
    44 
    46 function GetNext: Longword;
    45 function GetNext: Longword;
    47 begin
    46 begin
    48 n:= (n + 1) and $3F;
    47 n:= (n + 1) and $3F;
    49 cirbuf[n]:=
    48 cirbuf[n]:=
    50            (cirbuf[(n + 40) and $3F] +           {== n - 24 mod 64}
    49            (cirbuf[(n + 40) and $3F] +           {n - 24 mod 64}
    51             cirbuf[(n +  9) and $3F]) mod rndM;  {== n - 55 mod 64}
    50             cirbuf[(n +  9) and $3F])            {n - 55 mod 64}
       
    51             and $7FFFFFFF;                       {mod 2^31}
    52             
    52             
    53 Result:= cirbuf[n]
    53 Result:= cirbuf[n]
    54 end;
    54 end;
    55 
    55 
    56 procedure SetRandomSeed(Seed: shortstring);
    56 procedure SetRandomSeed(Seed: shortstring);
    57 var i: Longword;
    57 var i: Longword;
    58 begin
    58 begin
       
    59 if Length(Seed) > 60 then Seed:= copy(Seed, 1, 60); // not 64 to ensure we have even numbers in cirbuf
    59 for i:= 0 to pred(Length(Seed)) do
    60 for i:= 0 to pred(Length(Seed)) do
    60     cirbuf[i]:= byte(Seed[i + 1]) * 35791253;
    61     cirbuf[i]:= byte(Seed[i + 1]) * 35791253;
    61 
    62 
    62 for i:= Length(Seed) to 63 do
    63 for i:= Length(Seed) to 63 do
    63     cirbuf[i]:= i * 23860799;
    64     cirbuf[i]:= i * 23860799;
    70 Result:= frac( GetNext * 0.0007301 + GetNext * 0.003019)
    71 Result:= frac( GetNext * 0.0007301 + GetNext * 0.003019)
    71 end;
    72 end;
    72 
    73 
    73 function GetRandom(m: LongWord): LongWord;
    74 function GetRandom(m: LongWord): LongWord;
    74 begin
    75 begin
       
    76 GetNext;
    75 Result:= GetNext mod m
    77 Result:= GetNext mod m
    76 end;
    78 end;
    77 
    79 
    78 end.
    80 end.