예제 #1
0
bool PathFindingApp::doPathfinding(int startX, int startY, int endX, int endY)
{
	
	// Set color for start and end pos to path color
	setPathColor(m_texturePathFound, startX, startY);
	setPathColor(m_texturePathFound, endX, endY);

	bool done = true;
	// Some variables for path finding
	OpenList openList;
	ClosedList closedList;
	SearchLevel searchLevel(m_textureStartCase);
	SearchNode *result = 0;

	// Start A* search:
	// Add start node to open list.
	Position startPosition = Position(startX, startY);
	Position endPosition = Position(endX, endY);
	SearchNode *newNode = new SearchNode(startPosition, searchLevel.getH(startPosition, endPosition), 0, 0);
	openList.insertToOpenList(newNode);

	// 1. Get the square on the open list which has the lowest score. Let's call this square S (or prey)
	while (!openList.isEmpty())
	{
		SearchNode *prev = openList.removeSmallestFFromOpenList();
		if (prev->pos == endPosition)
		{
			// Goal found!
			result = prev;
			break;
		}
		else
		{
			// 2. Remove S from the open list and add S to the closed list.
			closedList.addToClosedList(prev);

			// 3. for each square T in S's walkable adjacent tiles:
			std::vector<Position> adjacentNodes = searchLevel.getAdjacentNodes(prev->pos.first, prev->pos.second);
			for (size_t i = 0; i < adjacentNodes.size(); ++i)
			{
				// If T is in the closed list : Ignore it.
				if (closedList.isInClosedList(adjacentNodes[i]))
				{
					continue;
				}

				SearchNode *n = openList.findFromOpenList(adjacentNodes[i]);
				if (n == 0)
				{
					// If T is not in the open list : Add it and compute its score
					SearchNode * newNode = new SearchNode(adjacentNodes[i],
						searchLevel.getH(adjacentNodes[i], endPosition),
						searchLevel.getG(prev, adjacentNodes[i]), prev);
					openList.insertToOpenList(newNode);
				}
				else
				{
					// If T is already in the open list : Check if the F score is lower
					// when we use the current generated path to get there. If it is update
					// it's score and update its parent as well.
					SearchNode *newNode = new SearchNode(adjacentNodes[i],
						searchLevel.getH(adjacentNodes[i], endPosition),
						searchLevel.getG(prev, adjacentNodes[i]), prev);
					if (n->distance() < newNode->distance())
					{
						n->resetPrev(newNode->prevNode, searchLevel.getG(newNode->prevNode, n->pos));
					}
				}
			}
		}
	}
	if (result == 0)
	{
		printf("Path not found!!!\n");
		return true;
	}

	while (result != 0)
	{
		setPathColor(m_texturePathFound, result->pos.first, result->pos.second);
		result = result->prevNode;
	}

	return true;

	// TODO: Remove that search end and delay hack as seen below..
	//static int i = 0;
	//i = ((i+1)%10); // 10*100ms = ~500 ms of total
	//Sleep(100);
	//return i==0;
}
예제 #2
0
bool GraphUtility::graph_contains_loop(const Graph& graph) {
  // Type definitions
  typedef typename Graph::vertex_descriptor VertexType;
  typedef typename Graph::edge_descriptor EdgeType;
  typedef std::stack<std::pair<VertexType, VertexType>> OpenList;
  typedef std::vector<bool> ClosedList;

  // Some local variables
  size_t num_node_explored = 0;
  const auto num_vertices = boost::num_vertices(graph);
  if (num_vertices == 0) return false;

  // Closed List inizialization
  ClosedList closedList(num_vertices, false);

  // Open List inizialization
  OpenList openList;
  const auto p_firstVertex = boost::vertices(graph).first;
  const auto p_nullVertex = boost::vertices(graph).second;
  openList.push(std::make_pair(*p_firstVertex, *p_nullVertex));
  closedList[*p_firstVertex] = true;
  ++num_node_explored;

  while (openList.empty() == false) {
    // Pop the next node
    const auto current_element = openList.top();
    const auto& current_node = current_element.first;
    const auto& current_parent = current_element.second;
    openList.pop();

    // Explore all adjacent vertices
    const auto adj_vertices = boost::adjacent_vertices(current_node, graph);

    // Look for a back vertices which is not the parent
    const auto finder = std::find_if(
        adj_vertices.first, adj_vertices.second,
        [&] (const VertexType& a_v) {
          if (closedList[a_v] == true) {
            if (a_v != current_parent) {
              // Found a back edge. A cycle is here!
              return true;
            }
          } else {
            openList.push(std::make_pair(a_v, current_node));
            closedList[a_v] = true;
            ++num_node_explored;
          }
          return false;
        });

    if (finder != adj_vertices.second) {
      return true;
    }
  }  // while openList is not empty

  // Assertion all nodes are explored. In case the graph is disconnected
  assert(num_node_explored == num_vertices);

  // No cycle found!
  return false;
}
예제 #3
0
std::vector<slm::vec2> PathFindingApp::doPathfinding(int startX, int startY, int endX, int endY)
{
	bool done = true;
	// Some variables for path finding
	OpenList openList;
	ClosedList closedList;
	SearchLevel searchLevel(mapLayer);
	SearchNode *result = 0;
	std::vector<slm::vec2> mapPoints;

	// Start A* search:
	// Add start node to open list.
	Position startPosition = Position(startX, startY);
	Position endPosition = Position(endX, endY);
	SearchNode *newNode = new SearchNode(startPosition, searchLevel.getH(startPosition, endPosition), 0, 0);
	openList.insertToOpenList(newNode);

	// 1. Get the square on the open list which has the lowest score. Let's call this square S (or prey)
	while (!openList.isEmpty())
	{
		SearchNode *prev = openList.removeSmallestFFromOpenList();
		if (prev->pos == endPosition)
		{
			// Goal found!
			result = prev;
			break;
		}
		else
		{
			// 2. Remove S from the open list and add S to the closed list.
			closedList.addToClosedList(prev);

			// 3. for each square T in S's walkable adjacent tiles:
			std::vector<Position> adjacentNodes = searchLevel.getAdjacentNodes(prev->pos.first, prev->pos.second);
			for (size_t i = 0; i < adjacentNodes.size(); ++i)
			{
				// If T is in the closed list : Ignore it.
				if (closedList.isInClosedList(adjacentNodes[i]))
				{
					continue;
				}

				SearchNode *n = openList.findFromOpenList(adjacentNodes[i]);
				if (n == 0)
				{
					// If T is not in the open list : Add it and compute its score
					SearchNode * newNode = new SearchNode(adjacentNodes[i],
						searchLevel.getH(adjacentNodes[i], endPosition),
						searchLevel.getG(prev, adjacentNodes[i]), prev);
					openList.insertToOpenList(newNode);
				}
				else
				{
					// If T is already in the open list : Check if the F score is lower
					// when we use the current generated path to get there. If it is update
					// it's score and update its parent as well.
					SearchNode *newNode = new SearchNode(adjacentNodes[i],
						searchLevel.getH(adjacentNodes[i], endPosition),
						searchLevel.getG(prev, adjacentNodes[i]), prev);
					if (n->distance() < newNode->distance())
					{
						n->resetPrev(newNode->prevNode, searchLevel.getG(newNode->prevNode, n->pos));
					}
				}
			}
		}
	}
	if (result == 0)
	{
		std::cout << "Path not found!!!\n";
		return mapPoints;
	}

	while (result != 0)
	{
		std::cout << "Path found!\n";
		result = result->prevNode;

		if (result != nullptr)
		{
			slm::vec2 mapPoint;

			mapPoint.x = result->pos.first;
			mapPoint.y = result->pos.second;
			mapPoints.push_back(mapPoint);
		}
	}

	return mapPoints;
}
예제 #4
0
void GraphUtility::find_all_disjointed_graph(
    const Graph& graph,
    std::vector<VertexFilter>* dis_graphs,
    bool unitary_subgraph) {
  assert(dis_graphs != nullptr);

  // Some type definitions
  typedef typename Graph::vertex_descriptor VertexType;
  typedef std::queue<VertexType> OpenList;
  typedef std::vector<bool> ClosedList;

  // Some local variable
  const auto num_vertices = boost::num_vertices(graph);
  VertexFilter* current_filter = nullptr;

  // Clean the output
  dis_graphs->clear();

  // Initialize the closed list. All vertices are unexplored
  ClosedList closedList(num_vertices, false);
  size_t explored_node = 0;

  // Inizialize the open list. Insert the first vertex
  OpenList openList;
  const auto first_vertex = boost::vertices(graph).first;
  openList.push(*first_vertex);
  ++explored_node;
  closedList[*first_vertex] = true;

  while (explored_node < num_vertices) {
    // Check if the open list is empty. In that case find another node
    if (openList.empty() == true) {
      // Force next iteration to create a new filter
      current_filter = nullptr;

      const auto all_vertices = boost::vertices(graph);
      const auto finder = std::find_if(
          all_vertices.first, all_vertices.second,
          [&] (const VertexType& v) {
            return (closedList[v] == false);
          });

      // There must to be another vertex to explore
      assert(finder != all_vertices.second);

      // Insert this new node in the openlist
      openList.push(*finder);
      closedList[*finder] = true;
      ++explored_node;
    }

    while (openList.empty() == false) {
      // Get the first vertex in the open list and remove from it
      const auto current_vertex = openList.front();
      openList.pop();

      // Check if the current vertex is a isolated node.
      // In that case, and the option for unitary graph is disabled
      // then you can skip that node
      if (unitary_subgraph == true ||
          (boost::out_degree(current_vertex, graph) > 0)) {
        // If the current filter is null, create a new one and
        // use it
        if (current_filter == nullptr) {
          dis_graphs->emplace_back(num_vertices, false);
          current_filter = &(dis_graphs->back());
        }

        // Add the current vertex to the current filter
        (*current_filter)[current_vertex] = true;

        // Get all adjacent vertices from the current vertex
        const auto adj_vertices = boost::adjacent_vertices(current_vertex,
                                                           graph);

        // Add all adjacent vertices to the open list
        std::for_each(
            adj_vertices.first, adj_vertices.second,
            [&] (const VertexType& a_v) {
              // Check the vertex is not in the closed list
              if (closedList[a_v] == false) {
                openList.push(a_v);

                // Add it to the closed list
                closedList[a_v] = true;
                ++explored_node;
              }
            });
      }
    }  // end while on openList
  }  // end while on all vertices explored

  // Assertion on disjointed property
  assert(GraphUtility::check_all_disjointed(
      *dis_graphs, num_vertices) == true);
}
예제 #5
0
파일: Path.cpp 프로젝트: jlippitt/spacewar
Path::Path(Unit* unit, Tile* targetTile, bool attack)
    : m_path  (),
      m_attack(attack)
{
    Q_ASSERT(unit != nullptr);
    Q_ASSERT(targetTile != nullptr);

    OpenList open;
    open.push(new Node(unit->tile(), 0, distance(unit->tile(), targetTile)));

    ClosedList closed;

    while (!open.isEmpty())
    {
        Node* current = open.pop();
        closed.push(current);

        if (current->tile() == targetTile)
        {
            // Target found
            constructPath(current);
            break;
        }

        for (Tile* neighbour : current->tile()->neighbours())
        {
            if (closed.contains(neighbour))
            {
                continue;
            }

            QScopedPointer<Node> newNode(new Node(
                neighbour,
                current->g() + 1,
                distance(neighbour, targetTile),
                current
            ));

            auto existing = open.find(neighbour);

            if (existing == open.end())
            {
                // Tile we haven't check before - make sure we can enter
                if (unit->canEnter(neighbour) ||
                    (attack && neighbour == targetTile))
                {
                    open.push(newNode.take());
                }
                else
                {
                    // If we can't enter, don't check again
                    closed.push(newNode.take());
                }
            }
            else if (newNode->g() < (*existing)->g())
            {
                open.replace(existing, newNode.take());
            }
        }
    }
}