From 8833ca6bcd56f0694ac23605d69b5fcdb4191a9a Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 8 Jul 2010 01:56:52 +0000 Subject: [PATCH] 1) Added false starts for Ai karts. 2) Adjusted the AI reaction time to be more in synch with what humans do. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5671 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- .../controller/default_ai_controller.cpp | 132 ++++++++++-------- .../controller/default_ai_controller.hpp | 20 +-- 2 files changed, 83 insertions(+), 69 deletions(-) diff --git a/src/karts/controller/default_ai_controller.cpp b/src/karts/controller/default_ai_controller.cpp index 4661abd63..4108e1df9 100644 --- a/src/karts/controller/default_ai_controller.cpp +++ b/src/karts/controller/default_ai_controller.cpp @@ -91,33 +91,42 @@ DefaultAIController::DefaultAIController(Kart *kart) : AIBaseController(kart) switch( race_manager->getDifficulty()) { case RaceManager::RD_EASY: - m_wait_for_players = true; - m_max_handicap_accel = 0.9f; - m_item_tactic = IT_TEN_SECONDS; - m_max_start_delay = 0.5f; - m_min_steps = 1; - m_nitro_level = NITRO_NONE; - m_handle_bomb = false; + m_wait_for_players = true; + m_max_handicap_accel = 0.9f; + m_item_tactic = IT_TEN_SECONDS; + m_false_start_probability = 0.08f; + m_min_start_delay = 0.3f; + m_max_start_delay = 0.5f; + m_min_steps = 1; + m_nitro_level = NITRO_NONE; + m_handle_bomb = false; setSkiddingFraction(4.0f); break; case RaceManager::RD_MEDIUM: - m_wait_for_players = true; - m_max_handicap_accel = 0.95f; - m_item_tactic = IT_CALCULATE; - m_max_start_delay = 0.4f; - m_min_steps = 1; - m_nitro_level = NITRO_SOME; - m_handle_bomb = true; + m_wait_for_players = true; + m_max_handicap_accel = 0.95f; + m_item_tactic = IT_CALCULATE; + m_false_start_probability = 0.04f; + m_min_start_delay = 0.25f; + m_max_start_delay = 0.4f; + m_min_steps = 1; + m_nitro_level = NITRO_SOME; + m_handle_bomb = true; setSkiddingFraction(3.0f); break; case RaceManager::RD_HARD: - m_wait_for_players = false; - m_max_handicap_accel = 1.0f; - m_item_tactic = IT_CALCULATE; - m_max_start_delay = 0.1f; - m_min_steps = 2; - m_nitro_level = NITRO_ALL; - m_handle_bomb = true; + m_wait_for_players = false; + m_max_handicap_accel = 1.0f; + m_item_tactic = IT_CALCULATE; + m_false_start_probability = 0.01f; + // See http://www.humanbenchmark.com/tests/reactiontime/stats.php + // Average reaction time is around 0.215 s, so using .15 as minimum + // gives an AI average slightly above the human average + m_min_start_delay = 0.15f; + m_max_start_delay = 0.28f; + m_min_steps = 2; + m_nitro_level = NITRO_ALL; + m_handle_bomb = true; setSkiddingFraction(2.0f); break; } @@ -138,6 +147,34 @@ DefaultAIController::~DefaultAIController() #endif } // ~DefaultAIController +//----------------------------------------------------------------------------- +void DefaultAIController::reset() +{ + m_time_since_last_shot = 0.0f; + m_start_kart_crash_direction = 0; + m_curve_target_speed = m_kart->getMaxSpeedOnTerrain(); + m_curve_angle = 0.0; + m_start_delay = -1.0f; + m_crash_time = 0.0f; + m_collided = false; + m_time_since_stuck = 0.0f; + m_kart_ahead = NULL; + m_distance_ahead = 0.0f; + m_kart_behind = NULL; + m_distance_behind = 0.0f; + + Controller::reset(); + m_track_node = QuadGraph::UNKNOWN_SECTOR; + m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node); + if(m_track_node==QuadGraph::UNKNOWN_SECTOR) + { + fprintf(stderr, "Invalid starting position for '%s' - not on track - can be ignored.\n", + m_kart->getIdent().c_str()); + m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ()); + } + +} // reset + //----------------------------------------------------------------------------- const irr::core::stringw& DefaultAIController::getNamePostfix() const { @@ -588,12 +625,12 @@ void DefaultAIController::computeNearestKarts() } // computeNearestKarts //----------------------------------------------------------------------------- -void DefaultAIController::handleAcceleration( const float DELTA ) +void DefaultAIController::handleAcceleration( const float dt) { //Do not accelerate until we have delayed the start enough - if( m_time_till_start > 0.0f ) + if( m_start_delay > 0.0f ) { - m_time_till_start -= DELTA; + m_start_delay -= dt; m_controls->m_accel = 0.0f; return; } @@ -637,16 +674,19 @@ void DefaultAIController::handleAcceleration( const float DELTA ) //----------------------------------------------------------------------------- void DefaultAIController::handleRaceStart() { - //FIXME: make karts able to get a penalty for accelerating too soon - //like players, should happen to about 20% of the karts in easy, - //5% in medium and less than 1% of the karts in hard. - if( m_time_till_start < 0.0f ) + if( m_start_delay < 0.0f ) { - srand(( unsigned ) time( 0 )); + // Each kart starts at a different, random time, and the time is + // smaller depending on the difficulty. + m_start_delay = m_min_start_delay + + (float) rand() / RAND_MAX * (m_max_start_delay-m_min_start_delay); - //Each kart starts at a different, random time, and the time is - //smaller depending on the difficulty. - m_time_till_start = ( float ) rand() / RAND_MAX * m_max_start_delay; + // Now check for a false start. If so, add 1 second penalty time. + if(rand() < RAND_MAX * m_false_start_probability) + { + m_start_delay+=stk_config->m_penalty_time; + return; + } } } // handleRaceStart @@ -886,34 +926,6 @@ void DefaultAIController::findNonCrashingPoint(Vec3 *result) } } // findNonCrashingPoint -//----------------------------------------------------------------------------- -void DefaultAIController::reset() -{ - m_time_since_last_shot = 0.0f; - m_start_kart_crash_direction = 0; - m_curve_target_speed = m_kart->getMaxSpeedOnTerrain(); - m_curve_angle = 0.0; - m_time_till_start = -1.0f; - m_crash_time = 0.0f; - m_collided = false; - m_time_since_stuck = 0.0f; - m_kart_ahead = NULL; - m_distance_ahead = 0.0f; - m_kart_behind = NULL; - m_distance_behind = 0.0f; - - Controller::reset(); - m_track_node = QuadGraph::UNKNOWN_SECTOR; - m_quad_graph->findRoadSector(m_kart->getXYZ(), &m_track_node); - if(m_track_node==QuadGraph::UNKNOWN_SECTOR) - { - fprintf(stderr, "Invalid starting position for '%s' - not on track - can be ignored.\n", - m_kart->getIdent().c_str()); - m_track_node = m_quad_graph->findOutOfRoadSector(m_kart->getXYZ()); - } - -} // reset - //----------------------------------------------------------------------------- /** calc_steps() divides the velocity vector by the lenght of the kart, * and gets the number of steps to use for the sight line of the kart. diff --git a/src/karts/controller/default_ai_controller.hpp b/src/karts/controller/default_ai_controller.hpp index aca2ccf7c..85fbc8d2c 100644 --- a/src/karts/controller/default_ai_controller.hpp +++ b/src/karts/controller/default_ai_controller.hpp @@ -60,8 +60,15 @@ private: } m_crashes; /*Difficulty handling variables*/ - float m_max_start_delay; //Delay before accelerating at the start of each - //race + /** Chance of a false start. */ + float m_false_start_probability; + /** The minimum delay time before a AI kart starts. */ + float m_min_start_delay; + /** The maximum delay time before an AI kart starts. */ + float m_max_start_delay; + /** The actual start delay used. */ + float m_start_delay; + int m_min_steps; //Minimum number of steps to check. If 0, the AI doesn't //even has check around the kart, if 1, it checks around //the kart always, and more than that will check the @@ -98,12 +105,7 @@ private: /** Time an item has been collected and not used. */ float m_time_since_last_shot; - - float m_time_till_start; //Used to simulate a delay at the start of the - //race, since human players don't accelerate - //at the same time and rarely repeat the a - //previous timing. - + float m_curve_target_speed; float m_curve_angle; @@ -125,7 +127,7 @@ private: * graph nodes. */ std::vector > m_all_look_aheads; - float m_time_since_stuck; + float m_time_since_stuck; int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash.