Skip to content

Commit

Permalink
convert pseudo fraction pair into actual fraction class
Browse files Browse the repository at this point in the history
  • Loading branch information
LessRekkless authored and RecursiveVision committed Aug 7, 2024
1 parent 9db61d5 commit 869e65d
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 71 deletions.
6 changes: 3 additions & 3 deletions CvGameCoreDLL_Expansion2/CvBeliefClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4597,11 +4597,11 @@ int CvReligionBeliefs::GetCSYieldBonus(PlayerTypes ePlayer, const CvCity* pCity,
}

/// Get votes per improvement (fractional) from belief
std::pair<int, int> CvReligionBeliefs::GetVoteFromOwnedImprovement(ImprovementTypes eImprovement, PlayerTypes ePlayer, const CvCity* pCity, bool bHolyCityOnly) const
fraction CvReligionBeliefs::GetVoteFromOwnedImprovement(ImprovementTypes eImprovement, PlayerTypes ePlayer, const CvCity* pCity, bool bHolyCityOnly) const
{
CvBeliefXMLEntries* pBeliefs = GC.GetGameBeliefs();

std::pair<int, int> fVotes = std::make_pair(0, 1);
fraction fVotes = 0;

// if two beliefs give fractional votes for the same improvement, then the fractional vote gets larger (1/2 + 1/3 = 5/6)
for (BeliefList::const_iterator it = m_ReligionBeliefs.begin(); it != m_ReligionBeliefs.end(); ++it)
Expand All @@ -4610,7 +4610,7 @@ std::pair<int, int> CvReligionBeliefs::GetVoteFromOwnedImprovement(ImprovementTy
int iValue = pBeliefs->GetEntry(*it)->GetImprovementVoteChange(eImprovement);
if (iValue != 0 && IsBeliefValid((BeliefTypes)*it, GetReligion(), ePlayer, pCity, bHolyCityOnly))
{
AddFractionToReference(fVotes, std::make_pair(1, iValue));
fVotes += fraction(1, iValue);
}
}

Expand Down
2 changes: 1 addition & 1 deletion CvGameCoreDLL_Expansion2/CvBeliefClasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ class CvReligionBeliefs
CivilizationTypes GetUniqueCiv(PlayerTypes ePlayer = NO_PLAYER, bool bHolyCityOnly = false) const;
int GetIgnorePolicyRequirementsAmount(EraTypes eEra, PlayerTypes ePlayer = NO_PLAYER, const CvCity* pCity = NULL, bool bHolyCityOnly = false) const;
int GetCSYieldBonus(PlayerTypes ePlayer = NO_PLAYER, const CvCity* pCity = NULL, bool bHolyCityOnly = false) const;
std::pair<int, int> GetVoteFromOwnedImprovement(ImprovementTypes eImprovement, PlayerTypes ePlayer = NO_PLAYER, const CvCity* pCity = NULL, bool bHolyCityOnly = false) const;
fraction GetVoteFromOwnedImprovement(ImprovementTypes eImprovement, PlayerTypes ePlayer = NO_PLAYER, const CvCity* pCity = NULL, bool bHolyCityOnly = false) const;

const BeliefList& GetBeliefList() const { return m_ReligionBeliefs; }
#endif
Expand Down
49 changes: 0 additions & 49 deletions CvGameCoreDLL_Expansion2/CvGameCoreUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1502,55 +1502,6 @@ int MapToPercent(int iValue, int iZeroAt, int iHundredAt)
return 50;
}

//------------------------------------------------------------------------------
// add a fraction to a referenced fraction without losing information; the referenced fraction is assumed to have the larger dividend & divisor
void AddFractionToReference(pair<int,int>& A, const pair<int,int>& B)
{
// protect from integer overflow (safe, simple max that will probably never be hit)
if (A.first >= (INT_MAX / B.first / B.second) - A.second)
{
// Divisor or Dividend is too large! Start fresh
if (A.first > A.second)
{
A.first /= A.second;
A.second = 1;
}
else
{
A.second /= A.first;
A.first = 1;
}
}

// N / D = nA / dA + nB / dB
// = (nA*dB + nB*dA) / (dB*dA)
A.first *= B.second;
A.first += B.first * A.second;

A.second *= B.second;
}

