//------------------------------------------------------------------------------ bool CvDllGameContext::RandomNumberGeneratorSyncCheck(PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost) { // uh oh! Check the Random number generator! const CvRandom& localSimRandomNumberGenerator = GC.getGame().getJonRand(); CvRandom* pkRandom = GC.UnwrapRandomPointer(pRandom); if(localSimRandomNumberGenerator != *pkRandom) { FILogFile* logFile = LOGFILEMGR.GetLog("net_message_debug.log", 0); char formatBuf[128] = {"\0"}; std::string rngLogMessage = "Game Random Number Generators are out of sync : local.seed="; _i64toa_s(localSimRandomNumberGenerator.getSeed(), formatBuf, 127, 10); rngLogMessage += formatBuf; rngLogMessage += ", remote.seed="; _i64toa_s(pkRandom->getSeed(), formatBuf, 127, 10); rngLogMessage += formatBuf; rngLogMessage += "\n\tlocal.callCount="; _itoa_s(localSimRandomNumberGenerator.getCallCount(), formatBuf, 10); rngLogMessage += formatBuf; rngLogMessage += ", remote.callCount="; _itoa_s(pkRandom->getCallCount(), formatBuf, 10); rngLogMessage += formatBuf; rngLogMessage += "\n\tlocal.resetCount="; _itoa_s(localSimRandomNumberGenerator.getResetCount(), formatBuf, 10); rngLogMessage += formatBuf; rngLogMessage += ", remote.resetCount="; _itoa_s(pkRandom->getResetCount(), formatBuf, 10); rngLogMessage += formatBuf; rngLogMessage += "\n"; if(logFile) logFile->DebugMsg(rngLogMessage.c_str()); return false; } return true; }
int CvMapGenerator::getRiverValueAtPlot(CvPlot* pPlot) { CvPlot* pAdjacentPlot; CvRandom riverRand; int iSum; int iI; FAssert(pPlot != NULL); long result = 0; CyPlot kPlot = CyPlot(pPlot); CyArgsList argsList; argsList.add(gDLL->getPythonIFace()->makePythonObject(&kPlot)); if (gDLL->getPythonIFace()->callFunction(gDLL->getPythonIFace()->getMapScriptModule(), "getRiverAltitude", argsList.makeFunctionArgs(), &result)) { if (!gDLL->getPythonIFace()->pythonUsingDefaultImpl()) // Python override { if (result >= 0) { return result; } else { FAssertMsg(false, "python getRiverAltitude() must return >= 0"); } } } iSum = result; iSum += ((NUM_PLOT_TYPES - pPlot->getPlotType()) * 20); for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++) { pAdjacentPlot = plotDirection(pPlot->getX_INLINE(), pPlot->getY_INLINE(), ((DirectionTypes)iI)); if (pAdjacentPlot != NULL) { iSum += (NUM_PLOT_TYPES - pAdjacentPlot->getPlotType()); } else { iSum += (NUM_PLOT_TYPES * 10); } } riverRand.init((pPlot->getX_INLINE() * 43251267) + (pPlot->getY_INLINE() * 8273903)); iSum += (riverRand.get(10, "River Rand")); return iSum; }
void shuffleArray(int* piShuffle, int iNum, CvRandom& rand) { int iI, iJ; for(iI = 0; iI < iNum; iI++) { piShuffle[iI] = iI; } for(iI = 0; iI < iNum; iI++) { iJ = (rand.get(iNum - iI, NULL) + iI); if(iI != iJ) { int iTemp = piShuffle[iI]; piShuffle[iI] = piShuffle[iJ]; piShuffle[iJ] = iTemp; } } }
//------------------------------------------------------------------------------ bool CvDllGameContext::RandomNumberGeneratorSyncCheck(PlayerTypes ePlayer, ICvRandom1* pRandom, bool bIsHost) { // uh oh! Check the Random number generator! const CvRandom& localSimRandomNumberGenerator = GC.getGame().getJonRand(); CvRandom* pkRandom = GC.UnwrapRandomPointer(pRandom); if(localSimRandomNumberGenerator != *pkRandom) { FILogFile* logFile = LOGFILEMGR.GetLog("net_message_debug.log", 0); char formatBuf[128] = {"\0"}; std::string rngLogMessage = "Game Random Number Generators are out of sync : local.seed="; rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getSeed(), formatBuf, 10); rngLogMessage += ", remote.seed="; rngLogMessage += _itoa_s(pkRandom->getSeed(), formatBuf, 10); rngLogMessage += "\n\tlocal.callCount="; rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getCallCount(), formatBuf, 10); rngLogMessage += ", remote.callCount="; rngLogMessage += _itoa_s(pkRandom->getCallCount(), formatBuf, 10); rngLogMessage += "\n\tlocal.resetCount="; rngLogMessage += _itoa_s(localSimRandomNumberGenerator.getResetCount(), formatBuf, 10); rngLogMessage += ", remote.resetCount="; rngLogMessage += _itoa_s(pkRandom->getResetCount(), formatBuf, 10); rngLogMessage += "\n"; if(localSimRandomNumberGenerator.callStackDebuggingEnabled() && pkRandom->callStackDebuggingEnabled()) { std::string localCallStack(""); std::string remoteCallStack(""); localSimRandomNumberGenerator.resolveCallStacks(); const std::vector<std::string>& localCallStacks = localSimRandomNumberGenerator.getResolvedCallStacks(); const std::vector<std::string>& remoteCallStacks = pkRandom->getResolvedCallStacks(); const std::vector<unsigned long>& localSeedHistory = localSimRandomNumberGenerator.getSeedHistory(); const std::vector<unsigned long>& remoteSeedHistory = pkRandom->getSeedHistory(); std::vector<unsigned long>::const_iterator localSeedIterator = localSeedHistory.begin(); std::vector<unsigned long>::const_iterator remoteSeedIterator = remoteSeedHistory.begin(); unsigned int callNumber = 0; for(localSeedIterator = localSeedHistory.begin(), remoteSeedIterator = remoteSeedHistory.begin(); localSeedIterator != localSeedHistory.end() && remoteSeedIterator != remoteSeedHistory.end(); ++localSeedIterator, ++remoteSeedIterator, ++callNumber) { if(*localSeedIterator != *remoteSeedIterator) { if(callNumber < localCallStacks.size() && callNumber < remoteCallStacks.size()) { rngLogMessage += "At Call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += " random number seeds are different.\n"; if(callNumber > 0) { rngLogMessage += "Call #"; rngLogMessage += _itoa_s(callNumber - 1, formatBuf, 10); rngLogMessage += "\nLocal:\n"; rngLogMessage += localCallStacks[callNumber - 1]; rngLogMessage += "\nRemote:\n"; rngLogMessage += remoteCallStacks[callNumber - 1]; } rngLogMessage += "Call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\nLocal:\n"; rngLogMessage += localCallStacks[callNumber]; rngLogMessage += "\nRemote:\n"; rngLogMessage += remoteCallStacks[callNumber]; break; } } } if(localSeedIterator != localSeedHistory.end() && remoteSeedIterator == remoteSeedHistory.end()) { rngLogMessage += "\nLocal random number generator called more than remote at call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\n"; if(callNumber < localSeedHistory.size()) { rngLogMessage += "Local CallStack:\n"; rngLogMessage += localCallStacks[callNumber]; } } else if(remoteSeedIterator != remoteSeedHistory.end() && localSeedIterator == localSeedHistory.end()) { rngLogMessage += "\nremote random number generator called more than local at call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\n"; if(callNumber < remoteSeedHistory.size()) { rngLogMessage += "remote CallStack:\n"; rngLogMessage += remoteCallStacks[callNumber]; } } // find first different call std::vector<std::string>::const_iterator localCallStackIterator; std::vector<std::string>::const_iterator remoteCallStackIterator; for(localCallStackIterator = localCallStacks.begin(), remoteCallStackIterator = remoteCallStacks.begin(), callNumber = 0; localCallStackIterator != localCallStacks.end() && remoteCallStackIterator != remoteCallStacks.end(); ++localCallStackIterator, ++remoteCallStackIterator, ++callNumber) { if(*localCallStackIterator != *remoteCallStackIterator) { rngLogMessage += "\nFirst different callstack at call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\n"; rngLogMessage += "Local :\n"; rngLogMessage += *localCallStackIterator; rngLogMessage += "Remote :\n"; rngLogMessage += *remoteCallStackIterator; break; } } if(logFile) { logFile->DebugMsg(rngLogMessage.c_str()); } CvAssertMsg(false, rngLogMessage.c_str()); if(logFile) { rngLogMessage = "\nDebug dump:\n"; // add full history rngLogMessage += "Seed History -\n"; localSeedIterator = localSeedHistory.begin(); remoteSeedIterator = remoteSeedHistory.begin(); callNumber = 0; while(localSeedIterator != localSeedHistory.end() || remoteSeedIterator != remoteSeedHistory.end()) { ++callNumber; rngLogMessage += "\t Call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += " LOCAL="; if(localSeedIterator != localSeedHistory.end()) { rngLogMessage += _itoa_s(*localSeedIterator, formatBuf, 10); ++localSeedIterator; } rngLogMessage += "\tREMOTE="; if(remoteSeedIterator != remoteSeedHistory.end()) { rngLogMessage += _itoa_s(*remoteSeedIterator, formatBuf, 10); ++remoteSeedIterator; } rngLogMessage += "\n"; } rngLogMessage += "\nLocal callstack history\n"; callNumber = 0; std::string lastCallStackLogged; unsigned int repeatCount = 0; std::vector<std::string>::const_iterator i; for(i = localCallStacks.begin(); i != localCallStacks.end(); ++i) { if(lastCallStackLogged != *i) { if(repeatCount > 0) { rngLogMessage += "Last message repeated "; rngLogMessage += _itoa_s(repeatCount, formatBuf, 10); rngLogMessage += " times\n"; } rngLogMessage += "Call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\n"; rngLogMessage += *i; lastCallStackLogged = *i; repeatCount = 0; } else { repeatCount++; } ++callNumber; } rngLogMessage += "\nRemote callstack history\n"; callNumber = 0; repeatCount = 0; for(i = remoteCallStacks.begin(); i != remoteCallStacks.end(); ++i) { if(lastCallStackLogged != *i) { if(repeatCount > 0) { rngLogMessage += "Last message repeated "; rngLogMessage += _itoa_s(repeatCount, formatBuf, 10); rngLogMessage += " times\n"; } rngLogMessage += "Call #"; rngLogMessage += _itoa_s(callNumber, formatBuf, 10); rngLogMessage += "\n"; rngLogMessage += *i; lastCallStackLogged = *i; repeatCount = 0; } else { repeatCount++; } ++callNumber; } logFile->DebugMsg(rngLogMessage.c_str()); } } else { if(logFile) { logFile->DebugMsg(rngLogMessage.c_str()); } CvAssertMsg(false, rngLogMessage.c_str()); } /* If this point has been reached, the OOS may be nearly unrecoverable // attempt to recover if(m_isHost) { CvRandom & rng = auto_ptr<ICvGame1> pGame = GameCore::GetGame();\n.getJonRand(); rng.reset(m_simRandomNumberGenerator.getSeed()); } // brute force approach // JAR : todo - this is the solution of last resort if // loadDelta() doesn't work out */ return false; } return true; }