From f88ee2766e6e756dcebb477fdda8cb248952f8c7 Mon Sep 17 00:00:00 2001 From: mimo Date: Sun, 16 Nov 2014 19:53:29 +0000 Subject: [PATCH] use by default a random seed for the AI to make it less repetitive This was SVN commit r15973. --- .../mods/public/gui/gamesetup/gamesetup.js | 3 ++ .../public/simulation/helpers/InitGame.js | 2 ++ binaries/system/readme.txt | 23 ++++++------ source/ps/GameSetup/GameSetup.cpp | 35 +++++++++++++------ .../simulation2/components/CCmpAIManager.cpp | 11 +++++- .../simulation2/components/ICmpAIManager.cpp | 1 + source/simulation2/components/ICmpAIManager.h | 1 + 7 files changed, 53 insertions(+), 23 deletions(-) diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index b5afbf2df4..9e0746633d 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -806,6 +806,7 @@ function selectMapType(type) // TODO: This should be remembered from the last session g_GameAttributes.mapPath = "maps/scenarios/"; g_GameAttributes.map = g_GameAttributes.mapPath + (g_IsNetworked ? DEFAULT_NETWORKED_MAP : DEFAULT_OFFLINE_MAP); + g_GameAttributes.settings.AISeed = Math.floor(Math.random() * 65536); break; case "skirmish": @@ -813,6 +814,7 @@ function selectMapType(type) g_GameAttributes.settings = { PlayerData: g_DefaultPlayerData.slice(0, 4), Seed: Math.floor(Math.random() * 65536), + AISeed: Math.floor(Math.random() * 65536), CheatsEnabled: g_GameAttributes.settings.CheatsEnabled }; break; @@ -822,6 +824,7 @@ function selectMapType(type) g_GameAttributes.settings = { PlayerData: g_DefaultPlayerData.slice(0, 4), Seed: Math.floor(Math.random() * 65536), + AISeed: Math.floor(Math.random() * 65536), CheatsEnabled: g_GameAttributes.settings.CheatsEnabled }; break; diff --git a/binaries/data/mods/public/simulation/helpers/InitGame.js b/binaries/data/mods/public/simulation/helpers/InitGame.js index 3c9d45992a..74fae08108 100644 --- a/binaries/data/mods/public/simulation/helpers/InitGame.js +++ b/binaries/data/mods/public/simulation/helpers/InitGame.js @@ -51,6 +51,8 @@ function InitGame(settings) cmpPlayer.SetResourceCounts(newResourceCounts); } } + let seed = settings.AISeed ? settings.AISeed : 0; + cmpAIManager.SetRNGSeed(seed); cmpAIManager.TryLoadSharedComponent(); cmpAIManager.RunGamestateInit(); } diff --git a/binaries/system/readme.txt b/binaries/system/readme.txt index cd8b6e0862..a55b7bbd79 100644 --- a/binaries/system/readme.txt +++ b/binaries/system/readme.txt @@ -7,19 +7,20 @@ Basic gameplay: -quickstart load faster (disables audio and some system info logging) Autostart: --autostart="TYPEDIR/MAPNAME" enables autostart and sets MAPNAME; TYPEDIR is skirmishes, scenarios, or random --autostart-ai=PLAYER:AI sets the AI for PLAYER (e.g. 2:petra) --autostart-aidiff=PLAYER:DIFF sets the DIFFiculty of PLAYER's AI (0: easy, 3: very hard) --autostart-civ=PLAYER:CIV sets PLAYER's civilisation to CIV (skirmish and random maps only) +-autostart="TYPEDIR/MAPNAME" enables autostart and sets MAPNAME; TYPEDIR is skirmishes, scenarios, or random +-autostart-ai=PLAYER:AI sets the AI for PLAYER (e.g. 2:petra) +-autostart-aidiff=PLAYER:DIFF sets the DIFFiculty of PLAYER's AI (0: sandbox, 4: very hard) +-autostart-civ=PLAYER:CIV sets PLAYER's civilisation to CIV (skirmish and random maps only) +-autostart-aiseed=AISEED sets the seed used for the AI random generator (default 0, use -1 for random) Multiplayer: --autostart-playername=NAME sets local player NAME (default 'anonymous') --autostart-host sets multiplayer host mode --autostart-host-players=NUMBER sets NUMBER of human players for multiplayer game (default 2) --autostart-client=IP sets multiplayer client to join host at given IP address +-autostart-playername=NAME sets local player NAME (default 'anonymous') +-autostart-host sets multiplayer host mode +-autostart-host-players=NUMBER sets NUMBER of human players for multiplayer game (default 2) +-autostart-client=IP sets multiplayer client to join host at given IP address Random maps only: --autostart-seed=SEED sets random map SEED value (default 0, use -1 for random) --autostart-size=TILES sets random map size in TILES (default 192) --autostart-players=NUMBER sets NUMBER of players on random map (default 2) +-autostart-seed=SEED sets random map SEED value (default 0, use -1 for random) +-autostart-size=TILES sets random map size in TILES (default 192) +-autostart-players=NUMBER sets NUMBER of players on random map (default 2) Examples: 1) "Bob" will host a 2 player game on the Arcadia map: diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 7933621a3e..1915b41cea 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -1161,19 +1161,20 @@ CStr8 LoadSettingsOfScenarioMap(const VfsPath &mapPath) /* * Command line options for autostart (keep synchronized with readme.txt): * - * -autostart="TYPEDIR/MAPNAME" enables autostart and sets MAPNAME; TYPEDIR is skirmishes, scenarios, or random - * -autostart-ai=PLAYER:AI sets the AI for PLAYER (e.g. 2:petra) - * -autostart-aidiff=PLAYER:DIFF sets the DIFFiculty of PLAYER's AI (0: easy, 3: very hard) - * -autostart-civ=PLAYER:CIV sets PLAYER's civilisation to CIV (skirmish and random maps only) + * -autostart="TYPEDIR/MAPNAME" enables autostart and sets MAPNAME; TYPEDIR is skirmishes, scenarios, or random + * -autostart-ai=PLAYER:AI sets the AI for PLAYER (e.g. 2:petra) + * -autostart-aidiff=PLAYER:DIFF sets the DIFFiculty of PLAYER's AI (0: sandbox, 4: very hard) + * -autostart-civ=PLAYER:CIV sets PLAYER's civilisation to CIV (skirmish and random maps only) + * -autostart-aiseed=AISEED sets the seed used for the AI random generator (default 0, use -1 for random) * Multiplayer: * -autostart-playername=NAME sets local player NAME (default 'anonymous') - * -autostart-host sets multiplayer host mode - * -autostart-host-players=NUMBER sets NUMBER of human players for multiplayer game (default 2) - * -autostart-client=IP sets multiplayer client to join host at given IP address + * -autostart-host sets multiplayer host mode + * -autostart-host-players=NUMBER sets NUMBER of human players for multiplayer game (default 2) + * -autostart-client=IP sets multiplayer client to join host at given IP address * Random maps only: - * -autostart-seed=SEED sets random map SEED value (default 0, use -1 for random) - * -autostart-size=TILES sets random map size in TILES (default 192) - * -autostart-players=NUMBER sets NUMBER of players on random map (default 2) + * -autostart-seed=SEED sets random map SEED value (default 0, use -1 for random) + * -autostart-size=TILES sets random map size in TILES (default 192) + * -autostart-players=NUMBER sets NUMBER of players on random map (default 2) * * Examples: * 1) "Bob" will host a 2 player game on the Arcadia map: @@ -1225,7 +1226,7 @@ bool Autostart(const CmdLineArgs& args) if (!seedArg.empty()) { // Random seed value - if (seedArg != "-1") + if (seedArg == "-1") seed = rand(); else seed = seedArg.ToULong(); @@ -1307,6 +1308,18 @@ bool Autostart(const CmdLineArgs& args) scriptInterface.SetProperty(attrs, "map", std::string("maps/" + autoStartName)); scriptInterface.SetProperty(settings, "mapType", mapType); + // Set seed for AIs + u32 aiseed = 0; + if (args.Has("autostart-aiseed")) + { + CStr seedArg = args.Get("autostart-aiseed"); + if (seedArg == "-1") + aiseed = rand(); + else + aiseed = seedArg.ToULong(); + } + scriptInterface.SetProperty(settings, "AISeed", aiseed); + // Set player data for AIs // attrs.settings = { PlayerData: [ { AI: ... }, ... ] }: if (args.Has("autostart-ai")) diff --git a/source/simulation2/components/CCmpAIManager.cpp b/source/simulation2/components/CCmpAIManager.cpp index 729fd357fd..95c0d760de 100644 --- a/source/simulation2/components/CCmpAIManager.cpp +++ b/source/simulation2/components/CCmpAIManager.cpp @@ -225,7 +225,6 @@ public: m_HasSharedComponent(false) { - // TODO: ought to seed the RNG (in a network-synchronised way) before we use it m_ScriptInterface->ReplaceNondeterministicRNG(m_RNG); m_ScriptInterface->LoadGlobalScripts(); @@ -361,6 +360,11 @@ public: tex_write(&t, filename); } + void SetRNGSeed(uint32_t seed) + { + m_RNG.seed(seed); + } + bool TryLoadSharedComponent(bool hasTechs) { JSContext* cx = m_ScriptInterface->GetContext(); @@ -917,6 +921,11 @@ public: cmpRangeManager->SetLosRevealAll(player, true); } + virtual void SetRNGSeed(uint32_t seed) + { + m_Worker.SetRNGSeed(seed); + } + virtual void TryLoadSharedComponent() { ScriptInterface& scriptInterface = GetSimContext().GetScriptInterface(); diff --git a/source/simulation2/components/ICmpAIManager.cpp b/source/simulation2/components/ICmpAIManager.cpp index 5e88257c8c..919eb4eb13 100644 --- a/source/simulation2/components/ICmpAIManager.cpp +++ b/source/simulation2/components/ICmpAIManager.cpp @@ -26,6 +26,7 @@ BEGIN_INTERFACE_WRAPPER(AIManager) DEFINE_INTERFACE_METHOD_3("AddPlayer", void, ICmpAIManager, AddPlayer, std::wstring, player_id_t, uint8_t) +DEFINE_INTERFACE_METHOD_1("SetRNGSeed", void, ICmpAIManager, SetRNGSeed, uint32_t) DEFINE_INTERFACE_METHOD_0("TryLoadSharedComponent", void, ICmpAIManager, TryLoadSharedComponent) DEFINE_INTERFACE_METHOD_0("RunGamestateInit", void, ICmpAIManager, RunGamestateInit) END_INTERFACE_WRAPPER(AIManager) diff --git a/source/simulation2/components/ICmpAIManager.h b/source/simulation2/components/ICmpAIManager.h index 9e81f2e334..bd3e04e6fa 100644 --- a/source/simulation2/components/ICmpAIManager.h +++ b/source/simulation2/components/ICmpAIManager.h @@ -31,6 +31,7 @@ public: * to control player @p player. */ virtual void AddPlayer(std::wstring id, player_id_t player, uint8_t difficulty) = 0; + virtual void SetRNGSeed(uint32_t seed) = 0; virtual void TryLoadSharedComponent() = 0; virtual void RunGamestateInit() = 0;