(* * Hedgewars, a free turn based strategy game * Copyright (c) 2004-2012 Andrey Korotaev <unC0Rr@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA *){$INCLUDE "options.inc"}unit uRandom;(* * This unit supplies platform-independent functions for getting various * pseudo-random values based on a shared seed. * * This is necessary for accomplishing pseudo-random behavior in the game * without causing a desynchronisation of different clients when playing over * a network. *)interfaceuses uFloat;procedure SetRandomSeed(Seed: shortstring); // Sets the seed that should be used for generating pseudo-random values.function GetRandomf: hwFloat; overload; // Returns a pseudo-random hwFloat.function GetRandom(m: LongWord): LongWord; overload; inline; // Returns a positive pseudo-random integer smaller than m.procedure AddRandomness(r: LongWord); inline;function rndSign(num: hwFloat): hwFloat; // Returns num with a random chance of having a inverted sign.implementationvar cirbuf: array[0..63] of Longword; n: byte;procedure AddRandomness(r: LongWord); inline;beginn:= (n + 1) and $3F;cirbuf[n]:= cirbuf[n] xor rend;function GetNext: Longword; inline;beginn:= (n + 1) and $3F;cirbuf[n]:= (cirbuf[(n + 40) and $3F] + {n - 24 mod 64} cirbuf[(n + 9) and $3F]) {n - 55 mod 64} and $7FFFFFFF; {mod 2^31}GetNext:= cirbuf[n]end;procedure SetRandomSeed(Seed: shortstring);var i: Longword;beginn:= 54;if Length(Seed) > 54 then Seed:= copy(Seed, 1, 54); // not 55 to ensure we have odd numbers in cirbuffor i:= 0 to Pred(Length(Seed)) do cirbuf[i]:= byte(Seed[i + 1]);for i:= Length(Seed) to 54 do cirbuf[i]:= $A98765 + 68; // odd numberfor i:= 0 to 1023 do GetNextend;function GetRandomf: hwFloat;beginGetNext;GetRandomf.isNegative:= false;GetRandomf.QWordValue:= GetNextend;function GetRandom(m: LongWord): LongWord; inline;beginGetNext;GetRandom:= GetNext mod mend;function rndSign(num: hwFloat): hwFloat;beginnum.isNegative:= odd(GetNext);rndSign:= numend;end.