Improved handling of zippers: zippers will now be selected earlier (previously

a kart needed 2.0 nitro in order to use a zipper), but won't be used if items
to avoid are close by (since zipper make it harder to avoid them).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11571 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-09-09 22:41:49 +00:00
parent 633937f979
commit 18d77b9da1
5 changed files with 59 additions and 20 deletions

View File

@ -216,10 +216,13 @@
to avoid hitting a bad item. If the distance is larger, it is to avoid hitting a bad item. If the distance is larger, it is
assumed that there will be enough time to change steering assumed that there will be enough time to change steering
direction. direction.
straight-length-for-zipper is the minimum length a straight
section of the track should have in order to activate a zipper.
--> -->
<ai max-item-angle="0.7" max-item-angle-high-speed="0.3" <ai max-item-angle="0.7" max-item-angle-high-speed="0.3"
time-full-steer="0.1" time-full-steer="0.1"
bad-item-closeness="6" bad-item-closeness="6"
straight-length-for-zipper="35"
/> />
<!-- Slipstream: length: How far behind a kart slipstream works <!-- Slipstream: length: How far behind a kart slipstream works

View File

@ -26,10 +26,11 @@ float AIProperties::UNDEFINED = -99.9f;
*/ */
AIProperties::AIProperties() AIProperties::AIProperties()
{ {
m_max_item_angle = UNDEFINED; m_max_item_angle = UNDEFINED;
m_max_item_angle_high_speed = UNDEFINED; m_max_item_angle_high_speed = UNDEFINED;
m_time_full_steer = UNDEFINED; m_time_full_steer = UNDEFINED;
m_bad_item_closeness_2 = UNDEFINED; m_bad_item_closeness_2 = UNDEFINED;
m_straight_length_for_zipper = UNDEFINED;
} // AIProperties } // AIProperties
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -38,10 +39,11 @@ AIProperties::AIProperties()
*/ */
void AIProperties::load(const XMLNode *ai_node) void AIProperties::load(const XMLNode *ai_node)
{ {
ai_node->get("max-item-angle", &m_max_item_angle ); ai_node->get("max-item-angle", &m_max_item_angle );
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("straight-length-for-zipper",&m_straight_length_for_zipper);
// We actually need the square of the distance later // We actually need the square of the distance later
m_bad_item_closeness_2 *= m_bad_item_closeness_2; m_bad_item_closeness_2 *= m_bad_item_closeness_2;
@ -59,10 +61,11 @@ void AIProperties::checkAllSet(const std::string &filename) const
fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \ fprintf(stderr,"Missing default value for '%s' in '%s'.\n", \
str_a,filename.c_str());exit(-1); \ str_a,filename.c_str());exit(-1); \
} }
CHECK_NEG(m_max_item_angle, "max-item-angle" ); CHECK_NEG(m_max_item_angle, "max-item-angle" );
CHECK_NEG(m_max_item_angle_high_speed, "max-item-angle-high-speed"); CHECK_NEG(m_max_item_angle_high_speed, "max-item-angle-high-speed" );
CHECK_NEG(m_time_full_steer, "time-full-steer" ); CHECK_NEG(m_time_full_steer, "time-full-steer" );
CHECK_NEG(m_bad_item_closeness_2, "bad-item-closeness" ); CHECK_NEG(m_bad_item_closeness_2, "bad-item-closeness" );
CHECK_NEG(m_straight_length_for_zipper,"straight-length-for-zipper");
} // checkAllSet } // checkAllSet

View File

@ -64,6 +64,9 @@ protected:
* of karts). */ * of karts). */
float m_time_full_steer; float m_time_full_steer;
/** Minimum length of a straight in order to activate a zipper. */
float m_straight_length_for_zipper;
public: public:
AIProperties(); AIProperties();

View File

