/// Priority for opening up this branch int CvPolicyAI::WeighBranch(PolicyBranchTypes eBranch) { int iWeight = 0; CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(eBranch); if(pkPolicyBranchInfo) { for(int iPolicyLoop = 0; iPolicyLoop < m_pCurrentPolicies->GetPolicies()->GetNumPolicies(); iPolicyLoop++) { const PolicyTypes ePolicyLoop = static_cast<PolicyTypes>(iPolicyLoop); CvPolicyEntry* pkLoopPolicyInfo = GC.getPolicyInfo(ePolicyLoop); if(pkLoopPolicyInfo) { // Policy we don't have? if(!m_pCurrentPolicies->HasPolicy(ePolicyLoop)) { // From this branch we are considering opening? if(pkLoopPolicyInfo->GetPolicyBranchType() == eBranch) { // With no prereqs? if(pkLoopPolicyInfo->GetPrereqAndPolicies(0) == NO_POLICY) { iWeight += m_PolicyAIWeights.GetWeight(iPolicyLoop); } } } } } // Add weight of free policy from branch iWeight += m_PolicyAIWeights.GetWeight(pkPolicyBranchInfo->GetFreePolicy()); } return iWeight; }
/// Based on game options (religion off, science off, etc.), would this branch do us any good? bool CvPolicyAI::IsBranchEffectiveInGame(PolicyBranchTypes eBranch) { CvPolicyBranchEntry* pBranchInfo = GC.getPolicyBranchInfo(eBranch); CvAssertMsg(pBranchInfo, "Branch info not found! Please send Anton your save file and version."); if (!pBranchInfo) return false; if (pBranchInfo->IsDelayWhenNoReligion()) if (GC.getGame().isOption(GAMEOPTION_NO_RELIGION)) return false; if (pBranchInfo->IsDelayWhenNoCulture()) if (GC.getGame().isOption(GAMEOPTION_NO_POLICIES)) return false; if (pBranchInfo->IsDelayWhenNoScience()) if (GC.getGame().isOption(GAMEOPTION_NO_SCIENCE)) return false; if (pBranchInfo->IsDelayWhenNoCityStates()) if (GC.getGame().GetNumMinorCivsEver() <= 0) return false; return true; }
/// Choose a player's next policy purchase (could be opening a branch) int CvPolicyAI::ChooseNextPolicy(CvPlayer* pPlayer) { RandomNumberDelegate fcn; fcn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum); int iRtnValue = (int)NO_POLICY; int iPolicyLoop; vector<int> aLevel3Tenets; bool bMustChooseTenet = (pPlayer->GetNumFreeTenets() > 0); // Create a new vector holding only policies we can currently adopt m_AdoptablePolicies.clear(); // Loop through adding the adoptable policies for(iPolicyLoop = 0; iPolicyLoop < m_pCurrentPolicies->GetPolicies()->GetNumPolicies(); iPolicyLoop++) { if(m_pCurrentPolicies->CanAdoptPolicy((PolicyTypes) iPolicyLoop) && (!bMustChooseTenet || m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() > 0)) { int iWeight = 0; iWeight += m_PolicyAIWeights.GetWeight(iPolicyLoop); // Does this policy finish a branch for us? if(m_pCurrentPolicies->WillFinishBranchIfAdopted((PolicyTypes) iPolicyLoop)) { int iPolicyBranch = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetPolicyBranchType(); if(iPolicyBranch != NO_POLICY_BRANCH_TYPE) { int iFinisherPolicy = m_pCurrentPolicies->GetPolicies()->GetPolicyBranchEntry(iPolicyBranch)->GetFreeFinishingPolicy(); if(iFinisherPolicy != NO_POLICY) { iWeight += m_PolicyAIWeights.GetWeight(iFinisherPolicy); } } } m_AdoptablePolicies.push_back(iPolicyLoop + GC.getNumPolicyBranchInfos(), iWeight); if (m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() == 3) { aLevel3Tenets.push_back(iPolicyLoop); } } } // Did we already start a branch in the set that is mutually exclusive? bool bStartedAMutuallyExclusiveBranch = false; for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++) { const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop); CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch); if(pkPolicyBranchInfo) { if(pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch)) { if(pkPolicyBranchInfo->IsMutuallyExclusive()) { bStartedAMutuallyExclusiveBranch = true; } } } } AIGrandStrategyTypes eCultureGrandStrategy = (AIGrandStrategyTypes) GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE"); AIGrandStrategyTypes eCurrentGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy(); // Loop though the branches adding each as another possibility if (!bMustChooseTenet) { for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++) { const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop); CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch); if(pkPolicyBranchInfo) { if(bStartedAMutuallyExclusiveBranch && pkPolicyBranchInfo->IsMutuallyExclusive()) { continue; } #if defined (JRMOD_C23) // Don't open a branch disabling an already opened branch if (pPlayer->GetPlayerPolicies()->IsPolicyBranchBlocked(ePolicyBranch)) continue; #endif if(pPlayer->GetPlayerPolicies()->CanUnlockPolicyBranch(ePolicyBranch) && !pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch)) { int iBranchWeight = 0; // Does this branch actually help us, based on game options? if(IsBranchEffectiveInGame(ePolicyBranch)) { iBranchWeight += WeighBranch(ePolicyBranch); iBranchWeight *= (100 - m_iPolicyWeightPercentDropNewBranch); iBranchWeight /= 100; #if defined (JRMOD_C23) //Following condition no longer makes sense since Cultural victory has changed but i let it since it can help the AI to focus on a tree. #endif if(eCurrentGrandStrategy == eCultureGrandStrategy) { iBranchWeight /= 3; } } m_AdoptablePolicies.push_back(iBranchLoop, iBranchWeight); } } } } m_AdoptablePolicies.SortItems(); LogPossiblePolicies(); // If there were any Level 3 tenets found, consider going for the one that matches our victory strategy if (aLevel3Tenets.size() > 0) { vector<int>::const_iterator it; for (it = aLevel3Tenets.begin(); it != aLevel3Tenets.end(); it++) { CvPolicyEntry *pEntry; pEntry = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(*it); if (pEntry) { AIGrandStrategyTypes eGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy(); if (eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CONQUEST")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_OFFENSE")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_SPACESHIP")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_SPACESHIP")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_UNITED_NATIONS")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_DIPLOMACY")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_CULTURE")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } } } } CvAssertMsg(m_AdoptablePolicies.GetTotalWeight() >= 0, "Total weights of considered policies should not be negative! Please send Anton your save file and version."); // If total weight is above 0, choose one above a threshold if(m_AdoptablePolicies.GetTotalWeight() > 0) { int iNumChoices = GC.getGame().getHandicapInfo().GetPolicyNumOptions(); iRtnValue = m_AdoptablePolicies.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing policy from Top Choices"); } // Total weight may be 0 if the only branches and policies left are ones that are ineffective in our game, but we gotta pick something else if(m_AdoptablePolicies.GetTotalWeight() == 0 && m_AdoptablePolicies.size() > 0) { iRtnValue = m_AdoptablePolicies.ChooseAtRandom(&fcn, "Choosing policy at random (no good choices)"); } // Log our choice if(iRtnValue != (int)NO_POLICY) { if(iRtnValue >= GC.getNumPolicyBranchInfos()) { LogPolicyChoice((PolicyTypes)(iRtnValue - GC.getNumPolicyBranchInfos())); } else { LogBranchChoice((PolicyBranchTypes)iRtnValue); } } return iRtnValue; }
/// Choose a player's next policy purchase (could be opening a branch) int CvPolicyAI::ChooseNextPolicy(CvPlayer* pPlayer) { RandomNumberDelegate fcn; fcn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum); int iRtnValue = (int)NO_POLICY; int iPolicyLoop; vector<int> aLevel3Tenets; bool bMustChooseTenet = (pPlayer->GetNumFreeTenets() > 0); // Create a new vector holding only policies we can currently adopt m_AdoptablePolicies.clear(); // Loop through adding the adoptable policies for(iPolicyLoop = 0; iPolicyLoop < m_pCurrentPolicies->GetPolicies()->GetNumPolicies(); iPolicyLoop++) { if(m_pCurrentPolicies->CanAdoptPolicy((PolicyTypes) iPolicyLoop) && (!bMustChooseTenet || m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() > 0)) { int iWeight = 0; iWeight += m_PolicyAIWeights.GetWeight(iPolicyLoop); #if defined(MOD_BALANCE_CORE) //If this is an ideology policy, let's snap those up. if(m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() > 0) { iWeight *= (m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() + 1); } //Older branches should be slowly phased out. PolicyBranchTypes ePolicyBranch = (PolicyBranchTypes)m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetPolicyBranchType(); if(ePolicyBranch != NO_POLICY_BRANCH_TYPE) { CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch); if(pkPolicyBranchInfo) { //If we're already in this branch, let's get a bonus based on how many we have in it (this will push the AI to finish branches quickly. if(m_pCurrentPolicies->GetNumPoliciesOwnedInBranch(ePolicyBranch) > 0 || m_pCurrentPolicies->IsPolicyBranchUnlocked(ePolicyBranch)) { iWeight *= (m_pCurrentPolicies->GetNumPoliciesOwnedInBranch(ePolicyBranch) + 1); } else { int iPolicyEra = pkPolicyBranchInfo->GetEraPrereq(); int iPlayerEra = pPlayer->GetCurrentEra(); if(iPolicyEra < iPlayerEra) { iWeight /= max(1, (iPlayerEra - iPolicyEra)); } } } if(ePolicyBranch == (PolicyBranchTypes)GC.getInfoTypeForString("POLICY_BRANCH_PIETY", true)) { EconomicAIStrategyTypes eStrategyBuildingReligion = (EconomicAIStrategyTypes) GC.getInfoTypeForString("ECONOMICAISTRATEGY_DEVELOPING_RELIGION", true); bool bBuildingReligion = false; if (eStrategyBuildingReligion != NO_ECONOMICAISTRATEGY) { bBuildingReligion = pPlayer->GetEconomicAI()->IsUsingStrategy(eStrategyBuildingReligion); } if(!bBuildingReligion) { iWeight = 0; } else { iWeight *= 5; } } } #endif // Does this policy finish a branch for us? if(m_pCurrentPolicies->WillFinishBranchIfAdopted((PolicyTypes) iPolicyLoop)) { int iPolicyBranch = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetPolicyBranchType(); if(iPolicyBranch != NO_POLICY_BRANCH_TYPE) { int iFinisherPolicy = m_pCurrentPolicies->GetPolicies()->GetPolicyBranchEntry(iPolicyBranch)->GetFreeFinishingPolicy(); if(iFinisherPolicy != NO_POLICY) { iWeight += m_PolicyAIWeights.GetWeight(iFinisherPolicy); } } } m_AdoptablePolicies.push_back(iPolicyLoop + GC.getNumPolicyBranchInfos(), iWeight); if (m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(iPolicyLoop)->GetLevel() == 3) { aLevel3Tenets.push_back(iPolicyLoop); } } } // Did we already start a branch in the set that is mutually exclusive? bool bStartedAMutuallyExclusiveBranch = false; for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++) { const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop); CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch); if(pkPolicyBranchInfo) { if(pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch)) { if(pkPolicyBranchInfo->IsMutuallyExclusive()) { bStartedAMutuallyExclusiveBranch = true; } } } } #if defined(MOD_BALANCE_CORE) //Leftover from Vanilla victory #else AIGrandStrategyTypes eCultureGrandStrategy = (AIGrandStrategyTypes) GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE"); AIGrandStrategyTypes eCurrentGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy(); #endif // Loop though the branches adding each as another possibility if (!bMustChooseTenet) { for(int iBranchLoop = 0; iBranchLoop < GC.getNumPolicyBranchInfos(); iBranchLoop++) { const PolicyBranchTypes ePolicyBranch = static_cast<PolicyBranchTypes>(iBranchLoop); CvPolicyBranchEntry* pkPolicyBranchInfo = GC.getPolicyBranchInfo(ePolicyBranch); if(pkPolicyBranchInfo) { if(bStartedAMutuallyExclusiveBranch && pkPolicyBranchInfo->IsMutuallyExclusive()) { continue; } #if defined(MOD_BALANCE_CORE) bool bNeedToFinish = false; for(int iBranchLoop2 = 0; iBranchLoop2 < GC.getNumPolicyBranchInfos(); iBranchLoop2++) { const PolicyBranchTypes ePolicyBranch2 = static_cast<PolicyBranchTypes>(iBranchLoop2); CvPolicyBranchEntry* pkPolicyBranchInfo2 = GC.getPolicyBranchInfo(ePolicyBranch2); //Do we already have a different policy branch unlocked? if(pkPolicyBranchInfo2 && ePolicyBranch2 != ePolicyBranch && pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch2)) { //Have we not finished it yet? If so, let's not open a new one. if(!pPlayer->GetPlayerPolicies()->HasPolicy((PolicyTypes)pkPolicyBranchInfo2->GetFreeFinishingPolicy())) { bNeedToFinish = true; break; } } } if(bNeedToFinish) { continue; } #endif if(pPlayer->GetPlayerPolicies()->CanUnlockPolicyBranch(ePolicyBranch) && !pPlayer->GetPlayerPolicies()->IsPolicyBranchUnlocked(ePolicyBranch)) { int iBranchWeight = 0; // Does this branch actually help us, based on game options? if(IsBranchEffectiveInGame(ePolicyBranch)) { iBranchWeight += WeighBranch(ePolicyBranch); iBranchWeight *= (100 - m_iPolicyWeightPercentDropNewBranch); iBranchWeight /= 100; #if defined(MOD_BALANCE_CORE) //Leftover from Vanilla victory #else if(eCurrentGrandStrategy == eCultureGrandStrategy) { iBranchWeight /= 3; } #endif } m_AdoptablePolicies.push_back(iBranchLoop, iBranchWeight); } } } } m_AdoptablePolicies.SortItems(); LogPossiblePolicies(); #if defined(MOD_BALANCE_CORE) #else // If there were any Level 3 tenets found, consider going for the one that matches our victory strategy if (aLevel3Tenets.size() > 0) { vector<int>::const_iterator it; for (it = aLevel3Tenets.begin(); it != aLevel3Tenets.end(); it++) { CvPolicyEntry *pEntry; pEntry = m_pCurrentPolicies->GetPolicies()->GetPolicyEntry(*it); if (pEntry) { AIGrandStrategyTypes eGrandStrategy = pPlayer->GetGrandStrategyAI()->GetActiveGrandStrategy(); if (eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CONQUEST")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_OFFENSE")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_SPACESHIP")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_SPACESHIP")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_UNITED_NATIONS")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_DIPLOMACY")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } else if(eGrandStrategy == GC.getInfoTypeForString("AIGRANDSTRATEGY_CULTURE")) { if (pEntry->GetFlavorValue((FlavorTypes)GC.getInfoTypeForString("FLAVOR_CULTURE")) > 0) { LogPolicyChoice((PolicyTypes)*it); return (*it) + GC.getNumPolicyBranchInfos(); } } } } } #endif CvAssertMsg(m_AdoptablePolicies.GetTotalWeight() >= 0, "Total weights of considered policies should not be negative! Please send Anton your save file and version."); // If total weight is above 0, choose one above a threshold if(m_AdoptablePolicies.GetTotalWeight() > 0) { int iNumChoices = GC.getGame().getHandicapInfo().GetPolicyNumOptions(); iRtnValue = m_AdoptablePolicies.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing policy from Top Choices"); } // Total weight may be 0 if the only branches and policies left are ones that are ineffective in our game, but we gotta pick something else if(m_AdoptablePolicies.GetTotalWeight() == 0 && m_AdoptablePolicies.size() > 0) { iRtnValue = m_AdoptablePolicies.ChooseAtRandom(&fcn, "Choosing policy at random (no good choices)"); } // Log our choice if(iRtnValue != (int)NO_POLICY) { if(iRtnValue >= GC.getNumPolicyBranchInfos()) { LogPolicyChoice((PolicyTypes)(iRtnValue - GC.getNumPolicyBranchInfos())); } else { LogBranchChoice((PolicyBranchTypes)iRtnValue); } } return iRtnValue; }