/// Log GrandStrategy state: what are the Priorities and who is Active? void CvGrandStrategyAI::LogGrandStrategies(const FStaticVector< int, 5, true, c_eCiv5GameplayDLL >& vModifiedGrandStrategyPriorities) { if(GC.getLogging() && GC.getAILogging()) { CvString strOutBuf; CvString strBaseString; CvString strTemp; CvString playerName; CvString strDesc; CvString strLogName; // Find the name of this civ and city playerName = GetPlayer()->getCivilizationShortDescription(); // Open the log file if(GC.getPlayerAndCityAILogSplit()) { strLogName = "GrandStrategyAI_Log_" + playerName + ".csv"; } else { strLogName = "GrandStrategyAI_Log.csv"; } FILogFile* pLog; pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp); AIGrandStrategyTypes eGrandStrategy; // Loop through Grand Strategies for(int iGrandStrategyLoop = 0; iGrandStrategyLoop < GC.getNumAIGrandStrategyInfos(); iGrandStrategyLoop++) { // Get the leading info for this line strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns()); strBaseString += playerName + ", "; eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategyLoop; // GrandStrategy Info CvAIGrandStrategyXMLEntry* pEntry = GC.getAIGrandStrategyInfo(eGrandStrategy); const char* szAIGrandStrategyType = (pEntry != NULL)? pEntry->GetType() : "Unknown Type"; if(GetActiveGrandStrategy() == eGrandStrategy) { strTemp.Format("*** %s, %d, %d", szAIGrandStrategyType, GetGrandStrategyPriority(eGrandStrategy), vModifiedGrandStrategyPriorities[eGrandStrategy]); } else { strTemp.Format("%s, %d, %d", szAIGrandStrategyType, GetGrandStrategyPriority(eGrandStrategy), vModifiedGrandStrategyPriorities[eGrandStrategy]); } strOutBuf = strBaseString + strTemp; pLog->Msg(strOutBuf); } } }
/// Get the base Priority for a Grand Strategy; these are elements common to ALL Grand Strategies int CvGrandStrategyAI::GetPersonalityAndGrandStrategy(FlavorTypes eFlavorType) { if(m_eActiveGrandStrategy != NO_AIGRANDSTRATEGY) { CvAIGrandStrategyXMLEntry* pGrandStrategy = GetAIGrandStrategies()->GetEntry(m_eActiveGrandStrategy); int iModdedFlavor = pGrandStrategy->GetFlavorModValue(eFlavorType) + m_pPlayer->GetFlavorManager()->GetPersonalityIndividualFlavor(eFlavorType); iModdedFlavor = max(0,iModdedFlavor); return iModdedFlavor; } return m_pPlayer->GetFlavorManager()->GetPersonalityIndividualFlavor(eFlavorType); }
/// Get the base Priority for a Grand Strategy; these are elements common to ALL Grand Strategies int CvGrandStrategyAI::GetBaseGrandStrategyPriority(AIGrandStrategyTypes eGrandStrategy) { CvAIGrandStrategyXMLEntry* pGrandStrategy = GetAIGrandStrategies()->GetEntry(eGrandStrategy); int iPriority = 0; // Personality effect on Priority for(int iFlavorLoop = 0; iFlavorLoop < GC.getNumFlavorTypes(); iFlavorLoop++) { if(pGrandStrategy->GetFlavorValue(iFlavorLoop) != 0) { iPriority += (pGrandStrategy->GetFlavorValue(iFlavorLoop) * GetPlayer()->GetFlavorManager()->GetPersonalityIndividualFlavor((FlavorTypes) iFlavorLoop)); } } return iPriority; }
int CvGrandStrategyAI::GetPersonalityAndGrandStrategy(FlavorTypes eFlavorType) #endif { if(m_eActiveGrandStrategy != NO_AIGRANDSTRATEGY) { CvAIGrandStrategyXMLEntry* pGrandStrategy = GetAIGrandStrategies()->GetEntry(m_eActiveGrandStrategy); int iModdedFlavor = pGrandStrategy->GetFlavorModValue(eFlavorType) + m_pPlayer->GetFlavorManager()->GetPersonalityIndividualFlavor(eFlavorType); iModdedFlavor = max(0,iModdedFlavor); #if defined(MOD_AI_SMART_V3) if(MOD_AI_SMART_V3 && bBoostGSMainFlavor && (pGrandStrategy->GetFlavorValue(eFlavorType) > 0)) { iModdedFlavor = min(10, ((pGrandStrategy->GetFlavorValue(eFlavorType) + iModdedFlavor + 1) / 2)); } #endif return iModdedFlavor; } return m_pPlayer->GetFlavorManager()->GetPersonalityIndividualFlavor(eFlavorType); }
/// Runs every turn to try and figure out what other known Players' Grand Strategies are void CvGrandStrategyAI::DoGuessOtherPlayersActiveGrandStrategy() { CvWeightedVector<int, 5, true> vGrandStrategyPriorities; FStaticVector< int, 5, true, c_eCiv5GameplayDLL > vGrandStrategyPrioritiesForLogging; GuessConfidenceTypes eGuessConfidence = NO_GUESS_CONFIDENCE_TYPE; int iGrandStrategiesLoop = 0; AIGrandStrategyTypes eGrandStrategy = NO_AIGRANDSTRATEGY; CvAIGrandStrategyXMLEntry* pGrandStrategy = 0; CvString strGrandStrategyName; CvTeam& pTeam = GET_TEAM(GetPlayer()->getTeam()); int iMajorLoop = 0; PlayerTypes eMajor = NO_PLAYER; int iPriority = 0; // Establish world Military strength average int iWorldMilitaryAverage = GC.getGame().GetWorldMilitaryStrengthAverage(GetPlayer()->GetID(), true, true); // Establish world culture and tourism averages int iNumPlayersAlive = 0; int iWorldCultureAverage = 0; int iWorldTourismAverage = 0; for(iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++) { eMajor = (PlayerTypes) iMajorLoop; if(GET_PLAYER(eMajor).isAlive()) { iWorldCultureAverage += GET_PLAYER(eMajor).GetJONSCultureEverGenerated(); iWorldTourismAverage += GET_PLAYER(eMajor).GetCulture()->GetTourism(); iNumPlayersAlive++; } } iWorldCultureAverage /= iNumPlayersAlive; iWorldTourismAverage /= iNumPlayersAlive; // Establish world Tech progress average iNumPlayersAlive = 0; int iWorldNumTechsAverage = 0; TeamTypes eTeam; for(int iTeamLoop = 0; iTeamLoop < MAX_MAJOR_CIVS; iTeamLoop++) // Looping over all MAJOR teams { eTeam = (TeamTypes) iTeamLoop; if(GET_TEAM(eTeam).isAlive()) { iWorldNumTechsAverage += GET_TEAM(eTeam).GetTeamTechs()->GetNumTechsKnown(); iNumPlayersAlive++; } } iWorldNumTechsAverage /= iNumPlayersAlive; // Look at every Major we've met for(iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++) { eMajor = (PlayerTypes) iMajorLoop; if(GET_PLAYER(eMajor).isAlive() && iMajorLoop != GetPlayer()->GetID()) { if(pTeam.isHasMet(GET_PLAYER(eMajor).getTeam())) { for(iGrandStrategiesLoop = 0; iGrandStrategiesLoop < GetAIGrandStrategies()->GetNumAIGrandStrategies(); iGrandStrategiesLoop++) { eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategiesLoop; pGrandStrategy = GetAIGrandStrategies()->GetEntry(iGrandStrategiesLoop); strGrandStrategyName = (CvString) pGrandStrategy->GetType(); if(strGrandStrategyName == "AIGRANDSTRATEGY_CONQUEST") { iPriority = GetGuessOtherPlayerConquestPriority(eMajor, iWorldMilitaryAverage); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_CULTURE") { iPriority = GetGuessOtherPlayerCulturePriority(eMajor, iWorldCultureAverage, iWorldTourismAverage); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_UNITED_NATIONS") { iPriority = GetGuessOtherPlayerUnitedNationsPriority(eMajor); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_SPACESHIP") { iPriority = GetGuessOtherPlayerSpaceshipPriority(eMajor, iWorldNumTechsAverage); } vGrandStrategyPriorities.push_back(iGrandStrategiesLoop, iPriority); vGrandStrategyPrioritiesForLogging.push_back(iPriority); } if(vGrandStrategyPriorities.size() > 0) { // Add "No Grand Strategy" in case we just don't have enough info to go on iPriority = /*40*/ GC.getAI_GRAND_STRATEGY_GUESS_NO_CLUE_WEIGHT(); vGrandStrategyPriorities.push_back(NO_AIGRANDSTRATEGY, iPriority); vGrandStrategyPrioritiesForLogging.push_back(iPriority); vGrandStrategyPriorities.SortItems(); eGrandStrategy = (AIGrandStrategyTypes) vGrandStrategyPriorities.GetElement(0); iPriority = vGrandStrategyPriorities.GetWeight(0); eGuessConfidence = NO_GUESS_CONFIDENCE_TYPE; // How confident are we in our Guess? if(eGrandStrategy != NO_AIGRANDSTRATEGY) { if(iPriority >= /*120*/ GC.getAI_GRAND_STRATEGY_GUESS_POSITIVE_THRESHOLD()) { eGuessConfidence = GUESS_CONFIDENCE_POSITIVE; } else if(iPriority >= /*70*/ GC.getAI_GRAND_STRATEGY_GUESS_LIKELY_THRESHOLD()) { eGuessConfidence = GUESS_CONFIDENCE_LIKELY; } else { eGuessConfidence = GUESS_CONFIDENCE_UNSURE; } } SetGuessOtherPlayerActiveGrandStrategy(eMajor, eGrandStrategy, eGuessConfidence); LogGuessOtherPlayerGrandStrategy(vGrandStrategyPrioritiesForLogging, eMajor); } vGrandStrategyPriorities.clear(); vGrandStrategyPrioritiesForLogging.clear(); } } } }
/// Runs every turn to determine what the player's Active Grand Strategy is and to change Priority Levels as necessary void CvGrandStrategyAI::DoTurn() { DoGuessOtherPlayersActiveGrandStrategy(); int iGrandStrategiesLoop; AIGrandStrategyTypes eGrandStrategy; CvAIGrandStrategyXMLEntry* pGrandStrategy; CvString strGrandStrategyName; // Loop through all GrandStrategies to set their Priorities for(iGrandStrategiesLoop = 0; iGrandStrategiesLoop < GetAIGrandStrategies()->GetNumAIGrandStrategies(); iGrandStrategiesLoop++) { eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategiesLoop; pGrandStrategy = GetAIGrandStrategies()->GetEntry(iGrandStrategiesLoop); strGrandStrategyName = (CvString) pGrandStrategy->GetType(); // Base Priority looks at Personality Flavors (0 - 10) and multiplies * the Flavors attached to a Grand Strategy (0-10), // so expect a number between 0 and 100 back from this int iPriority = GetBaseGrandStrategyPriority(eGrandStrategy); if(strGrandStrategyName == "AIGRANDSTRATEGY_CONQUEST") { iPriority += GetConquestPriority(); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_CULTURE") { iPriority += GetCulturePriority(); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_UNITED_NATIONS") { iPriority += GetUnitedNationsPriority(); } else if(strGrandStrategyName == "AIGRANDSTRATEGY_SPACESHIP") { iPriority += GetSpaceshipPriority(); } // Random element iPriority += GC.getGame().getJonRandNum(/*50*/ GC.getAI_GS_RAND_ROLL(), "Grand Strategy AI: GS rand roll."); // Give a boost to the current strategy so that small fluctuation doesn't cause a big change if(GetActiveGrandStrategy() == eGrandStrategy && GetActiveGrandStrategy() != NO_AIGRANDSTRATEGY) { iPriority += /*50*/ GC.getAI_GRAND_STRATEGY_CURRENT_STRATEGY_WEIGHT(); } SetGrandStrategyPriority(eGrandStrategy, iPriority); } // Now look at what we think the other players in the game are up to - we might have an opportunity to capitalize somewhere int iNumPlayersAliveAndMet = 0; int iMajorLoop; for(iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++) { if(GET_PLAYER((PlayerTypes) iMajorLoop).isAlive()) { if(GET_TEAM(GetPlayer()->getTeam()).isHasMet(GET_PLAYER((PlayerTypes) iMajorLoop).getTeam())) { iNumPlayersAliveAndMet++; } } } FStaticVector< int, 5, true, c_eCiv5GameplayDLL > viNumGrandStrategiesAdopted; int iNumPlayers; // Init vector for(iGrandStrategiesLoop = 0; iGrandStrategiesLoop < GetAIGrandStrategies()->GetNumAIGrandStrategies(); iGrandStrategiesLoop++) { iNumPlayers = 0; // Tally up how many players we think are pusuing each Grand Strategy for(iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++) { if(GetGuessOtherPlayerActiveGrandStrategy((PlayerTypes) iMajorLoop) == (AIGrandStrategyTypes) iGrandStrategiesLoop) { iNumPlayers++; } } viNumGrandStrategiesAdopted.push_back(iNumPlayers); } FStaticVector< int, 5, true, c_eCiv5GameplayDLL > viGrandStrategyChangeForLogging; int iChange; // Now modify our preferences based on how many people are going for stuff for(iGrandStrategiesLoop = 0; iGrandStrategiesLoop < GetAIGrandStrategies()->GetNumAIGrandStrategies(); iGrandStrategiesLoop++) { eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategiesLoop; // If EVERYONE else we know is also going for this Grand Strategy, reduce our Priority by 50% iChange = GetGrandStrategyPriority(eGrandStrategy) * /*50*/ GC.getAI_GRAND_STRATEGY_OTHER_PLAYERS_GS_MULTIPLIER(); iChange = iChange * viNumGrandStrategiesAdopted[eGrandStrategy] / iNumPlayersAliveAndMet; iChange /= 100; ChangeGrandStrategyPriority(eGrandStrategy, -iChange); viGrandStrategyChangeForLogging.push_back(-iChange); } ChangeNumTurnsSinceActiveSet(1); // Now see which Grand Strategy should be active, based on who has the highest Priority right now // Grand Strategy must be run for at least 10 turns if(GetActiveGrandStrategy() == NO_AIGRANDSTRATEGY || GetNumTurnsSinceActiveSet() >= /*10*/ GC.getAI_GRAND_STRATEGY_NUM_TURNS_STRATEGY_MUST_BE_ACTIVE()) { int iBestPriority = -1; int iPriority; AIGrandStrategyTypes eBestGrandStrategy = NO_AIGRANDSTRATEGY; for(iGrandStrategiesLoop = 0; iGrandStrategiesLoop < GetAIGrandStrategies()->GetNumAIGrandStrategies(); iGrandStrategiesLoop++) { eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategiesLoop; iPriority = GetGrandStrategyPriority(eGrandStrategy); if(iPriority > iBestPriority) { iBestPriority = iPriority; eBestGrandStrategy = eGrandStrategy; } } if(eBestGrandStrategy != GetActiveGrandStrategy()) { SetActiveGrandStrategy(eBestGrandStrategy); m_pPlayer->GetCitySpecializationAI()->SetSpecializationsDirty(SPECIALIZATION_UPDATE_NEW_GRAND_STRATEGY); } } LogGrandStrategies(viGrandStrategyChangeForLogging); }
/// Log our guess as to other Players' Active Grand Strategy void CvGrandStrategyAI::LogGuessOtherPlayerGrandStrategy(const FStaticVector< int, 5, true, c_eCiv5GameplayDLL >& vGrandStrategyPriorities, PlayerTypes ePlayer) { if(GC.getLogging() && GC.getAILogging()) { CvString strOutBuf; CvString strBaseString; CvString strTemp; CvString playerName; CvString otherPlayerName; CvString strDesc; CvString strLogName; // Find the name of this civ and city playerName = GetPlayer()->getCivilizationShortDescription(); // Open the log file if(GC.getPlayerAndCityAILogSplit()) { strLogName = "GrandStrategyAI_Guess_Log_" + playerName + ".csv"; } else { strLogName = "GrandStrategyAI_Guess_Log.csv"; } FILogFile* pLog; pLog = LOGFILEMGR.GetLog(strLogName, FILogFile::kDontTimeStamp); AIGrandStrategyTypes eGrandStrategy; int iPriority; // Loop through Grand Strategies for(int iGrandStrategyLoop = 0; iGrandStrategyLoop < GC.getNumAIGrandStrategyInfos(); iGrandStrategyLoop++) { // Get the leading info for this line strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns()); strBaseString += playerName + ", "; eGrandStrategy = (AIGrandStrategyTypes) iGrandStrategyLoop; iPriority = vGrandStrategyPriorities[iGrandStrategyLoop]; CvAIGrandStrategyXMLEntry* pEntry = GC.getAIGrandStrategyInfo(eGrandStrategy); const char* szGrandStrategyType = (pEntry != NULL)? pEntry->GetType() : "Unknown Strategy"; // GrandStrategy Info if(GetActiveGrandStrategy() == eGrandStrategy) { strTemp.Format("*** %s, %d", szGrandStrategyType, iPriority); } else { strTemp.Format("%s, %d", szGrandStrategyType, iPriority); } otherPlayerName = GET_PLAYER(ePlayer).getCivilizationShortDescription(); strOutBuf = strBaseString + otherPlayerName + ", " + strTemp; if(GetGuessOtherPlayerActiveGrandStrategy(ePlayer) == eGrandStrategy) { // Confidence in our guess switch(GetGuessOtherPlayerActiveGrandStrategyConfidence(ePlayer)) { case GUESS_CONFIDENCE_POSITIVE: strTemp.Format("Positive"); break; case GUESS_CONFIDENCE_LIKELY: strTemp.Format("Likely"); break; case GUESS_CONFIDENCE_UNSURE: strTemp.Format("Unsure"); break; default: strTemp.Format("XXX"); break; } strOutBuf += ", " + strTemp; } pLog->Msg(strOutBuf); } // One more entry for NO GRAND STRATEGY // Get the leading info for this line strBaseString.Format("%03d, ", GC.getGame().getElapsedGameTurns()); strBaseString += playerName + ", "; iPriority = vGrandStrategyPriorities[GC.getNumAIGrandStrategyInfos()]; // GrandStrategy Info strTemp.Format("NO_GRAND_STRATEGY, %d", iPriority); otherPlayerName = GET_PLAYER(ePlayer).getCivilizationShortDescription(); strOutBuf = strBaseString + otherPlayerName + ", " + strTemp; pLog->Msg(strOutBuf); } }