// add two fractions together without losing information; A is assumed to have the larger dividend & divisor
pair<int,int> AddFractions(pair<int,int>& A, pair<int,int>& B)
{
AddFractionToReference(A, B);
return A;
}

// add a list of fractions together (separated numerators and denominators)
pair<int,int> AddFractions(vector<int>& aDividendList, vector<int>& aDivisorList)
{
CvAssert(aDividendList.size() == aDivisorList.size());

pair<int,int> result = make_pair(0, 1);

for (size_t jJ = 0, jlen = aDividendList.size(); jJ < jlen; ++jJ)
{
AddFractionToReference(result, make_pair(aDividendList[jJ], aDivisorList[jJ]));
}
return result;
}

//------------------------------------------------------------------------------
fraction& fraction::operator+=(const fraction &rhs)
{
Expand Down
5 changes: 0 additions & 5 deletions CvGameCoreDLL_Expansion2/CvGameCoreUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,6 @@ T PseudoRandomChoiceByWeight(vector<OptionWithScore<T>>& candidates, const T& de
return defaultChoice;
}

//------------------------------------------------------------------------------
void AddFractionToReference(pair<int,int>& A, const pair<int,int>& B);
pair<int,int> AddFractions(pair<int,int>& A, pair<int,int>& B);
pair<int,int> AddFractions(vector<int>& dividendList, vector<int>& divisorList);

//------------------------------------------------------------------------------
class fraction
{
Expand Down
11 changes: 4 additions & 7 deletions CvGameCoreDLL_Expansion2/CvPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23058,22 +23058,19 @@ int CvPlayer::CalculateReligionVotesFromImprovements(const CvReligion *pReligion
{
int iNumImprovementInfos = GC.getNumImprovementInfos();

std::pair<int, int> fTotalVotes = std::make_pair(0, 1);
fraction fTotalVotes = 0;

for (int jJ = 0; jJ < iNumImprovementInfos; jJ++)
{
int iNumImprovements = getImprovementCount((ImprovementTypes)jJ); // less expensive function call
if (iNumImprovements > 0)
{
// number of votes per improvement (a fraction less than one)
std::pair<int, int> fPotentialVotes = pReligion->m_Beliefs.GetVoteFromOwnedImprovement((ImprovementTypes)jJ, m_eID); // more likely to be zero
if (fPotentialVotes.first > 0)
{
AddFractionToReference(fTotalVotes, std::make_pair(iNumImprovements * fPotentialVotes.first, fPotentialVotes.second));
}
fraction fPotentialVotes = pReligion->m_Beliefs.GetVoteFromOwnedImprovement((ImprovementTypes)jJ, m_eID); // more likely to be zero
fTotalVotes += fPotentialVotes * iNumImprovements;
}
}
return fTotalVotes.first / fTotalVotes.second;
return fTotalVotes.Truncate();
}

/// Extra influence from GPs
Expand Down
12 changes: 6 additions & 6 deletions CvGameCoreDLL_Expansion2/CvReligionClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10226,17 +10226,17 @@ int CvReligionAI::ScoreBeliefForPlayer(CvBeliefEntry* pEntry, bool bReturnConque
}

int iNumImprovementInfos = GC.getNumImprovementInfos();
pair<int, int> fVoteRatio = make_pair(0, 1);
fraction fVoteRatio = 0;
for (int jJ = 0; jJ < iNumImprovementInfos; jJ++)
{
int potentialVotes = pEntry->GetImprovementVoteChange((ImprovementTypes)jJ);
if (potentialVotes > 0)
int iPotentialVotes = pEntry->GetImprovementVoteChange((ImprovementTypes)jJ);
if (iPotentialVotes > 0)
{
int numImprovements = max(m_pPlayer->getImprovementCount((ImprovementTypes)jJ), 1);
AddFractionToReference(fVoteRatio, make_pair(numImprovements, potentialVotes));
int iNumImprovements = max(m_pPlayer->getImprovementCount((ImprovementTypes)jJ), 1);
fVoteRatio += fraction(iNumImprovements, iPotentialVotes);
}
}
iDiploTemp += 80 * fVoteRatio.first / fVoteRatio.second;
iDiploTemp += (fVoteRatio * 80).Truncate();

if (pEntry->GetCityStateInfluenceModifier() > 0)
{
Expand Down

0 comments on commit 869e65d

Please sign in to comment.