Fixed sing a skidding probability (before the random number

was tested each frame, making it mostly certain that skidding
was done).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@11748 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-10-23 21:13:17 +00:00
parent 1006d04cf5
commit c5720e7925
2 changed files with 26 additions and 19 deletions

View File

@ -185,6 +185,7 @@ void SkiddingAI::reset()
m_current_track_direction = GraphNode::DIR_STRAIGHT;
m_item_to_collect = NULL;
m_avoid_item_close = false;
m_skid_probability_state = SKID_PROBAB_NOT_YET;
AIBaseController::reset();
m_track_node = QuadGraph::UNKNOWN_SECTOR;
@ -2172,35 +2173,36 @@ bool SkiddingAI::doSkid(float steer_fraction)
void SkiddingAI::setSteering(float angle, float dt)
{
float steer_fraction = angle / m_kart->getMaxSteerAngle();
// Use a simple finite state machine to make sure to randomly decide
// whether to skid or not only once per skid section. See docs for
// m_skid_probability_state for more details.
if(!doSkid(steer_fraction))
{
m_tried_skid_last_frame = false;
m_controls->m_skid = KartControl::SC_NONE;
m_skid_probability_state = SKID_PROBAB_NOT_YET;
m_controls->m_skid = KartControl::SC_NONE;
}
else
{
KartControl::SkidControl sc = steer_fraction > 0
? KartControl::SC_RIGHT
: KartControl::SC_LEFT;
if(!m_tried_skid_last_frame)
if(m_skid_probability_state==SKID_PROBAB_NOT_YET)
{
float distance =
m_world->getOverallDistance(m_kart->getWorldKartId())
- m_distance_to_player;
int prob = (int)
(100.0f*m_ai_properties->getSkiddingProbability(distance));
if(m_random_skid.get(100)>=prob)
sc = KartControl::SC_NONE;
int prob = (int)(100.0f*m_ai_properties
->getSkiddingProbability(m_distance_to_player));
m_skid_probability_state = (m_random_skid.get(100)>=prob)
? SKID_PROBAB_SKID
: SKID_PROBAB_NO_SKID;
#undef PRINT_SKID_STATS
#ifdef PRINT_SKID_STATS
printf("%s distance %f prob %d skidding %s\n",
m_kart->getIdent().c_str(), distance, prob,
sc==0 ? "no" : sc==KartControl::SC_LEFT ? "left" : "right");
sc= ? "no" : sc==KartControl::SC_LEFT ? "left" : "right");
#endif
}
m_controls->m_skid = sc;
m_tried_skid_last_frame = true;
m_controls->m_skid = m_skid_probability_state == SKID_PROBAB_SKID
? sc : KartControl::SC_NONE;
}
// Adjust steer fraction in case to be in [-1,1]

View File

@ -115,11 +115,16 @@ private:
/** A random number generator to decide if the AI should skid or not. */
RandomGenerator m_random_skid;
/** True if the AI decided to skid in the previous frame. At the
* beginning of each skid it is randomly decided if the skid is
* to be done or not (to rubber-band the AI). This flag is used
* to decide if a new skid is happening. */
bool m_tried_skid_last_frame;
/** This implements a simple finite state machine: it starts in
* NOT_YET. The first time the AI decides to skid, the state is changed
* randomly (dependeng on skid probability) to N_SKID or SKID.
* As long as the AI keeps on deciding the skid, the state remains
* unchanged (so no new random decision is made) till it decides
* not to skid. In which case the state is set to NOT_YET again.
* This guarantees that for each 'skidable' section of the track
* the random decision is only done once. */
enum {SKID_PROBAB_NOT_YET, SKID_PROBAB_NO_SKID, SKID_PROBAB_SKID}
m_skid_probability_state;
/** Which of the three Point Selection Algorithms (i.e.
* findNoNCrashingPoint* functions) to use: