From b5d7d2b506a775e1a5ef043a69a92ca3260c8692 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Sun, 24 May 2009 10:58:45 +0000 Subject: [PATCH] Improved handling of using the same quad more than once (note: since esp. findOutOfRoadSector is not yet converted to use the quad graph structure, bugs and crashes can occur in some circumstances). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3539 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/robots/default_robot.cpp | 30 +++++++++++++++++++-- src/robots/default_robot.hpp | 3 +++ src/tracks/graph_node.cpp | 2 ++ src/tracks/quad_graph.cpp | 51 +++++++++++++----------------------- src/tracks/quad_graph.hpp | 2 +- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/src/robots/default_robot.cpp b/src/robots/default_robot.cpp index 3d276febc..6edc564ff 100644 --- a/src/robots/default_robot.cpp +++ b/src/robots/default_robot.cpp @@ -70,6 +70,26 @@ DefaultRobot::DefaultRobot(const std::string& kart_name, m_successor_index.push_back(indx); m_next_quad_index.push_back(next[indx]); } + const int look_ahead=10; + // Now compute for each node in the graph the list of the next 'look_ahead' + // graph nodes. This is the list of node that is tested in checkCrashes. + // If the look_ahead is too big, the AI can skip loops (see + // QuadGraph::findRoadSector for details), if it's too short the AI won't + // find too good a driveline. Note that in general this list should + // be computed recursively, but since the AI for now is using only + // (randomly picked) path this is fine + m_all_look_aheads.reserve(m_quad_graph->getNumNodes()); + for(unsigned int i=0; igetNumNodes(); i++) + { + std::vector l; + int current = i; + for(unsigned int j=0; j(RaceManager::getWorld()); assert(m_world != NULL); @@ -133,6 +153,8 @@ void DefaultRobot::update(float dt) m_controls.m_look_back = false; m_controls.m_nitro = false; m_track_sector = m_world->m_kart_info[ getWorldKartId() ].m_track_sector; + if(m_successor_index[m_track_sector]!=0) + printf("XX"); // The client does not do any AI computations. if(network_manager->getMode()==NetworkManager::NW_CLIENT) { @@ -844,8 +866,12 @@ void DefaultRobot::checkCrashes( const int STEPS, const Vec3& pos ) } /*Find if we crash with the drivelines*/ - m_track->getQuadGraph().findRoadSector(step_coord, &m_sector, - /* max look ahead */ 10); + if(m_sector!=QuadGraph::UNKNOWN_SECTOR) + m_track->getQuadGraph().findRoadSector(step_coord, &m_sector, + /* sectors to test*/ &m_all_look_aheads[m_sector]); + else + m_track->getQuadGraph().findRoadSector(step_coord, &m_sector); + #undef SHOW_FUTURE_PATH #ifdef SHOW_FUTURE_PATH diff --git a/src/robots/default_robot.hpp b/src/robots/default_robot.hpp index 85d16ba57..418f5ed06 100644 --- a/src/robots/default_robot.hpp +++ b/src/robots/default_robot.hpp @@ -133,6 +133,9 @@ private: * m_next_quad_index[i] = (i+1) % size; * but if a branch is possible, the AI will select one option here. */ std::vector m_next_quad_index; + /** For each graph node this list contains a list of the next X + * graph nodes. */ + std::vector > m_all_look_aheads; float m_time_since_stuck; int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash. diff --git a/src/tracks/graph_node.cpp b/src/tracks/graph_node.cpp index 4ae2471a6..fdd12bad8 100644 --- a/src/tracks/graph_node.cpp +++ b/src/tracks/graph_node.cpp @@ -66,6 +66,8 @@ GraphNode::GraphNode(unsigned int index) */ void GraphNode::addSuccessor(unsigned int to) { + if(m_index==4 || m_index==5) + printf("XX"); m_vertices.push_back(to); // m_index is the quad index, so we use m_all_quads const Quad &this_quad = m_all_quads->getQuad(m_index); diff --git a/src/tracks/quad_graph.cpp b/src/tracks/quad_graph.cpp index e24eea5e8..5393b03c9 100644 --- a/src/tracks/quad_graph.cpp +++ b/src/tracks/quad_graph.cpp @@ -76,9 +76,9 @@ void QuadGraph::load(const std::string &filename) // The graph file exist, so read it in. The graph file must first contain // the node definitions, before the edges can be set. - for(unsigned int i=0; igetNumNodes(); i++) + for(unsigned int node_index=0; node_indexgetNumNodes(); node_index++) { - const XMLNode *xml_node = xml->getNode(i); + const XMLNode *xml_node = xml->getNode(node_index); // First graph node definitions: // ----------------------------- if(xml_node->getName()=="node-list") @@ -247,38 +247,20 @@ void QuadGraph::spatialToTrack(Vec3 *dst, const Vec3& xyz, * \param XYZ Position for which the segment should be determined. * \param sector Contains the previous sector (as a shortcut, since usually * the sector is the same as the last one), and on return the result - * \param max_lookahead Maximum number of graph nodes that are to be searched - * from the current sector number. This is used by the AI to make sure - * the AI does not skip any parts of the track (e.g. if the graph has - * a loop, the AI code skip the whole loop otherwise and continue - * on the normal path). Only used ith sector is not UNKNOWN_SECTOR. - * Defaults to -1, which indicates to use all graph nodes. The actual - * value might depend on the track, the size of the drivelines etc. + * \param all_sectors If this is not NULL, it is a list of all sectors to + * test. This is used by the AI to make sure that it ends up on the + * selected way in case of a branch, and also to make sure that it + * doesn't skip e.g. a loop (see explanation below for details). */ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector, - int max_lookahead) const + std::vector *all_sectors) const { - if(*sector!=UNKNOWN_SECTOR) + // Most likely the kart will still be on the sector it was before, + // so this simple case is tested first. + if(*sector!=UNKNOWN_SECTOR && getQuad(*sector).pointInQuad(xyz) ) { - // Most likely the kart will still be on the sector it was before, - // so this simple case is tested first. - if(getQuad(*sector).pointInQuad(xyz) ) - return; - - // Then check all immediate neighbours. If it's any of them, - // immediately return without any further tests. - const GraphNode &node = *m_all_nodes[*sector]; - for(unsigned int i=0; i0) - ? max_lookahead + unsigned int max_count = (*sector!=UNKNOWN_SECTOR && all_sectors!=NULL) + ? all_sectors->size() : m_all_nodes.size(); *sector = UNKNOWN_SECTOR; for(unsigned int i=0; i *all_sectors=NULL) const; /** Returns the number of nodes in the graph. */ unsigned int getNumNodes() const { return m_all_nodes.size(); }