Started to address comments from the reviewer.

This commit is contained in:
hiker 2018-06-17 23:48:47 +10:00
parent 8cf52b4c7c
commit 48aca2f70f
3 changed files with 80 additions and 58 deletions

View File

@ -79,9 +79,16 @@
For each race mode (race, time-trial, soccer etc) there is one
weight-list entry (e.g. race-weight-list etc). Each of those lists
contains a list (1 or more entries) of weights for a certain number
of karts in the race (which is used to reduce the frequency of
'global' items). Each of those weight tagsis stored into a
WeightsData object.
of karts in the race. This offers two advantages:
1) the frequency of global items (like switch) can be reduced for
higher number of karts (so that game play does not get dominated
by frequent global items)
2) to take into account the balance changes when the number of karts
is different. Typically, the higher the number of karts, the
stronger the difference in "powerup quality" between the first and
the last.
Each of those weight tags is stored into a WeightsData object.
At race time, a new WeightsData object is created from the list for
the current race type depending on number of karts in the race.
If there is a WeightsData object for the same kart number, it is
@ -111,7 +118,7 @@
corresponds to the weights of getting one specific item,
the second line (multi) to the weight at which it will yeld
a triple item rather than a single one. The probability to get
an item is its weight divided by sum of weights of all items
an item is its weight divided by the sum of weights of all items
(single AND multi). It is recommended to keep that sum equal
to 200 to easily keep track of probabilities.
@ -126,72 +133,72 @@
there are more karts. -->
<race-weight-list>
<!-- The entry for '0' karts is special and means 'first kart' -->
<!-- The entry for '1' karts is special and means 'first kart' -->
<weights num-karts="1">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="28 0 60 20 45 15 32 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="30 0 59 26 40 14 27 0 0 0"
multi =" 0 0 4 0 0 0 0 0 0 0" />
multi =" 0 0 4 0 0 0 0 0 0 0" />
<weight single ="30 0 62 27 36 13 27 0 0 0"
multi =" 0 0 5 0 0 0 0 0 0 0" />
multi =" 0 0 5 0 0 0 0 0 0 0" />
<weight single ="31 0 56 36 34 12 25 0 0 0"
multi =" 0 0 6 0 0 0 0 0 0 0" />
multi =" 0 0 6 0 0 0 0 0 0 0" />
<weight single ="34 0 36 55 30 10 17 0 0 0"
multi =" 0 0 18 0 0 0 0 0 0 0" />
multi =" 0 0 18 0 0 0 0 0 0 0" />
</weights>
<weights num-karts="5">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="26 16 52 15 46 12 33 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="30 27 48 25 28 10 27 0 0 0"
multi =" 0 0 5 0 0 0 0 0 0 0" />
multi =" 0 0 5 0 0 0 0 0 0 0" />
<weight single ="30 27 45 27 27 9 27 3 0 0"
multi =" 0 0 5 0 0 0 0 0 0 0" />
multi =" 0 0 5 0 0 0 0 0 0 0" />
<weight single ="32 24 28 38 22 7 20 16 6 0"
multi =" 0 0 7 0 0 0 0 0 0 0" />
multi =" 0 0 7 0 0 0 0 0 0 0" />
<weight single ="28 21 9 45 0 6 0 10 18 0"
multi =" 8 0 16 35 4 0 0 0 0 0" />
multi =" 8 0 16 35 4 0 0 0 0 0" />
</weights>
<weights num-karts="9">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="24 12 58 10 54 8 34 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="29 30 45 24 32 7 27 0 0 0"
multi =" 0 0 6 0 0 0 0 0 0 0" />
multi =" 0 0 6 0 0 0 0 0 0 0" />
<weight single ="30 26 41 28 26 6 26 10 0 0"
multi =" 0 0 7 0 0 0 0 0 0 0" />
multi =" 0 0 7 0 0 0 0 0 0 0" />
<weight single ="33 23 26 45 14 5 16 12 8 0"
multi =" 0 0 12 0 6 0 0 0 0 0" />
multi =" 0 0 12 0 6 0 0 0 0 0" />
<weight single ="20 16 7 37 0 3 0 4 15 0"
multi ="18 0 18 58 4 0 0 0 0 0" />
multi ="18 0 18 58 4 0 0 0 0 0" />
</weights>
<weights num-karts="14">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="22 8 64 5 60 6 35 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="28 31 48 22 34 4 27 0 0 0"
multi =" 0 0 6 0 0 0 0 0 0 0" />
multi =" 0 0 6 0 0 0 0 0 0 0" />
<weight single ="30 25 42 29 29 3 24 10 0 0"
multi =" 0 0 8 0 0 0 0 0 0 0" />
multi =" 0 0 8 0 0 0 0 0 0 0" />
<weight single ="27 21 23 44 12 3 14 8 6 0"
multi =" 8 0 16 8 10 0 0 0 0 0" />
multi =" 8 0 16 8 10 0 0 0 0 0" />
<weight single ="18 14 3 35 0 0 0 0 10 0"
multi ="24 0 25 65 6 0 0 0 0 0" />
multi ="24 0 25 65 6 0 0 0 0 0" />
</weights>
<weights num-karts="20">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="20 0 74 0 66 4 36 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="27 32 48 20 37 3 27 0 0 0"
multi =" 0 0 6 0 0 0 0 0 0 0" />
multi =" 0 0 6 0 0 0 0 0 0 0" />
<weight single ="30 24 40 30 28 2 21 10 0 0"
multi =" 0 0 10 0 5 0 0 0 0 0" />
multi =" 0 0 10 0 5 0 0 0 0 0" />
<weight single ="25 18 20 50 10 2 10 6 3 0"
multi ="10 0 20 10 16 0 0 0 0 0" />
multi ="10 0 20 10 16 0 0 0 0 0" />
<weight single ="15 12 0 25 0 0 0 0 7 0"
multi ="30 0 31 80 0 0 0 0 0 0" />
multi ="30 0 31 80 0 0 0 0 0 0" />
</weights>
</race-weight-list>
@ -200,17 +207,17 @@
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<!-- This is the entry for the leader: -->
<weight single ="35 0 25 35 25 15 25 0 0 0"
multi ="20 0 0 20 0 0 0 0 0 0" />
multi ="20 0 0 20 0 0 0 0 0 0" />
<!-- This is the entry for the first non-leader karts: -->
<weight single ="25 0 60 25 58 2 30 0 0 0"
multi =" 0 0 0 0 0 0 0 0 0 0" />
multi =" 0 0 0 0 0 0 0 0 0 0" />
<weight single ="35 0 55 35 25 3 25 0 0 0"
multi =" 0 0 10 0 12 0 0 0 0 0" />
multi =" 0 0 10 0 12 0 0 0 0 0" />
<weight single ="25 0 40 45 15 5 15 10 5 0"
multi ="10 0 15 15 0 0 0 0 0 0" />
multi ="10 0 15 15 0 0 0 0 0 0" />
<!-- This is the entry for the last kart: -->
<weight single ="20 0 15 25 0 0 0 0 15 0"
multi ="20 0 25 80 0 0 0 0 0 0" />
multi ="20 0 25 80 0 0 0 0 0 0" />
</weights>
</ftl-weight-list>
@ -218,7 +225,7 @@
<weights num-karts="1">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single ="10 30 60 0 0 10 30 0 0 0"
multi =" 0 0 5 0 0 0 0 0 0 0" />
multi =" 0 0 5 0 0 0 0 0 0 0" />
</weights>
</battle-weight-list>
@ -226,7 +233,7 @@
<weights num-karts="1">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single =" 0 30 60 0 0 10 30 0 0 0"
multi =" 0 0 5 0 0 0 0 0 0 0" />
multi =" 0 0 5 0 0 0 0 0 0 0" />
</weights>
</soccer-weight-list>
@ -234,7 +241,7 @@
<weights num-karts="0">
<!-- bubble cake bowl zipper plunger switch swattr rubber para anvil -->
<weight single =" 0 0 0 0 0 0 0 0 0 0"
multi =" 0 0 100 0 0 0 0 0 0 0" /> />
multi =" 0 0 100 0 0 0 0 0 0 0" /> />
</weights>
</tutorial-weight-list>

View File

@ -220,7 +220,13 @@ void PowerupManager::WeightsData::readData(int num_karts, const XMLNode *node)
l.push_back(n);
}
// Make sure we have the right number of entries
while(l.size()<2*(int)POWERUP_LAST) l.push_back(0);
if (l.size() < 2 * (int)POWERUP_LAST)
{
Log::error("PowerupManager",
"Not enough entries for '%s' in powerup.xml",
node->getName().c_str());
while (l.size() < 2 * (int)POWERUP_LAST) l.push_back(0);
}
if(l.size()>2*(int)POWERUP_LAST)
{
Log::error("PowerupManager",
@ -265,7 +271,7 @@ void PowerupManager::WeightsData::interpolate(WeightsData *prev,
} // WeightsData::interpolate
// ----------------------------------------------------------------------------
/** For a given rank in the current race this computed the previous and
/** For a given rank in the current race this computes the previous and
* next entry in the weight list, and the weight necessary to interpolate
* between these two values. If the requested rank should exactly match
* one entries, previous and next entry will be identical, and weight set
@ -276,10 +282,11 @@ void PowerupManager::WeightsData::interpolate(WeightsData *prev,
* \param next On return contains the index of the closest weight field
* bigger than the given rank.
* \param weight On return contains the weight to use to interpolate between
* next and previous.
* next and previous. The weight is for 'next', so (1-weight) is the
* weight that needs to be applied to the previous data.
*/
int PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
int *next, float *weight)
void PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
int *next, float *weight)
{
// If there is only one section (e.g. in soccer mode etc), use it.
// If the rank is first, always use the first entry as well.
@ -287,7 +294,7 @@ int PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
{
*prev = *next = 0;
*weight = 1.0f;
return 1;
return;
}
// The last kart always uses the data for the last section
@ -295,7 +302,7 @@ int PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
{
*prev = *next = m_weights_for_section.size() - 1;
*weight = 1.0f;
return 1;
return;
}
// In FTL mode the first section is for the leader, the
@ -304,7 +311,7 @@ int PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
{
*prev = *next = 1;
*weight = 1.0f;
return 1;
return;
}
// Now we have a rank that needs to be interpolated between
@ -314,25 +321,33 @@ int PowerupManager::WeightsData::convertRankToSection(int rank, int *prev,
// special since index 2 is for the first non-leader kart):
int first_section_index = race_manager->isFollowMode() ? 2 : 1;
// Get the lowest rank for which the grouping applies:
int first_section_rank = race_manager->isFollowMode() ? 3 : 2;
// If we have three points, we get 4 sections etc.
// If we have five points, the first and last assigned to the first
// and last kart, leaving 3 points 'inside' this interval, which define
// 4 'sections'. So the number of sections is number_of_points - 2 + 1.
// If the first two points are assigned to rank 1 and 2 in a FTL race
// and the last to the last kart, leaving two inner points defining
// 3 sections, i.e. number_of_points - 3 + 1
// In both cases the number of sections is:
int num_sections = (m_weights_for_section.size() - first_section_index);
float karts_per_fraction = (m_num_karts - first_section_index)
/ float(num_sections);
int count = 0;
while (rank - 1 > (count + 1) * karts_per_fraction)
// Now check in which section the current rank is: Test from the first
// section (section 0) and see if the rank is still greater than the
// next section. If not, the current section is the section to which
// this rank belongs. Otherwise increase section and try again:
int section = 0;
while (rank - first_section_index > (section + 1) * karts_per_fraction)
{
count++;
section++;
}
*prev = first_section_index + count - 1;
*prev = first_section_index + section - 1;
*next = *prev + 1;
*weight = (rank - first_section_index - count * karts_per_fraction)
*weight = (rank - first_section_index - section * karts_per_fraction)
/ karts_per_fraction;
return 1;
return;
} // WeightsData::convertRankToSection
// ----------------------------------------------------------------------------
@ -357,7 +372,7 @@ void PowerupManager::WeightsData::precomputeWeights()
j <= 2 * POWERUP_LAST - POWERUP_FIRST; j++)
{
float av = (1.0f - weight) * m_weights_for_section[prev][j]
+ weight * m_weights_for_section[next][j];
+ weight * m_weights_for_section[next][j];
sum += int(av + 0.5f);
m_summed_weights_for_rank[i].push_back(sum);
}

View File

@ -101,7 +101,7 @@ private:
void reset();
void readData(int num_karts, const XMLNode *node);
void interpolate(WeightsData *prev, WeightsData *next, int num_karts);
int convertRankToSection(int rank, int *prev, int *next,
void convertRankToSection(int rank, int *prev, int *next,
float *weight);
void precomputeWeights();
int getRandomItem(int rank, int random_number);