1
0
forked from 0ad/0ad

Actually seed the random number generator used in the simulation. Reviewed by sanderd17, fixes #4127.

This was SVN commit r18604.
This commit is contained in:
elexis 2016-08-14 16:28:54 +00:00
parent 00a469be1b
commit 6eaf76d653
6 changed files with 49 additions and 9 deletions

View File

@ -1282,11 +1282,9 @@ function launchGame()
g_GameAttributes.settings.PlayerData[player.player - 1].Name = player.name;
}
// This seed is only used for map-generation
if (g_GameAttributes.mapType == "random")
g_GameAttributes.settings.Seed = Math.floor(Math.random() * 65536);
g_GameAttributes.settings.AISeed = Math.floor(Math.random() * 65536);
// Seed used for both map generation and simulation
g_GameAttributes.settings.Seed = Math.floor(Math.random() * Math.pow(2, 32));
g_GameAttributes.settings.AISeed = Math.floor(Math.random() * Math.pow(2, 32));
// Used for identifying rated game reports for the lobby
g_GameAttributes.matchID = Engine.GetMatchID();

View File

@ -752,6 +752,12 @@ void CSimulation2::SetMapSettings(const std::string& settings)
void CSimulation2::SetMapSettings(JS::HandleValue settings)
{
m->m_MapSettings = settings;
u32 seed = 0;
if (!m->m_ComponentManager.GetScriptInterface().GetProperty(m->m_MapSettings, "Seed", seed))
LOGWARNING("CSimulation2::SetInitAttributes: No seed value specified - using %d", seed);
m->m_ComponentManager.SetRNGSeed(seed);
}
std::string CSimulation2::GetMapSettingsString()

View File

@ -108,12 +108,14 @@ public:
/**
* Set the initial map settings (as a UTF-8-encoded JSON string),
* which will be used to set up the simulation state.
* Called from atlas.
*/
void SetMapSettings(const std::string& settings);
/**
* Set the initial map settings, which will be used
* to set up the simulation state.
* Called from MapReader (for all map-types).
*/
void SetMapSettings(JS::HandleValue settings);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015 Wildfire Games.
/* Copyright (C) 2016 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -61,8 +61,6 @@ CComponentManager::CComponentManager(CSimContext& context, shared_ptr<ScriptRunt
context.SetComponentManager(this);
m_ScriptInterface.SetCallbackData(static_cast<void*> (this));
// TODO: ought to seed the RNG (in a network-synchronised way) before we use it
m_ScriptInterface.ReplaceNondeterministicRNG(m_RNG);
m_ScriptInterface.LoadGlobalScripts();
@ -540,6 +538,11 @@ void CComponentManager::ResetState()
m_NextLocalEntityId = FIRST_LOCAL_ENTITY;
}
void CComponentManager::SetRNGSeed(u32 seed)
{
m_RNG.seed(seed);
}
void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
const char* name, const std::string& schema)
{

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2015 Wildfire Games.
/* Copyright (C) 2016 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -295,6 +295,11 @@ public:
*/
void ResetState();
/**
* Initializes the random number generator with a seed determined by the host.
*/
void SetRNGSeed(u32 seed);
// Various state serialization functions:
bool ComputeStateHash(std::string& outHash, bool quick);
bool DumpDebugState(std::ostream& stream, bool includeDebugInfo);

View File

@ -96,6 +96,32 @@ public:
TS_ASSERT_EQUALS(man.AllocateNewLocalEntity(), (u32)FIRST_LOCAL_ENTITY);
}
void test_rng()
{
// Ensure we get the same random number with the same seed
double first;
{
CSimContext context;
CComponentManager man(context, g_ScriptRuntime);
man.SetRNGSeed(123);
if (!man.m_ScriptInterface.MathRandom(first))
TS_FAIL("Couldn't get random number!");
}
double second;
{
CSimContext context;
CComponentManager man(context, g_ScriptRuntime);
man.SetRNGSeed(123);
if (!man.m_ScriptInterface.MathRandom(second))
TS_FAIL("Couldn't get random number!");
}
TS_ASSERT_EQUALS(first, second);
}
void test_AddComponent_errors()
{
CSimContext context;