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; g_GameAttributes.settings.PlayerData[player.player - 1].Name = player.name;
} }
// This seed is only used for map-generation // Seed used for both map generation and simulation
if (g_GameAttributes.mapType == "random") g_GameAttributes.settings.Seed = Math.floor(Math.random() * Math.pow(2, 32));
g_GameAttributes.settings.Seed = Math.floor(Math.random() * 65536); g_GameAttributes.settings.AISeed = Math.floor(Math.random() * Math.pow(2, 32));
g_GameAttributes.settings.AISeed = Math.floor(Math.random() * 65536);
// Used for identifying rated game reports for the lobby // Used for identifying rated game reports for the lobby
g_GameAttributes.matchID = Engine.GetMatchID(); g_GameAttributes.matchID = Engine.GetMatchID();

View file

@ -752,6 +752,12 @@ void CSimulation2::SetMapSettings(const std::string& settings)
void CSimulation2::SetMapSettings(JS::HandleValue settings) void CSimulation2::SetMapSettings(JS::HandleValue settings)
{ {
m->m_MapSettings = 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() std::string CSimulation2::GetMapSettingsString()

View file

@ -108,12 +108,14 @@ public:
/** /**
* Set the initial map settings (as a UTF-8-encoded JSON string), * Set the initial map settings (as a UTF-8-encoded JSON string),
* which will be used to set up the simulation state. * which will be used to set up the simulation state.
* Called from atlas.
*/ */
void SetMapSettings(const std::string& settings); void SetMapSettings(const std::string& settings);
/** /**
* Set the initial map settings, which will be used * Set the initial map settings, which will be used
* to set up the simulation state. * to set up the simulation state.
* Called from MapReader (for all map-types).
*/ */
void SetMapSettings(JS::HandleValue settings); 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. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 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); context.SetComponentManager(this);
m_ScriptInterface.SetCallbackData(static_cast<void*> (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.ReplaceNondeterministicRNG(m_RNG);
m_ScriptInterface.LoadGlobalScripts(); m_ScriptInterface.LoadGlobalScripts();
@ -540,6 +538,11 @@ void CComponentManager::ResetState()
m_NextLocalEntityId = FIRST_LOCAL_ENTITY; 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, void CComponentManager::RegisterComponentType(InterfaceId iid, ComponentTypeId cid, AllocFunc alloc, DeallocFunc dealloc,
const char* name, const std::string& schema) 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. * This file is part of 0 A.D.
* *
* 0 A.D. is free software: you can redistribute it and/or modify * 0 A.D. is free software: you can redistribute it and/or modify
@ -295,6 +295,11 @@ public:
*/ */
void ResetState(); void ResetState();
/**
* Initializes the random number generator with a seed determined by the host.
*/
void SetRNGSeed(u32 seed);
// Various state serialization functions: // Various state serialization functions:
bool ComputeStateHash(std::string& outHash, bool quick); bool ComputeStateHash(std::string& outHash, bool quick);
bool DumpDebugState(std::ostream& stream, bool includeDebugInfo); bool DumpDebugState(std::ostream& stream, bool includeDebugInfo);

View file

@ -96,6 +96,32 @@ public:
TS_ASSERT_EQUALS(man.AllocateNewLocalEntity(), (u32)FIRST_LOCAL_ENTITY); 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() void test_AddComponent_errors()
{ {
CSimContext context; CSimContext context;