Skip to content

Commit

Permalink
Merge pull request #17 from VanNostrand/rng
Browse files Browse the repository at this point in the history
slightly fairer RNG
  • Loading branch information
lynxlynxlynx committed May 30, 2014
2 parents fe29971 + 2bef958 commit 3a9b5cd
Show file tree
Hide file tree
Showing 25 changed files with 1,356 additions and 42 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Expand Up @@ -152,6 +152,8 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
if (NOT APPLE AND NOT UNSAFE_PLUGIN) if (NOT APPLE AND NOT UNSAFE_PLUGIN)
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
endif (NOT APPLE AND NOT UNSAFE_PLUGIN) endif (NOT APPLE AND NOT UNSAFE_PLUGIN)
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
ADD_DEFINITIONS("-DSFMT_MEXP=19937")
ENDIF() ENDIF()


set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
Expand Down
3 changes: 2 additions & 1 deletion gemrb/core/Animation.cpp
Expand Up @@ -27,6 +27,7 @@
#include "Map.h" #include "Map.h"
#include "Sprite2D.h" #include "Sprite2D.h"
#include "Video.h" #include "Video.h"
#include "RNG/RNG_SFMT.h"


namespace GemRB { namespace GemRB {


Expand All @@ -35,7 +36,7 @@ Animation::Animation(int count)
frames = (Sprite2D **) calloc(count, sizeof(Sprite2D *)); frames = (Sprite2D **) calloc(count, sizeof(Sprite2D *));
indicesCount = count; indicesCount = count;
if (count) { if (count) {
pos = rand() % count; pos = RAND(0, count-1);
} }
else { else {
pos = 0; pos = 0;
Expand Down
2 changes: 2 additions & 0 deletions gemrb/core/CMakeLists.txt
Expand Up @@ -118,6 +118,8 @@ FILE(GLOB gemrb_core_LIB_SRCS
GUI/TextEdit.cpp GUI/TextEdit.cpp
GUI/Window.cpp GUI/Window.cpp
GUI/WorldMapControl.cpp GUI/WorldMapControl.cpp
RNG/RNG_SFMT.cpp
RNG/sfmt/SFMT.c
Scriptable/Actor.cpp Scriptable/Actor.cpp
Scriptable/CombatInfo.cpp Scriptable/CombatInfo.cpp
Scriptable/Container.cpp Scriptable/Container.cpp
Expand Down
5 changes: 3 additions & 2 deletions gemrb/core/CharAnimations.cpp
Expand Up @@ -30,6 +30,7 @@
#include "Interface.h" #include "Interface.h"
#include "Map.h" #include "Map.h"
#include "Palette.h" #include "Palette.h"
#include "RNG/RNG_SFMT.h"


namespace GemRB { namespace GemRB {


Expand Down Expand Up @@ -1406,7 +1407,7 @@ void CharAnimations::AddPSTSuffix(char* ResRef, unsigned char StanceID,
Prefix="wlk"; break; Prefix="wlk"; break;
case IE_ANI_HEAD_TURN: case IE_ANI_HEAD_TURN:
Cycle=SixteenToFive[Orient]; Cycle=SixteenToFive[Orient];
if (rand()&1) { if (RAND(0,1)) {
Prefix="sf2"; Prefix="sf2";
sprintf(ResRef,"%c%3s%4s",this->ResRef[0], Prefix, this->ResRef+1); sprintf(ResRef,"%c%3s%4s",this->ResRef[0], Prefix, this->ResRef+1);
if (gamedata->Exists(ResRef, IE_BAM_CLASS_ID) ) { if (gamedata->Exists(ResRef, IE_BAM_CLASS_ID) ) {
Expand Down Expand Up @@ -1792,7 +1793,7 @@ void CharAnimations::AddVHRSuffix(char* ResRef, unsigned char StanceID,
break; break;


case IE_ANI_HEAD_TURN: case IE_ANI_HEAD_TURN:
if (rand()&1) { if (RAND(0,1)) {
strcat( ResRef, "g12" ); strcat( ResRef, "g12" );
Cycle += 18; Cycle += 18;
} else { } else {
Expand Down
8 changes: 6 additions & 2 deletions gemrb/core/ControlAnimation.cpp
Expand Up @@ -27,6 +27,7 @@
#include "GlobalTimer.h" #include "GlobalTimer.h"
#include "Interface.h" #include "Interface.h"
#include "GUI/Button.h" #include "GUI/Button.h"
#include "RNG/RNG_SFMT.h"


namespace GemRB { namespace GemRB {


Expand Down Expand Up @@ -88,11 +89,14 @@ void ControlAnimation::UpdateAnimation(bool paused)
if (anim_phase == 0) { if (anim_phase == 0) {
frame = 0; frame = 0;
anim_phase = 1; anim_phase = 1;
time = 500 + 500 * (rand() % 20); // note: the granularity of time should be
// one of twenty values from [500, 10000]
// but not the full range.
time = 500 + 500 * RAND(0, 19);
cycle&=~1; cycle&=~1;
Cycle=cycle; Cycle=cycle;
} else if (anim_phase == 1) { } else if (anim_phase == 1) {
if (rand() % 30 == 0) { if (!RAND(0,29)) {
cycle|=1; cycle|=1;
Cycle=cycle; Cycle=cycle;
} }
Expand Down
3 changes: 2 additions & 1 deletion gemrb/core/Dialog.cpp
Expand Up @@ -23,6 +23,7 @@
#include "win32def.h" #include "win32def.h"


#include "GameScript/GameScript.h" #include "GameScript/GameScript.h"
#include "RNG/RNG_SFMT.h"


namespace GemRB { namespace GemRB {


Expand Down Expand Up @@ -85,7 +86,7 @@ int Dialog::FindRandomState(Scriptable* target)
unsigned int i; unsigned int i;
unsigned int max = TopLevelCount; unsigned int max = TopLevelCount;
if (!max) return -1; if (!max) return -1;
unsigned int pick = rand()%max; unsigned int pick = RAND(0, max-1);
for (i=pick; i < max; i++) { for (i=pick; i < max; i++) {
Condition *cond = GetState(i)->condition; Condition *cond = GetState(i)->condition;
if (cond && cond->Evaluate(target)) { if (cond && cond->Evaluate(target)) {
Expand Down
5 changes: 3 additions & 2 deletions gemrb/core/GUI/GameControl.cpp
Expand Up @@ -41,6 +41,7 @@
#include "GUI/EventMgr.h" #include "GUI/EventMgr.h"
#include "GUI/TextArea.h" #include "GUI/TextArea.h"
#include "GUI/Window.h" #include "GUI/Window.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Container.h" #include "Scriptable/Container.h"
#include "Scriptable/Door.h" #include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h" #include "Scriptable/InfoPoint.h"
Expand Down Expand Up @@ -839,7 +840,7 @@ bool GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
Actor *target; Actor *target;
int i = game->GetPartySize(true); int i = game->GetPartySize(true);
if(i<2) break; if(i<2) break;
i=rand()%i; i=RAND(0, i-1);
do do
{ {
target = game->GetPC(i, true); target = game->GetPC(i, true);
Expand Down Expand Up @@ -972,7 +973,7 @@ bool GameControl::OnKeyRelease(unsigned char Key, unsigned short Mod)
core->GetDictionary()->DebugDump(); core->GetDictionary()->DebugDump();
break; break;
case 'v': //marks some of the map visited (random vision distance) case 'v': //marks some of the map visited (random vision distance)
area->ExploreMapChunk( p, rand()%30, 1 ); area->ExploreMapChunk( p, RAND(0,29), 1 );
break; break;
case 'w': // consolidates found ground piles under the pointed pc case 'w': // consolidates found ground piles under the pointed pc
area->MoveVisibleGroundPiles(p); area->MoveVisibleGroundPiles(p);
Expand Down
13 changes: 7 additions & 6 deletions gemrb/core/GameScript/Actions.cpp
Expand Up @@ -44,6 +44,7 @@
#include "WorldMap.h" #include "WorldMap.h"
#include "GUI/GameControl.h" #include "GUI/GameControl.h"
#include "GUI/EventMgr.h" #include "GUI/EventMgr.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Container.h" #include "Scriptable/Container.h"
#include "Scriptable/Door.h" #include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h" #include "Scriptable/InfoPoint.h"
Expand Down Expand Up @@ -988,7 +989,7 @@ void GameScript::WaitRandom(Scriptable* Sender, Action* parameters)
if (width<2) { if (width<2) {
width = parameters->int0Parameter; width = parameters->int0Parameter;
} else { } else {
width = rand() % width + parameters->int0Parameter; width = RAND(0, width-1) + parameters->int0Parameter;
} }
Sender->CurrentActionState = width * AI_UPDATE_TIME; Sender->CurrentActionState = width * AI_UPDATE_TIME;
} else { } else {
Expand Down Expand Up @@ -1041,7 +1042,7 @@ void GameScript::SmallWaitRandom(Scriptable* Sender, Action* parameters)
if (random<1) { if (random<1) {
random = 1; random = 1;
} }
Sender->CurrentActionState = rand() % random + parameters->int0Parameter; Sender->CurrentActionState = RAND(0, random-1) + parameters->int0Parameter;
} else { } else {
Sender->CurrentActionState--; Sender->CurrentActionState--;
} }
Expand Down Expand Up @@ -1679,7 +1680,7 @@ void GameScript::FloatMessageFixedRnd(Scriptable* Sender, Action* parameters)
Log(ERROR, "GameScript", "Cannot display resource!"); Log(ERROR, "GameScript", "Cannot display resource!");
return; return;
} }
DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD); DisplayStringCore(target, rndstr->at(RAND(0, rndstr->size()-1)), DS_CONSOLE|DS_HEAD);
FreeSrc(rndstr, parameters->string0Parameter); FreeSrc(rndstr, parameters->string0Parameter);
} }


Expand All @@ -1696,7 +1697,7 @@ void GameScript::FloatMessageRnd(Scriptable* Sender, Action* parameters)
Log(ERROR, "GameScript", "Cannot display resource!"); Log(ERROR, "GameScript", "Cannot display resource!");
return; return;
} }
DisplayStringCore(target, rndstr->at(rand()%rndstr->size()), DS_CONSOLE|DS_HEAD); DisplayStringCore(target, rndstr->at(RAND(0, rndstr->size()-1)), DS_CONSOLE|DS_HEAD);
FreeSrc(rndstr, parameters->string0Parameter); FreeSrc(rndstr, parameters->string0Parameter);
} }


Expand Down Expand Up @@ -5395,7 +5396,7 @@ void GameScript::RandomFly(Scriptable* Sender, Action* /*parameters*/)
return; return;
} }
Actor* actor = ( Actor* ) Sender; Actor* actor = ( Actor* ) Sender;
int x = rand()&31; int x = RAND(0,31);
if (x<10) { if (x<10) {
actor->SetOrientation(actor->GetOrientation()-1, false); actor->SetOrientation(actor->GetOrientation()-1, false);
} else if (x>20) { } else if (x>20) {
Expand Down Expand Up @@ -5646,7 +5647,7 @@ void GameScript::RandomTurn(Scriptable* Sender, Action* /*parameters*/)
return; return;
} }
Actor *actor = (Actor *) Sender; Actor *actor = (Actor *) Sender;
actor->SetOrientation(rand() % MAX_ORIENT, true); actor->SetOrientation(RAND(0, MAX_ORIENT-1), true);
actor->SetWait( 1 ); actor->SetWait( 1 );
Sender->ReleaseCurrentAction(); // todo, blocking? Sender->ReleaseCurrentAction(); // todo, blocking?
} }
Expand Down
3 changes: 2 additions & 1 deletion gemrb/core/GameScript/GSUtils.cpp
Expand Up @@ -44,6 +44,7 @@
#include "Video.h" #include "Video.h"
#include "WorldMap.h" #include "WorldMap.h"
#include "GUI/GameControl.h" #include "GUI/GameControl.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Container.h" #include "Scriptable/Container.h"
#include "Scriptable/Door.h" #include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h" #include "Scriptable/InfoPoint.h"
Expand Down Expand Up @@ -2479,7 +2480,7 @@ void SetupWishCore(Scriptable *Sender, int column, int picks)
} }
} else { } else {
for(i=0;i<picks;i++) { for(i=0;i<picks;i++) {
selects[i]=rand()%count; selects[i]=RAND(0, count-1);
retry: retry:
for(j=0;j<i;j++) { for(j=0;j<i;j++) {
if(selects[i]==selects[j]) { if(selects[i]==selects[j]) {
Expand Down
5 changes: 3 additions & 2 deletions gemrb/core/GameScript/GameScript.cpp
Expand Up @@ -30,6 +30,7 @@
#include "Interface.h" #include "Interface.h"
#include "PluginMgr.h" #include "PluginMgr.h"
#include "TableMgr.h" #include "TableMgr.h"
#include "RNG/RNG_SFMT.h"
#include "System/StringBuffer.h" #include "System/StringBuffer.h"


namespace GemRB { namespace GemRB {
Expand Down Expand Up @@ -1952,7 +1953,7 @@ bool GameScript::Update(bool *continuing, bool *done)
bool continueExecution = false; bool continueExecution = false;
if (continuing) continueExecution = *continuing; if (continuing) continueExecution = *continuing;


RandomNumValue=rand(); RandomNumValue=RNG_SFMT::getInstance()->rand();
for (size_t a = 0; a < script->responseBlocks.size(); a++) { for (size_t a = 0; a < script->responseBlocks.size(); a++) {
ResponseBlock* rB = script->responseBlocks[a]; ResponseBlock* rB = script->responseBlocks[a];
if (rB->condition->Evaluate(MySelf)) { if (rB->condition->Evaluate(MySelf)) {
Expand Down Expand Up @@ -2258,7 +2259,7 @@ int ResponseSet::Execute(Scriptable* Sender)
maxWeight += responses[i]->weight; maxWeight += responses[i]->weight;
} }
if (maxWeight) { if (maxWeight) {
randWeight = rand() % maxWeight; randWeight = RAND(0, maxWeight-1);
} }
else { else {
randWeight = 0; randWeight = 0;
Expand Down
5 changes: 3 additions & 2 deletions gemrb/core/GlobalTimer.cpp
Expand Up @@ -25,6 +25,7 @@
#include "Interface.h" #include "Interface.h"
#include "Video.h" #include "Video.h"
#include "GUI/GameControl.h" #include "GUI/GameControl.h"
#include "RNG/RNG_SFMT.h"


namespace GemRB { namespace GemRB {


Expand Down Expand Up @@ -139,10 +140,10 @@ void GlobalTimer::DoStep(int count)
} }
if (shakeCounter) { if (shakeCounter) {
if (shakeX) { if (shakeX) {
x += rand()%shakeX; x += RAND(0, shakeX-1);
} }
if (shakeY) { if (shakeY) {
y += rand()%shakeY; y += RAND(0, shakeY-1);
} }
} }
} }
Expand Down
9 changes: 2 additions & 7 deletions gemrb/core/Interface.cpp
Expand Up @@ -81,6 +81,7 @@
#include "GUI/TextArea.h" #include "GUI/TextArea.h"
#include "GUI/Window.h" #include "GUI/Window.h"
#include "GUI/WorldMapControl.h" #include "GUI/WorldMapControl.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Container.h" #include "Scriptable/Container.h"
#include "System/FileStream.h" #include "System/FileStream.h"
#include "System/VFS.h" #include "System/VFS.h"
Expand All @@ -90,8 +91,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif


#include <cstdlib>
#include <time.h>
#include <vector> #include <vector>


namespace GemRB { namespace GemRB {
Expand Down Expand Up @@ -1658,10 +1657,6 @@ int Interface::Init(InterfaceConfig* config)
} }
plugin->RunInitializers(); plugin->RunInitializers();


time_t t;
t = time( NULL );
srand( ( unsigned int ) t );

Log(MESSAGE, "Core", "GemRB Core Initialization..."); Log(MESSAGE, "Core", "GemRB Core Initialization...");
Log(MESSAGE, "Core", "Initializing Video Driver..."); Log(MESSAGE, "Core", "Initializing Video Driver...");
video = ( Video * ) PluginMgr::Get()->GetDriver(&Video::ID, VideoDriverName.c_str()); video = ( Video * ) PluginMgr::Get()->GetDriver(&Video::ID, VideoDriverName.c_str());
Expand Down Expand Up @@ -3678,7 +3673,7 @@ int Interface::Roll(int dice, int size, int add) const
return add + dice * size / 2; return add + dice * size / 2;
} }
for (int i = 0; i < dice; i++) { for (int i = 0; i < dice; i++) {
add += rand() % size + 1; add += RAND(1, size);
} }
return add; return add;
} }
Expand Down
11 changes: 6 additions & 5 deletions gemrb/core/Map.cpp
Expand Up @@ -51,6 +51,7 @@
#include "GameScript/GSUtils.h" #include "GameScript/GSUtils.h"
#include "GUI/GameControl.h" #include "GUI/GameControl.h"
#include "GUI/Window.h" #include "GUI/Window.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Container.h" #include "Scriptable/Container.h"
#include "Scriptable/Door.h" #include "Scriptable/Door.h"
#include "Scriptable/InfoPoint.h" #include "Scriptable/InfoPoint.h"
Expand Down Expand Up @@ -2411,7 +2412,7 @@ void Map::AdjustPosition(Point &goal, unsigned int radiusx, unsigned int radiusy


while(radiusx<Width || radiusy<Height) { while(radiusx<Width || radiusy<Height) {
//lets make it slightly random where the actor will appear //lets make it slightly random where the actor will appear
if (rand()&1) { if (RAND(0,1)) {
if (AdjustPositionX(goal, radiusx, radiusy)) { if (AdjustPositionX(goal, radiusx, radiusy)) {
return; return;
} }
Expand Down Expand Up @@ -3126,7 +3127,7 @@ void Map::TriggerSpawn(Spawn *spawn)


//check day or night chance //check day or night chance
bool day = core->GetGame()->IsDay(); bool day = core->GetGame()->IsDay();
int chance = rand() % 100; int chance = RAND(0, 99);
if ((day && chance > spawn->DayChance) || if ((day && chance > spawn->DayChance) ||
(!day && chance > spawn->NightChance)) { (!day && chance > spawn->NightChance)) {
spawn->NextSpawn = time + spawn->Frequency * AI_UPDATE_TIME * 60; spawn->NextSpawn = time + spawn->Frequency * AI_UPDATE_TIME * 60;
Expand All @@ -3135,7 +3136,7 @@ void Map::TriggerSpawn(Spawn *spawn)
} }
//create spawns //create spawns
int difficulty = spawn->Difficulty * core->GetGame()->GetPartyLevel(true); int difficulty = spawn->Difficulty * core->GetGame()->GetPartyLevel(true);
unsigned int spawncount = 0, i = rand() % spawn->Count; unsigned int spawncount = 0, i = RAND(0, spawn->Count-1);
while (difficulty >= 0 && spawncount < spawn->Maximum) { while (difficulty >= 0 && spawncount < spawn->Maximum) {
if (!SpawnCreature(spawn->Pos, spawn->Creatures[i], 0, 0, &difficulty, &spawncount)) { if (!SpawnCreature(spawn->Pos, spawn->Creatures[i], 0, 0, &difficulty, &spawncount)) {
break; break;
Expand Down Expand Up @@ -3192,13 +3193,13 @@ int Map::CheckRestInterruptsAndPassTime(const Point &pos, int hours, int day)


//based on ingame timer //based on ingame timer
int chance=day?RestHeader.DayChance:RestHeader.NightChance; int chance=day?RestHeader.DayChance:RestHeader.NightChance;
bool interrupt = rand()%100 < chance; bool interrupt = (int) RAND(0, 99) < chance;
unsigned int spawncount = 0; unsigned int spawncount = 0;
int spawnamount = core->GetGame()->GetPartyLevel(true) * RestHeader.Difficulty; int spawnamount = core->GetGame()->GetPartyLevel(true) * RestHeader.Difficulty;
if (spawnamount < 1) spawnamount = 1; if (spawnamount < 1) spawnamount = 1;
for (int i=0;i<hours;i++) { for (int i=0;i<hours;i++) {
if (interrupt) { if (interrupt) {
int idx = rand()%RestHeader.CreatureNum; int idx = RAND(0, RestHeader.CreatureNum-1);
Actor *creature = gamedata->GetCreature(RestHeader.CreResRef[idx]); Actor *creature = gamedata->GetCreature(RestHeader.CreResRef[idx]);
if (!creature) { if (!creature) {
core->GetGame()->AdvanceTime(300*AI_UPDATE_TIME); core->GetGame()->AdvanceTime(300*AI_UPDATE_TIME);
Expand Down
9 changes: 5 additions & 4 deletions gemrb/core/Projectile.cpp
Expand Up @@ -33,6 +33,7 @@
#include "Sprite2D.h" #include "Sprite2D.h"
#include "VEFObject.h" #include "VEFObject.h"
#include "Video.h" #include "Video.h"
#include "RNG/RNG_SFMT.h"
#include "Scriptable/Actor.h" #include "Scriptable/Actor.h"


#include <cmath> #include <cmath>
Expand Down Expand Up @@ -140,7 +141,7 @@ void Projectile::CreateAnimations(Animation **anims, const ieResRef bamres, int
} }


if((ExtFlags&PEF_CYCLE) && !Seq) { if((ExtFlags&PEF_CYCLE) && !Seq) {
Seq=rand()%Max; Seq=RAND(0, Max-1);
} }


//this hack is needed because bioware .pro files are sometimes //this hack is needed because bioware .pro files are sometimes
Expand Down Expand Up @@ -1478,7 +1479,7 @@ void Projectile::DrawExplosion(const Region &screen)
if (children[i]) if (children[i])
continue; continue;
if(apflags&APF_BOTH) { if(apflags&APF_BOTH) {
if(rand()&1) { if(RAND(0,1)) {
tmp = Extension->Secondary; tmp = Extension->Secondary;
} else { } else {
tmp = Extension->Spread; tmp = Extension->Spread;
Expand Down Expand Up @@ -1522,12 +1523,12 @@ void Projectile::DrawExplosion(const Region &screen)
//a bit of difference in case crowding is needed //a bit of difference in case crowding is needed
//make this a separate flag if speed difference //make this a separate flag if speed difference
//is not always wanted //is not always wanted
pro->Speed-=rand()&7; pro->Speed-=RAND(0,7);


delay = Extension->Delay*extension_explosioncount; delay = Extension->Delay*extension_explosioncount;
if(apflags&APF_BOTH) { if(apflags&APF_BOTH) {
if (delay) { if (delay) {
delay = rand()%delay; delay = RAND(0, delay-1);
} }
} }
//this needs to be commented out for ToB horrid wilting //this needs to be commented out for ToB horrid wilting
Expand Down

0 comments on commit 3a9b5cd

Please sign in to comment.