(Just making use of the code sniplet from above ...)
Code:
// PatchMod: Random Start Locs START
// Randomise start locations amongst water starters (Human Europeans)
int iWaterCount = 0;
int iCounter = 0;
[B][COLOR="Green"]for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
if (GC.getCivilizationInfo(GET_PLAYER((PlayerTypes)iI).getCivilizationType()).isWaterStart())[/COLOR][/B]
{
iWaterCount++;
}
}
}
int iRandStart = 0;
CvPlot* pTempPlot = NULL;
[B][COLOR="blue"]for (iJ = 0; iJ < MAX_PLAYERS; iJ++)
{
if (GET_PLAYER((PlayerTypes)iJ).isAlive())
{
if (GC.getCivilizationInfo(GET_PLAYER((PlayerTypes)iJ).getCivilizationType()).isWaterStart()[/COLOR][/B] && GET_PLAYER((PlayerTypes)iJ).isHuman())
{
iRandStart = getSorenRandNum(iWaterCount, "");
iCounter = 0;
[B][COLOR="Red"]for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())
{
if (GC.getCivilizationInfo(GET_PLAYER((PlayerTypes)iI).getCivilizationType()).isWaterStart())[/COLOR][/B]
{
iCounter++;
}
}
if (iCounter == iRandStart)
{
pTempPlot = GET_PLAYER((PlayerTypes)iJ).getStartingPlot();
GET_PLAYER((PlayerTypes)iJ).setStartingPlot(GET_PLAYER((PlayerTypes)iI).getStartingPlot(), true);
GET_PLAYER((PlayerTypes)iI).setStartingPlot(pTempPlot, true);
iI = MAX_PLAYERS;
}
}
}
}
Sorry, guys, for bringing this example up again, but I think I can use it to demonstrate some things.
Let's have a look at the first (green) loop. We are iterating over all (in the case of RaR) 48 players to find out if they (a) are alive (which might be the case for all of them) and then (b) if they are starting on the water (colonies) to increment a counter.
This could have been avoided in this case by simply switching the second and third condition line:
Code:
[B][COLOR="Green"]for (iI = 0; iI < MAX_PLAYERS; iI++)
{
if (GC.getCivilizationInfo(GET_PLAYER((PlayerTypes)iI).getCivilizationType()).isWaterStart())
{
if (GET_PLAYER((PlayerTypes)iI).isAlive())[/COLOR][/B]
{
iWaterCount++;
}
}
}
Now we no longer have to check 48 times if the player has a water start, but only 8 times if the player is alive: By just switching the filter conditions, we have reduced the number of calculations to 1/6.
Now to the blue and red lines. Please notice that I am making use of those just as an example (I am very aware of the conditions .isHuman() / .isWaterStart() which in this case drastically reduce the iterations, but as I said, it's just an example. Similar constructions regarding loops inside loops you will find each and everywhere in the code).
In general we iterate two times over the whole number of players in the game (MAX_PLAYERS = 48) meaning that we have a total of 48² = 2304 iterations.
But let's have a look at what is really going on.
The respective conditions are:
for (iI = 0; iI < MAX_PLAYERS; iI++) and embedded in it
for (iJ = 0; iJ < MAX_PLAYERS; iJ++)
The consequence is to check Player(i=0) with Player(j=0,1,2....), Player(i=1) with Player(j=0,1,2....) and so forth...
But in fact we only have to do the following:
For Player(i=0) do 46 checks against other players, for Player(i=1) do 45 checks against other players and so forth. After all, whether you check Player(0) against Player(1) or Player(1) against Player(0) typically won't make a difference.
So, if we replace above conditions with:
for (iI = 0; iI < MAX_PLAYERS
-1; iI++) and embedded in it
for (iJ =
i+1; iJ < MAX_PLAYERS; iJ++)
we should reduce the number of iterations to almost the half: 1128
If we now calculate the worst case over all three loops and compare it with the changed loops, we see the difference:
48 + 48² =
2352 vs
1136 = 8 + 1128 iterations.
As I said, similar constructions you'll find each and everywhere. Might be worth the effort to have a closer look next time if one could save some time.