/// 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;
}