Beispiel #1
0
vector<PositionNode*> AstarPathfind::FindPath(Vector2 startPos, Vector2 targetPos)
{
	PositionNode* startNode = NodeFromWorldPoint(startPos);
	PositionNode* targetNode = NodeFromWorldPoint(targetPos);

	vector<PositionNode*> openSet;
	vector<PositionNode*> closeSet;

	openSet.push_back(startNode);

	while(openSet.size() > 0)
	{
		PositionNode* currentNode = openSet[0];
		
		for(int i = 1; i < openSet.size(); ++i)
		{
			if(openSet[i]->GetfCost() < currentNode->GetfCost() || (openSet[i]->GetfCost() == currentNode->GetfCost() && openSet[i]->GethCost() < currentNode->GethCost()))
			{
				currentNode = openSet[i];
			}
		}

		openSet.erase(std::remove(openSet.begin(), openSet.end(), currentNode), openSet.end());
		closeSet.push_back(currentNode);

		if(currentNode == targetNode)
		{
			openSet.clear();
			closeSet.clear();
			return RetracePath(startNode, targetNode);
		}

		vector<PositionNode*> neighbours = GetNeighbours(currentNode);

		for(int i = 0; i < neighbours.size(); ++i)
		{
			if(!neighbours[i]->GetWalkable() || (std::find(closeSet.begin(), closeSet.end(), neighbours[i]) != closeSet.end()))
			{
				continue;
			}

			int newMovementCostToNeighbour = currentNode->GetgCost() + GetDistance(currentNode, neighbours[i]);

			if(newMovementCostToNeighbour < neighbours[i]->GetgCost() || !(std::find(openSet.begin(), openSet.end(), neighbours[i]) != openSet.end()))
			{
				neighbours[i]->SetgCost(newMovementCostToNeighbour);
				neighbours[i]->SethCost(GetDistance(neighbours[i], targetNode));
				neighbours[i]->SetParentNode(currentNode);

				if(!(std::find(openSet.begin(), openSet.end(), neighbours[i]) != openSet.end()))
				{
					openSet.push_back(neighbours[i]);
				}
			}
		}
	}
}
Beispiel #2
0
void USBMapGenerator::AddTerrain(ESBTerrainType terrain, int seeds, int iterations, float chance)
{
	// Generate seed locations
	TArray<FMapGenPoint> seedList;
	for (int i = 0; i < seeds; i++)
	{
		UE_LOG(LogTemp, Warning, TEXT("Adding map gen seeds"));

		FMapGenPoint s(FMath::RandRange(0, _w - 1), FMath::RandRange(0, _h - 1));
		_grid[s] = terrain;

		seedList.Add(s);
	}

	// grow seeds
	TArray<FMapGenPoint> newPoints;
	for (int i = 0; i < iterations; i++)
	{
		newPoints.Empty();

		for (auto s : seedList)
		{
			auto neighbours = GetNeighbours(s);
			for (auto n : neighbours)
			{
				if (_grid[n] != terrain && FMath::RandRange(0.0f, 1.0f) < chance)
				{
					_grid[n] = terrain;
					newPoints.Add(n);
				}
			}
		}

		seedList.Append(newPoints);
	}
}
/* Algorithm used for cluster analysis

   DBSCAN(D, eps, MinPts)
    C = 0
    for each unvisited point P in dataset D
      mark P as visited
      N = getNeighbors (P, eps)
      if sizeof(N) < MinPts
        mark P as NOISE
      else
        C = next cluster
        expandCluster(P, N, C, eps, MinPts)
   
     expandCluster(P, N, C, eps, MinPts)
       add P to cluster C
       for each point P' in N 
         if P' is not visited
           mark P' as visited
           N' = getNeighbors(P', eps)
           if sizeof(N') >= MinPts
             N = N joined with N'
          if P' is not yet member of any cluster
            add P' to cluster C
*/
vector< Vector<2,float> > ClusterAnalyser::AnalyseDataSet(vector< Vector<2,float> > points) {
    // List of clusters
    vector< Vector<2,float> > clusterCenters;

    // Check if there are any points to analyse (returns empty set).
    if( points.size() == 0 ) return clusterCenters; 

    // List of visited points.
    bool visited[points.size()];
    memset(&visited, 0, points.size());
    //
    bool assignedToCluster[points.size()];
    memset(&assignedToCluster, 0, points.size());

    // Iterate through all unvisited points
    for(unsigned int i=0; i<points.size(); i++){
         // Only loop unvisited points
        if( visited[i] ) continue;

        // Mark as visited
        visited[i] = true;

        // Get point.
        Vector<2,float> point = points[i];

        // Get indexes to all neighbouring points.
        vector<unsigned int> neighbours = GetNeighbours(points, point, epsilon);

        if( neighbours.size() > minClusterPoints ){
            // Form new cluster.
            std::vector< Vector<2,float> > cluster;
            // Add current point to cluster
            cluster.push_back(point);
            assignedToCluster[i] = true;

            for(unsigned int n=0; n<neighbours.size(); n++){
                // Get index of the n'th neighbour
                unsigned int nId = neighbours[n];
                // Get point data for the n'th neighbour
                Vector<2,float> nPoint = points[nId];
                if(!visited[nId]){
                    visited[nId] = true;
                    vector<unsigned int> nNeighbours = GetNeighbours(points, nPoint, epsilon);

                    // Enough support => join neighbours and neighbours-neighbours.
                    if( nNeighbours.size() >= minClusterPoints ){
                        // TODO: change GetNeighbours return type to list, then perform sort and unique here...
                        neighbours.insert(neighbours.end(), nNeighbours.begin(), nNeighbours.end());
                    }
                }

                // If nId is not assigned to any cluster add it to this cluster.
                if( !assignedToCluster[nId] ){
                    cluster.push_back(nPoint);
                    assignedToCluster[nId] = true;
                }
            }

            // Calculate center of cluster
            Vector<2,float> center = GetClusterCenter(cluster);
            clusterCenters.push_back(center);
        }
    }
    return clusterCenters;
}
Beispiel #4
0
/**
 * This is a straight forward C++ implementation of Wikipedia's A* pseudo code.
 * As proof of this the pseudo code is embedded in the source, just above the
 * C++ statements.
 *
 * See http://en.wikipedia.org/wiki/A*#Pseudocode for the complete pseudo code
 *
 * But also see the discussion page: it explains why the algorithm is only
 * correct if the cost function is monotone.This algorithm does not give the
 * correct solution in our case. The routes and hence costs differ whether we
 * go from (0,0) to (10,10) or vice versa:
 *
 * 0-0 -> 3-2 -> 4-5 -> 4-8 -> 6-9 -> 10-10, cost = 15
 *
 * 10-10 -> 10-7 -> 7-5 -> 6-3 -> 3-2 -> 0-0, cost = 14
 *
 * Use this piece of code as inspiration only.
 *
 */