@ -23,7 +23,7 @@
//to 2 in main.cpp with quickstart and run supertuxkart with the arg -N. //to 2 in main.cpp with quickstart and run supertuxkart with the arg -N.
#ifdef DEBUG #ifdef DEBUG
// Enable AeI graphical debugging // Enable AeI graphical debugging
# undef AI_DEBUG # define AI_DEBUG
// Shows left and right lines when using new findNonCrashing function // Shows left and right lines when using new findNonCrashing function
# undef AI_DEBUG_NEW_FIND_NON_CRASHING # undef AI_DEBUG_NEW_FIND_NON_CRASHING
// Show the predicted turn circles // Show the predicted turn circles
@ -31,7 +31,7 @@
// Show the heading of the kart // Show the heading of the kart
# undef AI_DEBUG_KART_HEADING # undef AI_DEBUG_KART_HEADING
// Shows line from kart to its aim point // Shows line from kart to its aim point
# undef AI_DEBUG_KART_AIM # define AI_DEBUG_KART_AIM
#endif #endif
#include "karts/controller/skidding_ai.hpp" #include "karts/controller/skidding_ai.hpp"
@ -196,12 +196,13 @@ SkiddingAI::SkiddingAI(AbstractKart *kart)
m_curve[CURVE_QG] = new ShowCurve(0.5f, 0.5f, m_curve[CURVE_QG] = new ShowCurve(0.5f, 0.5f,
irr::video::SColor(128, 0, 128, 0)); irr::video::SColor(128, 0, 128, 0));
#ifdef AI_DEBUG_KART_AIM #ifdef AI_DEBUG_KART_AIM
irr::video::SColor c1;
if(m_item_behaviour == ITEM_COLLECT_PRIORITY) if(m_item_behaviour == ITEM_COLLECT_PRIORITY)
c = irr::video::SColor(128, 0, 0, 128); c1 = irr::video::SColor(128, 0, 0, 128);
else else
c = irr::video::SColor(128, 0, 128, 0); c1 = irr::video::SColor(128, 0, 128, 0);
m_curve[CURVE_AIM] = new ShowCurve(0.5f, 0.5f, c); m_curve[CURVE_AIM] = new ShowCurve(0.5f, 0.5f, c1);
#endif #endif
#endif #endif
@ -240,6 +241,7 @@ void SkiddingAI::reset()
m_curve_center = Vec3(0,0,0); m_curve_center = Vec3(0,0,0);
m_current_track_direction = GraphNode::DIR_STRAIGHT; m_current_track_direction = GraphNode::DIR_STRAIGHT;
m_item_to_collect = NULL; m_item_to_collect = NULL;
m_avoid_item_close = false;
AIBaseController::reset(); AIBaseController::reset();
m_track_node = QuadGraph::UNKNOWN_SECTOR; m_track_node = QuadGraph::UNKNOWN_SECTOR;
@ -392,11 +394,12 @@ void SkiddingAI::update(float dt)
handleNitroAndZipper(); handleNitroAndZipper();
} }
// If we are supposed to use nitro, but have a zipper, // If we are supposed to use nitro, but have a zipper,
// use the zipper instead // use the zipper instead (unless there are items to avoid cloe by)
if(m_controls->m_nitro && if(m_controls->m_nitro &&
m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER && m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
m_kart->getSpeed()>1.0f && m_kart->getSpeed()>1.0f &&
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0) m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0 &&
!m_avoid_item_close)
{ {
// Make sure that not all AI karts use the zipper at the same // Make sure that not all AI karts use the zipper at the same
// time in time trial at start up, so during the first 5 seconds // time in time trial at start up, so during the first 5 seconds
@ -626,7 +629,7 @@ void SkiddingAI::handleItemCollectionAndAvoidance(Vec3 *aim_point,
if(node==last_node) break; if(node==last_node) break;
} // while (distance < max_item_lookahead_distance) } // while (distance < max_item_lookahead_distance)
m_avoid_item_close = items_to_avoid.size()>0;
core::line2df line_to_target(aim_point->getX(), core::line2df line_to_target(aim_point->getX(),
aim_point->getZ(), aim_point->getZ(),
@ -1396,6 +1399,11 @@ void SkiddingAI::handleNitroAndZipper()
m_item_tactic==IT_TEN_SECONDS ) ) m_item_tactic==IT_TEN_SECONDS ) )
return; return;
// If there are items to avoid close, and we only have zippers, don't
// use them (since this make it harder to avoid items).
if(m_avoid_item_close &&
(m_kart->getEnergy()==0|| m_nitro_level==NITRO_NONE) )
return;
// If a parachute or anvil is attached, the nitro doesn't give much // If a parachute or anvil is attached, the nitro doesn't give much
// benefit. Better wait till later. // benefit. Better wait till later.
const bool has_slowdown_attachment = const bool has_slowdown_attachment =
@ -1459,6 +1467,24 @@ void SkiddingAI::handleNitroAndZipper()
return; return;
} }
if(m_kart->getPowerup()->getType()==PowerupManager::POWERUP_ZIPPER &&
m_kart->getSpeed()>1.0f &&
m_kart->getSpeedIncreaseTimeLeft(MaxSpeed::MS_INCREASE_ZIPPER)<=0)
{
GraphNode::DirectionType dir;
unsigned int last;
const GraphNode &gn = QuadGraph::get()->getNode(m_track_node);
gn.getDirectionData(m_successor_index[m_track_node], &dir, &last);
if(dir==GraphNode::DIR_STRAIGHT)
{
float diff = QuadGraph::get()->getDistanceFromStart(last)
- QuadGraph::get()->getDistanceFromStart(m_track_node);
if(diff<0) diff+=World::getWorld()->getTrack()->getTrackLength();
if(diff>m_ai_properties->m_straight_length_for_zipper)
m_controls->m_fire = true;
}
}
} // handleNitroAndZipper } // handleNitroAndZipper
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View File

@ -146,6 +146,10 @@ private:
/** If set an item that the AI should aim for. */ /** If set an item that the AI should aim for. */
const Item *m_item_to_collect; const Item *m_item_to_collect;
/** True if items to avoid are close by. Used to avoid using zippers
* (which would make it more difficult to avoid items). */
bool m_avoid_item_close;
/** True if the new findNonCrashingPoint2 function should be used. */ /** True if the new findNonCrashingPoint2 function should be used. */
bool m_use_new_aim_point_selection; bool m_use_new_aim_point_selection;