author | belphegorr <szabibibi@gmail.com> |
Mon, 23 Jul 2012 19:15:59 +0300 | |
changeset 7263 | 644eabbc9218 |
parent 7043 | 7c080e5ac8d0 |
child 7389 | 15c3fb4882df |
permissions | -rw-r--r-- |
(* * 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. *) interface uses uFloat; procedure initModule; procedure freeModule; 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; // Returns a positive pseudo-random integer smaller than m. function rndSign(num: hwFloat): hwFloat; // Returns num with a random chance of having a inverted sign. implementation var cirbuf: array[0..63] of Longword; n: byte; function GetNext: Longword; begin n:= (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; begin n:= 54; if Length(Seed) > 54 then Seed:= copy(Seed, 1, 54); // not 55 to ensure we have odd numbers in cirbuf for 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 number for i:= 0 to 1023 do GetNext end; function GetRandomf: hwFloat; begin GetNext; GetRandomf.isNegative:= false; GetRandomf.QWordValue:= GetNext end; function GetRandom(m: LongWord): LongWord; begin GetNext; GetRandom:= GetNext mod m end; function rndSign(num: hwFloat): hwFloat; begin num.isNegative:= odd(GetNext); rndSign:= num end; procedure initModule; begin n:= 54; FillChar(cirbuf, 64*sizeof(Longword), 0); end; procedure freeModule; begin end; end.