|
| SkiddingAI (AbstractKart *kart) |
|
| ~SkiddingAI () |
| Destructor, mostly to clean up debug data structures.
|
|
virtual void | update (int ticks) |
| This is the main entry point for the AI.
|
|
virtual void | reset () |
| Resets the AI when a race is restarted.
|
|
virtual const irr::core::stringw & | getNamePostfix () const |
| Returns a name for the AI.
|
|
| AIBaseLapController (AbstractKart *kart) |
| This is the base class for all AIs.
|
|
virtual void | reset () |
|
| AIBaseController (AbstractKart *kart) |
|
virtual void | reset () OVERRIDE |
|
virtual bool | disableSlipstreamBonus () const OVERRIDE |
| Certain AI levels will not receive a slipstream bonus in order to be not as hard.
|
|
virtual void | crashed (const Material *m) OVERRIDE |
| This is called when the kart crashed with the terrain.
|
|
virtual void | crashed (const AbstractKart *k) OVERRIDE |
|
virtual void | handleZipper (bool play_sound) OVERRIDE |
|
virtual void | finishedRace (float time) OVERRIDE |
| Called whan this controller's kart finishes the last lap.
|
|
virtual void | collectedItem (const ItemState &item, float previous_energy=0) OVERRIDE |
|
virtual void | setPosition (int p) OVERRIDE |
|
virtual bool | isPlayerController () const OVERRIDE |
| This function checks if this player is not an AI, i.e.
|
|
virtual bool | isLocalPlayerController () const OVERRIDE |
| This function checks if this is a local player.
|
|
virtual bool | action (PlayerAction action, int value, bool dry_run=false) OVERRIDE |
| Default: ignore actions.
|
|
virtual void | skidBonusTriggered () OVERRIDE |
|
virtual bool | saveState (BareNetworkString *buffer) const OVERRIDE |
|
virtual void | rewindTo (BareNetworkString *buffer) OVERRIDE |
|
void | setNetworkAI (bool val) |
|
virtual void | update (int ticks) OVERRIDE |
|
| Controller (AbstractKart *kart) |
| Constructor, saves the kart pointer and a pointer to the KartControl of the kart.
|
|
virtual void | reset ()=0 |
|
virtual void | update (int ticks)=0 |
|
virtual void | handleZipper (bool play_sound)=0 |
|
virtual void | collectedItem (const ItemState &item, float previous_energy=0)=0 |
|
virtual void | crashed (const AbstractKart *k)=0 |
|
virtual void | crashed (const Material *m)=0 |
|
virtual void | setPosition (int p)=0 |
|
virtual bool | isLocalPlayerController () const =0 |
| This function checks if this is a local player.
|
|
virtual bool | isPlayerController () const =0 |
| This function checks if this player is not an AI, i.e.
|
|
virtual bool | disableSlipstreamBonus () const =0 |
|
virtual bool | saveState (BareNetworkString *buffer) const =0 |
|
virtual void | rewindTo (BareNetworkString *buffer)=0 |
|
virtual void | rumble (float strength_low, float strength_high, uint16_t duration) |
|
virtual void | setControllerName (const std::string &name) |
| Sets the controller name for this controller.
|
|
const std::string & | getControllerName () const |
| Returns the name of this controller.
|
|
virtual bool | action (PlayerAction action, int value, bool dry_run=false)=0 |
| Default: ignore actions.
|
|
virtual void | newLap (int lap)=0 |
| Callback whenever a new lap is triggered.
|
|
virtual void | skidBonusTriggered ()=0 |
|
virtual void | finishedRace (float time)=0 |
| Called whan this controller's kart finishes the last lap.
|
|
virtual KartControl * | getControls () |
| Get a pointer on the kart controls.
|
|
void | setControls (KartControl *kc) |
|
virtual bool | canGetAchievements () const |
| Only local players can get achievements.
|
|
virtual core::stringw | getName (bool include_handicap_string=true) const |
| Display name of the controller.
|
|
AbstractKart * | getKart () const |
| Returns the kart controlled by this controller.
|
|
|
virtual unsigned int | getNextSector (unsigned int index) |
| Returns the pre-computed successor of a graph node.
|
|
virtual void | update (int ticks) |
| Updates the ai base controller each time step.
|
|
virtual unsigned int | getNextSector (unsigned int index) |
| Returns the next sector of the given sector index.
|
|
virtual void | newLap (int lap) |
| Triggers a recomputation of the path to use, so that the AI does not always use the same way.
|
|
float | steerToAngle (const unsigned int sector, const float angle) |
| This function steers towards a given angle.
|
|
void | computePath () |
| Computes a path for the AI to follow.
|
|
virtual void | raceFinished () |
| Nothing special to do when the race is finished.
|
|
void | setControllerName (const std::string &name) OVERRIDE |
| In debug mode when the user specified –ai-debug on the command line set the name of the controller as on-screen text, so that the different AI controllers can be distinguished.
|
|
float | steerToPoint (const Vec3 &point) |
| Computes the steering angle to reach a certain point.
|
|
float | normalizeAngle (float angle) |
| Normalises an angle to be between -pi and _ pi.
|
|
bool | isStuck () const |
| This can be called to detect if the kart is stuck (i.e.
|
|
void | determineTurnRadius (const Vec3 &end, Vec3 *center, float *radius) const |
| Determine the center point and radius of a circle given two points on the circle and the tangent at the first point.
|
|
virtual void | setSteering (float angle, float dt) |
| Converts the steering angle to a lr steering in the range of -1 to 1.
|
|
virtual bool | canSkid (float steer_fraction)=0 |
| Return true if AI can skid now.
|
|
|
void | handleRaceStart () |
|
void | handleAccelerationAndBraking (int ticks) |
| Determines if the AI should accelerate or not, and if not if it should brake.
|
|
void | handleSteering (float dt) |
| Decides in which direction to steer.
|
|
int | computeSkill (SkillType type) |
| Returns the AI skill value used by the kart.
|
|
void | handleItems (const float dt, const Vec3 *aim_point, int last_node, int item_skill) |
| Handle all items depending on the chosen strategy.
|
|
void | handleBubblegum (int item_skill, const std::vector< const ItemState * > &items_to_collect, const std::vector< const ItemState * > &items_to_avoid) |
| Handle bubblegum depending on the chosen strategy Level 2 : Use the shield immediately after a wait time Level 3 : Use the shield against flyables except cakes.
|
|
void | handleCake (int item_skill) |
| Handle cake depending on the chosen strategy Level 2 : Use the cake against any close vulnerable enemy, with priority to those ahead and close, check if the enemy is roughly ahead.
|
|
void | handleBowling (int item_skill) |
| Handle the bowling ball depending on the chosen strategy Level 2 : Use the bowling ball against enemies straight ahead or straight behind, and not invulnerable, with a 5 second delay Level 3 : Only 3 seconds of delay Level 4 : Same as level 3 Level 5 : Level 4 and don't fire on a shielded kart if we're just behind (gum)
|
|
void | handleSwatter (int item_skill) |
| Handle the swatter depending on the chosen strategy Level 2 : Use the swatter immediately after a wait time Level 3 : Use the swatter when enemies are close Level 4 : Level 3 and use the swatter to remove bad attachments Level 5 : Level 4 and use against bomb only when the timer ends.
|
|
void | handleSwitch (int item_skill, const std::vector< const ItemState * > &items_to_collect, const std::vector< const ItemState * > &items_to_avoid) |
| Handle switch depending on the chosen strategy Level 2 : Use the switch after a wait time Level 3 : Same as level 2 but don't fire if close to a good item Level 4 : Same as level 3 and fire if very close to a bad item Level 5 : Use if it makes a better item available, or if very close to a bad item.
|
|
void | handleRescue (const float dt) |
|
void | handleBraking (float max_turn_speed, float min_speed) |
| This function decides if the AI should brake.
|
|
void | handleNitroAndZipper (float max_safe_speed) |
| Decides wether to use nitro and zipper or not.
|
|
void | computeNearestKarts () |
| Determines the closest karts just behind and in front of this kart.
|
|
void | handleItemCollectionAndAvoidance (Vec3 *aim_point, int last_node) |
| Decides if the currently selected aim at point (as determined by handleSteering) should be changed in order to collect/avoid an item.
|
|
bool | handleSelectedItem (Vec3 kart_aim_direction, Vec3 *aim_point) |
| This function is called when the AI is trying to hit an item that is pre-selected to be collected.
|
|
bool | steerToAvoid (const std::vector< const ItemState * > &items_to_avoid, const core::line3df &line_to_target, Vec3 *aim_point) |
| Decides if steering is necessary to avoid bad items.
|
|
bool | hitBadItemWhenAimAt (const ItemState *item, const std::vector< const ItemState * > &items_to_avoid) |
| Returns true if the AI would hit any of the listed bad items when trying to drive towards the specified item.
|
|
void | evaluateItems (const ItemState *item, Vec3 kart_aim_direction, std::vector< const ItemState * > *items_to_avoid, std::vector< const ItemState * > *items_to_collect) |
| This subroutine decides if the specified item should be collected, avoided, or ignored.
|
|
void | checkCrashes (const Vec3 &pos) |
|
void | findNonCrashingPointNew (Vec3 *result, int *last_node) |
| This is a new version of findNonCrashingPoint, which at this stage is slightly inferior (though faster and more correct) than the original version - the original code cuts corner more aggressively than this version (and in most cases cuting the corner does not end in a collision, so it's actually faster).
|
|
void | findNonCrashingPoint (Vec3 *result, int *last_node) |
| This is basically the original AI algorithm.
|
|
void | determineTrackDirection () |
| Determines the direction of the track ahead of the kart: 0 indicates straight, +1 right turn, -1 left turn.
|
|
virtual bool | canSkid (float steer_fraction) |
| Determines if the kart should skid.
|
|
virtual void | setSteering (float angle, float dt) |
| Converts the steering angle to a lr steering in the range of -1 to 1.
|
|
void | handleCurve () |
| If the kart is at/in a curve, determine the turn radius.
|
|
|
class SkiddingAI::CrashTypes | m_crashes |
|
RaceManager::AISuperPower | m_superpower |
|
AbstractKart * | m_kart_ahead |
| Pointer to the closest kart ahead of this kart.
|
|
float | m_distance_ahead |
| Distance to the kart ahead.
|
|
AbstractKart * | m_kart_behind |
| Pointer to the closest kart behind this kart.
|
|
float | m_distance_behind |
| Distance to the kard behind.
|
|
float | m_distance_leader |
| Distance to the leader kart (used only in FTL) If this kart is leader, contains a high value to avoid the leader slowing down.
|
|
int | m_start_delay |
| The actual start delay used in ticks.
|
|
float | m_time_since_last_shot |
| Time an item has been collected and not used.
|
|
float | m_time_since_stuck |
|
int | m_start_kart_crash_direction |
| Direction of crash: -1 = left, 1 = right, 0 = no crash.
|
|
DriveNode::DirectionType | m_current_track_direction |
| The direction of the track where the kart is on atm.
|
|
float | m_current_curve_radius |
| The radius of the curve the kart is currently driving.
|
|
Vec3 | m_curve_center |
| Stores the center of the curve (if the kart is in a curve, otherwise undefined).
|
|
unsigned int | m_last_direction_node |
| The index of the last node with the same direction as the current node the kart is on.
|
|
const ItemState * | m_item_to_collect |
| If set an item that the AI should aim for.
|
|
bool | m_avoid_item_close |
| True if items to avoid are close by.
|
|
float | m_distance_to_player |
| Distance to the player, used for rubber-banding.
|
|
int | m_num_players_ahead |
| Number of players ahead, used for rubber-banding.
|
|
bool | m_burster |
| This bool allows to make the AI use nitro by series of two bursts.
|
|
RandomGenerator | m_random_skid |
| A random number generator to decide if the AI should skid or not.
|
|
enum SkiddingAI:: { ... } | m_skid_probability_state |
| This implements a simple finite state machine: it starts in NOT_YET.
|
|
const ItemState * | m_last_item_random |
| The last item selected for collection, for which a probability was determined.
|
|
bool | m_really_collect_item |
| True if m_last_item_random was randomly selected to be collected.
|
|
RandomGenerator | m_random_collect_item |
| A random number generator for collecting items.
|
|
enum SkiddingAI:: { ... } | m_point_selection_algorithm |
| Determines the algorithm to use to select the point-to-aim-for There are two different Point Selection Algorithms:
|
|
ItemManager * | m_item_manager |
|
|
static void | enableDebug () |
|
static void | setTestAI (int n) |
|
static int | getTestAI () |
|
int | m_track_node |
| The current node the kart is on.
|
|
LinearWorld * | m_world |
| Keep a pointer to world.
|
|
std::vector< int > | m_successor_index |
| Which of the successors of a node was selected by the AI.
|
|
std::vector< int > | m_next_node_index |
| For each node in the graph this list contains the chosen next node.
|
|
std::vector< std::vector< int > > | m_all_look_aheads |
| For each graph node this list contains a list of the next X graph nodes.
|
|
bool | m_enabled_network_ai |
|
float | m_kart_length |
| Length of the kart, storing it here saves many function calls.
|
|
float | m_kart_width |
| Cache width of kart.
|
|
Track * | m_track |
| Keep a pointer to the track to reduce calls.
|
|
const AIProperties * | m_ai_properties |
| A pointer to the AI properties for this kart.
|
|
AbstractKart * | m_kart |
| Pointer to the kart that is controlled by this controller.
|
|
KartControl * | m_controls |
| A pointer to the main controller, from which the kart takes it commands.
|
|
std::string | m_controller_name |
| The name of the controller, mainly used for debugging purposes.
|
|
static bool | m_ai_debug = false |
|
static int | m_test_ai = 0 |
| Stores the '–test-ai=n' command line parameter: It indicates which fraction of the AIs are going to be the test AI: 1 means only to use the TestAI, 2 means every second AI will be test etc.
|
|
This is the actual racing AI.
The main entry point, called once per frame for each AI, is update(). After handling some standard cases (race start, AI being rescued) the AI does the following steps:
- compute nearest karts (one ahead and one behind)
- check if the kart is about to crash with another kart or the track. This is done by simply testing a certain number of timesteps ahead and estimating the future position of any kart by using current_position + velocity * time (so turns are not taken into account). It also checks if the kart would be outside the quad graph, which indicates a 'collision with track' (though technically this only means the kart would be off track). This information is stored in the m_crashes data structure.
- Determine track direction (straight, left, or right), which the function determineTrackDirection stores in m_current_track_direction
- If the kart has a bomb attached, it will try to hit the kart ahead, using nitro if necessary. The kart will aim at the target kart, nothing els is done (idea: if the kart has a plunger, fire it).
- Otherwise, the AI will:
- set acceleration (handleAcceleration)
- decide where to steer to (handleSteering()): it will first check if it is outside of the track, and if so, steer towards the center of the next quad. If it was detected that the AI is going to hit another kart, it will try to avoid this. Otherwise it will aim at the center of the quad furthest away so that a straight line from the current position to this center is on track (see findNonCrashingPoint). There are actually three different implementations of this, but the (somewhat buggy) default one results in reality with the best AI behaviour. The function handleSteering() then calls setSteering() to set the actually steering amount. The latter function also decides if skidding should be done or not (by calling canSkid()).
- decide if to try to collect or avoid items (handeItems). It considers all items on quads between the current quad of the kart and the quad the AI is aiming at (see handleSteering). If it finds an item to collect, it pre-selects this items, which means it will not select another item for collection until this pre-selected item is clearly uncollectable (gone or too far out of the way). This avoids problems that the AI is between two items it can collects, and keeps switching between both items, at the end missing both.
- detects if the AI is stuck and needs rescue (handleRescue)
- decides if it needs to brake (handlebraking)
- decides if nitro or zipper should be used
- Finally, it checks if it has a zipper but selected to use nitro, and under certain circumstances will use zipper instead of nitro.
void SkiddingAI::findNonCrashingPointNew |
( |
Vec3 * |
result, |
|
|
int * |
last_node |
|
) |
| |
|
private |
This is a new version of findNonCrashingPoint, which at this stage is slightly inferior (though faster and more correct) than the original version - the original code cuts corner more aggressively than this version (and in most cases cuting the corner does not end in a collision, so it's actually faster).
This version find the point furthest ahead which can be reached by travelling in a straight direction from the current location of the kart. This is done by using two lines: one from the kart to the lower left side of the next quad, and one from the kart to the lower right side of the next quad. The area between those two lines can be reached by the kart in a straight line, and will not go off track (assuming that the kart is on track). Then the next quads are tested: New left/right lines are computed. If the new left line is to the right of the old left line, the new left line becomes the current left line:
X The new left line connecting kart to X will be to the right
\ / of the old left line, so the available area for the kart
\ / will be dictated by the new left line.
\ /
kart
Similarly for the right side. This will narrow down the available area the kart can aim at, till finally the left and right line overlap. All points between the connection of the two end points of the left and right line can be reached without getting off track. Which point the kart aims at then depends on the direction of the track: if there is a left turn, the kart will aim to the left point (and vice versa for right turn) - slightly offset by the width of the kart to avoid that the kart is getting off track.
- Parameters
-
aim_position | The point to aim for, i.e. the point that can be driven to in a straight line. |
last_node | The graph node index in which the aim_position is. |