Added probability to collect an item for the AI, to allow us

to make it a bit less competitive.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11811 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-10-29 22:06:17 +00:00
parent dca5e568af
commit fb84565bf8
5 changed files with 67 additions and 3 deletions

View File

@ -272,6 +272,9 @@
at. Used to slow down karts that are ahead of the player. at. Used to slow down karts that are ahead of the player.
Note that setting this to a value >1 does NOT increase Note that setting this to a value >1 does NOT increase
the speed the kart can drive at! the speed the kart can drive at!
collect-item-probability: Probability of the AI actually
trying to collect an item (if an item is selected for
collection in the first place).
--> -->
<ai> <ai>
<easy time-full-steer="0.1" <easy time-full-steer="0.1"
@ -286,6 +289,7 @@
speed-cap="5:1.0 20:0.9 50:0.6" speed-cap="5:1.0 20:0.9 50:0.6"
max-item-angle="0.7" max-item-angle-high-speed="0.3" max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6" bad-item-closeness="6"
collect-item-probability="0:0"
rb-skid-probability="0:0.0" rb-skid-probability="0:0.0"
skidding-threshold="4.0" skidding-threshold="4.0"
/> />
@ -301,6 +305,7 @@
speed-cap="10:1.0 50:0.8" speed-cap="10:1.0 50:0.8"
max-item-angle="0.7" max-item-angle-high-speed="0.3" max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6" bad-item-closeness="6"
collect-item-probability="-10:1.0 0:0"
rb-skid-probability="0:0.0" rb-skid-probability="0:0.0"
skidding-threshold="3.0" skidding-threshold="3.0"
/> />
@ -316,6 +321,7 @@
speed-cap="20:1.0 50:0.8" speed-cap="20:1.0 50:0.8"
max-item-angle="0.7" max-item-angle-high-speed="0.3" max-item-angle="0.7" max-item-angle-high-speed="0.3"
bad-item-closeness="6" bad-item-closeness="6"
collect-item-probability="10:1.0 20:0"
rb-skid-probability="-50:1.0 -20:0.7 20:0.2 50:0.0" rb-skid-probability="-50:1.0 -20:0.7 20:0.2 50:0.0"
skidding-threshold="2.0" skidding-threshold="2.0"
/> />

View File

@ -28,6 +28,7 @@ float AIProperties::UNDEFINED = -99.9f;
AIProperties::AIProperties(RaceManager::Difficulty difficulty) AIProperties::AIProperties(RaceManager::Difficulty difficulty)
: m_skid_probability(/*decreasing*/false) : m_skid_probability(/*decreasing*/false)
, m_speed_cap(/*decreasing*/true) , m_speed_cap(/*decreasing*/true)
, m_collect_item_probability(/*decreasing*/true)
{ {
switch(difficulty) switch(difficulty)
{ {
@ -65,6 +66,7 @@ void AIProperties::load(const XMLNode *ai_node)
ai_node->get("max-item-angle-high-speed", &m_max_item_angle_high_speed ); ai_node->get("max-item-angle-high-speed", &m_max_item_angle_high_speed );
ai_node->get("time-full-steer", &m_time_full_steer ); ai_node->get("time-full-steer", &m_time_full_steer );
ai_node->get("bad-item-closeness", &m_bad_item_closeness_2 ); ai_node->get("bad-item-closeness", &m_bad_item_closeness_2 );
ai_node->get("collect-item-probability", &m_collect_item_probability );
ai_node->get("straight-length-for-zipper",&m_straight_length_for_zipper); ai_node->get("straight-length-for-zipper",&m_straight_length_for_zipper);
ai_node->get("rb-skid-probability", &m_skid_probability ); ai_node->get("rb-skid-probability", &m_skid_probability );
ai_node->get("speed-cap", &m_speed_cap ); ai_node->get("speed-cap", &m_speed_cap );
@ -130,6 +132,12 @@ void AIProperties::checkAllSet(const std::string &filename) const
exit(-1); exit(-1);
} }
if(m_collect_item_probability.size()==0)
{
printf("No collect-item-probability defined.\n");
exit(-1);
}
} // checkAllSet } // checkAllSet
/* EOF */ /* EOF */

View File

@ -77,6 +77,9 @@ protected:
/** To cap maximum speed if the kart is ahead of the player. */ /** To cap maximum speed if the kart is ahead of the player. */
InterpolationArray m_speed_cap; InterpolationArray m_speed_cap;
/** To determine the probability of selecting an item. */
InterpolationArray m_collect_item_probability;
/** Probability of a false start. Note that Nolok in boss battle will never /** Probability of a false start. Note that Nolok in boss battle will never
* have a false start. */ * have a false start. */
float m_false_start_probability; float m_false_start_probability;
@ -131,6 +134,13 @@ public:
{ {
return m_speed_cap.get(distance); return m_speed_cap.get(distance);
} // getSpeedCap } // getSpeedCap
// ------------------------------------------------------------------------
/** Returns the probability to collect an item depending on the distance
* to the first player kart. */
float getItemCollectProbability(float distance) const
{
return m_collect_item_probability.get(distance);
} // getItemcollectProbability
}; // AIProperties }; // AIProperties

View File

@ -707,17 +707,45 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point,
} }
} }
// 5) Try to aim for items-to-collect // 5) We are aiming for a new item. If necessary, determine
// randomly if this item sshould actually be collected.
// --------------------------------------------------------
if(items_to_collect.size()>0)
{
if(items_to_collect[0] != m_last_item_random)
{
int p = (int)(100.0f*m_ai_properties->
getItemCollectProbability(m_distance_to_player));
m_really_collect_item = m_random_collect_item.get(100)<p;
m_last_item_random = items_to_collect[0];
}
if(!m_really_collect_item)
{
// The same item was selected previously, but it was randomly
// decided not to collect it - so keep on ignoring this item.
return;
}
}
// Reset the probability if a different (or no) item is selected.
if(items_to_collect.size()==0 || items_to_collect[0]!=m_last_item_random)
m_last_item_random = NULL;
// 6) Try to aim for items-to-collect
// ---------------------------------- // ----------------------------------
if(items_to_collect.size()>0) if(items_to_collect.size()>0)
{ {
const Item *item_to_collect = items_to_collect[0]; const Item *item_to_collect = items_to_collect[0];
// Test if we would hit a bad item when aiming at this good item. // Test if we would hit a bad item when aiming at this good item.
// If so, don't change the aim. In this case it has already been // If so, don't change the aim. In this case it has already been
// ensured that we won't hit the bad item (otherwise steerToAVoid // ensured that we won't hit the bad item (otherwise steerToAvoid
// would have detected this earlier). // would have detected this earlier).
if(!hitBadItemWhenAimAt(item_to_collect, items_to_avoid)) if(!hitBadItemWhenAimAt(item_to_collect, items_to_avoid))
{ {
// If the item is hit (with the current steering), it means
// it's on a good enough driveline, so make this item a permanent
// target. Otherwise only try to get closer (till hopefully this
// item s on our driveline)
if(item_to_collect->hitLine(line_to_target, m_kart)) if(item_to_collect->hitLine(line_to_target, m_kart))
{ {
#ifdef AI_DEBUG #ifdef AI_DEBUG
@ -731,8 +759,10 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point,
item_to_collect->getType()); item_to_collect->getType());
m_item_to_collect = item_to_collect; m_item_to_collect = item_to_collect;
} }
else // kart will not hit item else
{ {
// Kart will not hit item, try to get closer to this item
// so that it can potentially become a permanent target.
Vec3 xyz = item_to_collect->getXYZ(); Vec3 xyz = item_to_collect->getXYZ();
float item_angle = atan2(xyz.getX() - m_kart->getXYZ().getX(), float item_angle = atan2(xyz.getX() - m_kart->getXYZ().getX(),
xyz.getZ() - m_kart->getXYZ().getZ()); xyz.getZ() - m_kart->getXYZ().getZ());

View File

@ -126,6 +126,16 @@ private:
enum {SKID_PROBAB_NOT_YET, SKID_PROBAB_NO_SKID, SKID_PROBAB_SKID} enum {SKID_PROBAB_NOT_YET, SKID_PROBAB_NO_SKID, SKID_PROBAB_SKID}
m_skid_probability_state; m_skid_probability_state;
/** The last item selected for collection, for which a probability
* was determined. */
const Item *m_last_item_random;
/** True if m_last_item_random was randomly selected to be collected. */
bool m_really_collect_item;
/** A random number generator for collecting items. */
RandomGenerator m_random_collect_item;
/** Which of the three Point Selection Algorithms (i.e. /** Which of the three Point Selection Algorithms (i.e.
* findNoNCrashingPoint* functions) to use: * findNoNCrashingPoint* functions) to use:
* the default (which is actually slightly buggy, but so far best one * the default (which is actually slightly buggy, but so far best one