Added a new 'testing ai', which can be started using a command line
option to either test it in play against computer, or in AI against AI races. Atm the test_ai is nearly identical to the skidding ai, except for one brake statement that needs to be investigated.
This commit is contained in:
parent
c1445386b2
commit
2745e42935
@ -218,6 +218,7 @@ protected:
|
||||
// ------------------------------------------------------------------------
|
||||
// Some convenient functions for the AI only
|
||||
friend class SkiddingAI;
|
||||
friend class TestAI;
|
||||
/** Returns true if the specified line segment would come close enough
|
||||
* to this item so that this item would be collected.
|
||||
* \param line The line segment which is tested if it is close enough
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <assert.h>
|
||||
|
||||
bool AIBaseController::m_ai_debug = false;
|
||||
int AIBaseController::m_test_ai = 0;
|
||||
|
||||
AIBaseController::AIBaseController(AbstractKart *kart)
|
||||
: Controller(kart)
|
||||
|
@ -57,6 +57,13 @@ protected:
|
||||
|
||||
static bool m_ai_debug;
|
||||
|
||||
/** 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. Used
|
||||
* for AI testing only. */
|
||||
static int m_test_ai;
|
||||
|
||||
/** Position info structure of targets. */
|
||||
struct posData {bool behind; bool on_side; float angle; float distance;};
|
||||
|
||||
@ -79,6 +86,8 @@ public:
|
||||
virtual bool disableSlipstreamBonus() const;
|
||||
virtual void crashed(const Material *m);
|
||||
static void enableDebug() {m_ai_debug = true; }
|
||||
static void setTestAI(int n) {m_test_ai = n; }
|
||||
static int getTestAI() { return m_test_ai; }
|
||||
virtual void crashed(const AbstractKart *k) {};
|
||||
virtual void handleZipper(bool play_sound) {};
|
||||
virtual void finishedRace(float time) {};
|
||||
|
@ -46,6 +46,7 @@ protected:
|
||||
friend class AIBaseLapController;
|
||||
friend class SkiddingAI;
|
||||
friend class ArenaAI;
|
||||
friend class TestAI;
|
||||
|
||||
/** Used to check that all values are defined in the xml file. */
|
||||
static float UNDEFINED;
|
||||
|
2496
src/karts/controller/test_ai.cpp
Normal file
2496
src/karts/controller/test_ai.cpp
Normal file
File diff suppressed because it is too large
Load Diff
246
src/karts/controller/test_ai.hpp
Normal file
246
src/karts/controller/test_ai.hpp
Normal file
@ -0,0 +1,246 @@
|
||||
|
||||
//
|
||||
// SuperTuxKart - a fun racing game with go-kart
|
||||
// Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
|
||||
// Copyright (C) 2006-2015 Eduardo Hernandez Munoz
|
||||
// Copyright (C) 2010-2015 Joerg Henrichs
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 3
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
#ifndef HEADER_TEST_AI_HPP
|
||||
#define HEADER_TEST_AI_HPP
|
||||
|
||||
|
||||
// Some debugging features for the AI. For example you can visualise the
|
||||
// point the AI is aiming at, or visualise the curve the AI is predicting.
|
||||
// It works best with just 1 AI kart, so set the number of karts
|
||||
// to 2 in main.cpp with quickstart and run supertuxkart with the arg -N.
|
||||
// Or use --profile-laps=99 and run just one AI. Using the debug camera
|
||||
// (top view) is useful, too
|
||||
|
||||
#ifdef DEBUG
|
||||
// Enable AI graphical debugging
|
||||
# undef AI_DEBUG
|
||||
// Shows left and right lines when using new findNonCrashing function
|
||||
# undef AI_DEBUG_NEW_FIND_NON_CRASHING
|
||||
// Show the predicted turn circles
|
||||
# undef AI_DEBUG_CIRCLES
|
||||
// Show the heading of the kart
|
||||
# undef AI_DEBUG_KART_HEADING
|
||||
// Shows line from kart to its aim point
|
||||
# undef AI_DEBUG_KART_AIM
|
||||
#endif
|
||||
|
||||
|
||||
#include "karts/controller/ai_base_lap_controller.hpp"
|
||||
#include "race/race_manager.hpp"
|
||||
#include "tracks/graph_node.hpp"
|
||||
#include "utils/random_generator.hpp"
|
||||
|
||||
#ifdef AI_DEBUG
|
||||
class ShowCurve;
|
||||
|
||||
namespace irr
|
||||
{
|
||||
namespace scene
|
||||
{
|
||||
class ISceneNode;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** This is a test version of the AI, which can be used to create new
|
||||
* AIs, and compare them with the current AI. It is otherwise (at this
|
||||
* stage) identical to the Skidding AI.
|
||||
\ingroup controller
|
||||
*/
|
||||
|
||||
class TestAI : public AIBaseLapController
|
||||
{
|
||||
private:
|
||||
|
||||
class CrashTypes
|
||||
{
|
||||
public:
|
||||
|
||||
bool m_road; //true if we are going to 'crash' with the bounds of the road
|
||||
int m_kart; //-1 if no crash, pos numbers are the kart it crashes with
|
||||
CrashTypes() : m_road(false), m_kart(-1) {};
|
||||
void clear() {m_road = false; m_kart = -1;}
|
||||
} m_crashes;
|
||||
|
||||
RaceManager::AISuperPower m_superpower;
|
||||
|
||||
/*General purpose variables*/
|
||||
|
||||
/** Pointer to the closest kart ahead of this kart. NULL if this
|
||||
* kart is first. */
|
||||
AbstractKart *m_kart_ahead;
|
||||
|
||||
/** Distance to the kart ahead. */
|
||||
float m_distance_ahead;
|
||||
|
||||
/** Pointer to the closest kart behind this kart. NULL if this kart
|
||||
* is last. */
|
||||
AbstractKart *m_kart_behind;
|
||||
|
||||
/** Distance to the kard behind. */
|
||||
float m_distance_behind;
|
||||
|
||||
/** The actual start delay used. */
|
||||
float m_start_delay;
|
||||
|
||||
/** Time an item has been collected and not used. */
|
||||
float m_time_since_last_shot;
|
||||
|
||||
float m_time_since_stuck;
|
||||
|
||||
/** Direction of crash: -1 = left, 1 = right, 0 = no crash. */
|
||||
int m_start_kart_crash_direction;
|
||||
|
||||
/** The direction of the track where the kart is on atm. */
|
||||
GraphNode::DirectionType m_current_track_direction;
|
||||
|
||||
/** The radius of the curve the kart is currently driving. Undefined
|
||||
* when being on a straigt section. */
|
||||
float m_current_curve_radius;
|
||||
|
||||
/** Stores the center of the curve (if the kart is in a curve,
|
||||
* otherwise undefined). */
|
||||
Vec3 m_curve_center;
|
||||
|
||||
/** The index of the last node with the same direction as the current
|
||||
* node the kart is on. If kart is in a left turn, this will be
|
||||
* the last node that is still turning left etc. */
|
||||
unsigned int m_last_direction_node;
|
||||
|
||||
/** If set an item that the AI should aim for. */
|
||||
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;
|
||||
|
||||
/** Distance to the player, used for rubber-banding. */
|
||||
float m_distance_to_player;
|
||||
|
||||
/** A random number generator to decide if the AI should skid or not. */
|
||||
RandomGenerator m_random_skid;
|
||||
|
||||
/** 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 (depending on skid probability) to NO_SKID or SKID.
|
||||
* As long as the AI keeps on deciding to 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** \brief Determines the algorithm to use to select the point-to-aim-for
|
||||
* There are three different Point Selection Algorithms:
|
||||
* 1. findNonCrashingPoint() is the default (which is actually slightly
|
||||
* buggy, but so far best one after handling of 90 degree turns was
|
||||
* added).
|
||||
* 2. findNonCrashingPointFixed() which fixes the bugs of the default
|
||||
* algorithm.
|
||||
* 3. findNonCrashingPointNew() A newly designed algorithm, which is
|
||||
* faster than the standard one, but does not give as good results
|
||||
* as the 'buggy' one.
|
||||
*
|
||||
* So far the default one has by far the best performance, even though
|
||||
* it has bugs. */
|
||||
enum {PSA_DEFAULT, PSA_FIXED, PSA_NEW}
|
||||
m_point_selection_algorithm;
|
||||
|
||||
#ifdef AI_DEBUG
|
||||
/** For skidding debugging: shows the estimated turn shape. */
|
||||
ShowCurve **m_curve;
|
||||
|
||||
/** For debugging purpose: a sphere indicating where the AI
|
||||
* is targeting at. */
|
||||
irr::scene::ISceneNode *m_debug_sphere[4];
|
||||
|
||||
/** For item debugging: set to the item that is selected to
|
||||
* be collected. */
|
||||
irr::scene::ISceneNode *m_item_sphere;
|
||||
#endif
|
||||
|
||||
|
||||
/*Functions called directly from update(). They all represent an action
|
||||
*that can be done, and end up setting their respective m_controls
|
||||
*variable, except handle_race_start() that isn't associated with any
|
||||
*specific action (more like, associated with inaction).
|
||||
*/
|
||||
void handleRaceStart();
|
||||
void handleAcceleration(const float dt);
|
||||
void handleSteering(float dt);
|
||||
void handleItems(const float dt);
|
||||
void handleRescue(const float dt);
|
||||
void handleBraking();
|
||||
void handleNitroAndZipper();
|
||||
void computeNearestKarts();
|
||||
void handleItemCollectionAndAvoidance(Vec3 *aim_point,
|
||||
int last_node);
|
||||
bool handleSelectedItem(float kart_aim_angle, Vec3 *aim_point);
|
||||
bool steerToAvoid(const std::vector<const Item *> &items_to_avoid,
|
||||
const core::line2df &line_to_target,
|
||||
Vec3 *aim_point);
|
||||
bool hitBadItemWhenAimAt(const Item *item,
|
||||
const std::vector<const Item *> &items_to_avoid);
|
||||
void evaluateItems(const Item *item, float kart_aim_angle,
|
||||
std::vector<const Item *> *items_to_avoid,
|
||||
std::vector<const Item *> *items_to_collect);
|
||||
|
||||
void checkCrashes(const Vec3& pos);
|
||||
void findNonCrashingPointFixed(Vec3 *result, int *last_node);
|
||||
void findNonCrashingPointNew(Vec3 *result, int *last_node);
|
||||
void findNonCrashingPoint(Vec3 *result, int *last_node);
|
||||
|
||||
void determineTrackDirection();
|
||||
void determineTurnRadius(const Vec3 &start,
|
||||
const Vec3 &start_direction,
|
||||
const Vec3 &end,
|
||||
Vec3 *center,
|
||||
float *radius);
|
||||
virtual bool canSkid(float steer_fraction);
|
||||
virtual void setSteering(float angle, float dt);
|
||||
void handleCurve();
|
||||
|
||||
protected:
|
||||
virtual unsigned int getNextSector(unsigned int index);
|
||||
|
||||
public:
|
||||
TestAI(AbstractKart *kart);
|
||||
~TestAI();
|
||||
virtual void update (float delta) ;
|
||||
virtual void reset ();
|
||||
virtual const irr::core::stringw& getNamePostfix() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
@ -531,6 +531,9 @@ void cmdLineHelp()
|
||||
// " --history=n Replay history file 'history.dat' using:\n"
|
||||
// " n=1: recorded positions\n"
|
||||
// " n=2: recorded key strokes\n"
|
||||
// " --test-ai=n Use the test-ai for every n-th AI kart.\n"
|
||||
// " (so n=1 means all Ais will be the test ai)\n"
|
||||
// "
|
||||
" --server=name Start a server (not a playing client).\n"
|
||||
" --lan-server=name Start a LAN server (not a playing client).\n"
|
||||
" --server-password= Sets a password for a server (both client&server).\n"
|
||||
@ -763,6 +766,8 @@ int handleCmdLine()
|
||||
UserConfigParams::m_rendering_debug=true;
|
||||
if(CommandLine::has("--ai-debug"))
|
||||
AIBaseController::enableDebug();
|
||||
if(CommandLine::has("--test-ai", &n))
|
||||
AIBaseController::setTestAI(n);
|
||||
if (CommandLine::has("--fps-debug"))
|
||||
UserConfigParams::m_fps_debug = true;
|
||||
|
||||
|
@ -61,6 +61,12 @@ MainLoop::~MainLoop()
|
||||
*/
|
||||
float MainLoop::getLimitedDt()
|
||||
{
|
||||
// In profile mode without graphics, run with a fixed dt of 1/60
|
||||
if (ProfileWorld::isProfileMode() && ProfileWorld::isNoGraphics())
|
||||
{
|
||||
return 1.0f/60.0f;
|
||||
}
|
||||
|
||||
IrrlichtDevice* device = irr_driver->getDevice();
|
||||
m_prev_time = m_curr_time;
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "karts/controller/end_controller.hpp"
|
||||
#include "karts/controller/local_player_controller.hpp"
|
||||
#include "karts/controller/skidding_ai.hpp"
|
||||
#include "karts/controller/test_ai.hpp"
|
||||
#include "karts/controller/network_player_controller.hpp"
|
||||
#include "karts/kart.hpp"
|
||||
#include "karts/kart_properties_manager.hpp"
|
||||
@ -384,6 +385,11 @@ Controller* World::loadAIController(AbstractKart *kart)
|
||||
switch(turn)
|
||||
{
|
||||
case 0:
|
||||
// If requested, start the test ai
|
||||
if( (AIBaseController::getTestAI()!=0 ) &&
|
||||
( (kart->getWorldKartId()+1) % AIBaseController::getTestAI() )==0)
|
||||
controller = new TestAI(kart);
|
||||
else
|
||||
controller = new SkiddingAI(kart);
|
||||
break;
|
||||
case 1:
|
||||
|
Loading…
Reference in New Issue
Block a user