std::vector<Vertex> WikiAStar( Vertex start, Vertex goal)
{
	ClosedSet closedSet;		// The set of nodes already evaluated.
	OpenSet openSet;			// The set of tentative nodes to be evaluated, initially containing the start node
	VertexMap predecessorMap;	// The map of navigated nodes.

	start.actualCost = 0.0; 												// Cost from start along best known path.
	start.heuristicCost = start.actualCost + HeuristicCost(start, goal);	// Estimated total cost from start to goal through y.
	openSet.insert(start);

	//while openset is not empty
	while(!openSet.empty())
	{
		// current := the node in openset having the lowest f_score[] value
		Vertex current = *openSet.begin();
		// if current = goal
		if(current == goal)
		{
			// return reconstruct_path(came_from, goal)
			return ConstructPath(predecessorMap,current);
		}
		// remove current from openset
		openSet.erase(current);
		// add current to closedset
		closedSet.insert(current);

		//for each neighbour in neighbour_nodes(current)
		std::vector< Vertex > neighbours = GetNeighbours(current);
		for(Vertex neighbour : neighbours)
		{
			// if neighbor in closedset continue (with next neighbour)
			if(closedSet.find(neighbour) != closedSet.end())
			{
				continue;
			}
			// tentative_g_score := g_score[current] + dist_between(current,neighbour)
			double calculatedActualNeighbourCost = current.actualCost + ActualCost(current,neighbour);

			// if neighbour not in openset or tentative_g_score < g_score[neighbour]
			if(openSet.find(neighbour) == openSet.end() || calculatedActualNeighbourCost < neighbour.actualCost)
			{
				// Here we deviate from the Wikipedia article, because of the map semantics:
				// we cannot change the object's key values once it in the map so we first
				// set the vales and then put it into the map.

				// g_score[neighbor] := tentative_g_score
				neighbour.actualCost = calculatedActualNeighbourCost;
				// f_score[neighbor] := g_score[neighbor] + heuristic_cost_estimate(neighbor, goal)
				neighbour.heuristicCost = neighbour.actualCost + HeuristicCost(neighbour, goal);

				// came_from[neighbor] := current
				std::pair<VertexMap::iterator,bool> result = predecessorMap.insert(std::make_pair(neighbour,current));

				// The following if-statement is not part of the pseudo code but a partial fix for a semantic difference
				// in the map of the pseudo code and the c++ std::map
				if(result.second==false)
					(*result.first).second = current;

				// if neighbor not in openset
				if(openSet.find(neighbour) == openSet.end())
				{
					// add neighbor to openset
					openSet.insert(neighbour);
				}
			}
		}
	}
	//return failure
	return std::vector<Vertex>();
}