// ---------------------------------------------------------------------------------- // Actual A* algorithm: return number of steps in the creation of the path or -1 ---- // ---------------------------------------------------------------------------------- int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination) { int ret = 0; // TODO 1: if origin or destination are not walkable, return -1 if (IsWalkable(origin) == true && IsWalkable(destination) == true) { // TODO 2: Create three lists: open, close // Add the origin tile to open // Iterate while we have tile in the open list PathList open; PathList closed; PathNode origin_tile; origin_tile.pos = origin; open.list.add(origin_tile); while (open.Find(origin) != NULL) { // TODO 3: Move the lowest score cell from open list to the closed list p2List_item<PathNode>* open_lowestScore = open.GetNodeLowestScore(); closed.list.add(open_lowestScore->data); open.list.del(open_lowestScore); // TODO 4: If we just added the destination, we are done! // Backtrack to create the final path // Use the Pathnode::parent and Flip() the path when you are finish if (open.Find(destination) != NULL) { } // TODO 5: Fill a list of all adjancent nodes // TODO 6: Iterate adjancent nodes: // ignore nodes in the closed list // If it is NOT found, calculate its F and add it to the open list // If it is already in the open list, check if it is a better path (compare G) // If it is a better path, Update the parent } } else ret = -1; return ret; }
bool cPath::ProcessIfWalkable(const Vector3i & a_Location, cPathCell * a_Parent, int a_Cost) { if (IsWalkable(a_Location, a_Parent->m_Location)) { ProcessCell(GetCell(a_Location), a_Parent, a_Cost); return true; } return false; }
/* cPath implementation */ cPath::cPath( cChunk & a_Chunk, const Vector3d & a_StartingPoint, const Vector3d & a_EndingPoint, int a_MaxSteps, double a_BoundingBoxWidth, double a_BoundingBoxHeight ) : m_StepsLeft(a_MaxSteps), m_IsValid(true), m_CurrentPoint(0), // GetNextPoint increments this to 1, but that's fine, since the first cell is always a_StartingPoint m_Chunk(&a_Chunk), m_BadChunkFound(false) { a_BoundingBoxWidth = 1; // Treat all mobs width as 1 until physics is improved. m_BoundingBoxWidth = CeilC(a_BoundingBoxWidth); m_BoundingBoxHeight = CeilC(a_BoundingBoxHeight); m_HalfWidth = a_BoundingBoxWidth / 2; int HalfWidthInt = FloorC(a_BoundingBoxWidth / 2); m_Source.x = FloorC(a_StartingPoint.x - HalfWidthInt); m_Source.y = FloorC(a_StartingPoint.y); m_Source.z = FloorC(a_StartingPoint.z - HalfWidthInt); m_Destination.x = FloorC(a_EndingPoint.x - HalfWidthInt); m_Destination.y = FloorC(a_EndingPoint.y); m_Destination.z = FloorC(a_EndingPoint.z - HalfWidthInt); if (!IsWalkable(m_Source, m_Source)) { m_Status = ePathFinderStatus::PATH_NOT_FOUND; return; } m_NearestPointToTarget = GetCell(m_Source); m_Status = ePathFinderStatus::CALCULATING; ProcessCell(GetCell(m_Source), nullptr, 0); }
void World::GenerateWalkableTileSurface(EUnitType parUnitType) { if (unitTypeToWalkableSurface.count(parUnitType) > 0) SDL_FreeSurface(unitTypeToWalkableSurface[parUnitType]); unitTypeToWalkableSurface[parUnitType] = SDL_CreateRGBSurface(SDL_HWSURFACE, width_ * BUILD_TILE_SIZE, height_ * BUILD_TILE_SIZE, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); assert(unitTypeToWalkableSurface[parUnitType]); SDL_Rect dst = { 0, 0, WALK_TILE_SIZE, WALK_TILE_SIZE }; int2 unitDimension(unitTypeToUnitDesc[parUnitType].width, unitTypeToUnitDesc[parUnitType].height); for (size_t x = 0; x < width_ * (BUILD_TILE_SIZE / WALK_TILE_SIZE); ++x) for (size_t y = 0; y < height_ * (BUILD_TILE_SIZE / WALK_TILE_SIZE); ++y) { dst.x = x * WALK_TILE_SIZE; dst.y = y * WALK_TILE_SIZE; bool walkable = IsWalkable(WalkTile(x, y), unitDimension); Uint32 color = ((x + y) % 2 == 0) ? 0x00ffffff : (walkable ? 0x0000ffff : 0x00ff0000); SDL_FillRect(unitTypeToWalkableSurface[parUnitType], &dst, color); } }
// ---------------------------------------------------------------------------------- // Actual A* algorithm: return number of steps in the creation of the path or -1 ---- // ---------------------------------------------------------------------------------- int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination) { // TODO 1: if origin or destination are not walkable, return -1 last_path.Clear(); if (IsWalkable(origin) && IsWalkable(destination)) { uint num = 0; PathList open; PathList closed; PathList adjacents; PathNode source; p2List_item<PathNode>* closest; p2List_item<PathNode>* operations; bool isfinish = false; source.pos.x = origin.x; source.pos.y = origin.y; source.h = (abs(origin.x - destination.x) + abs(origin.y - destination.y)); source.g = 0; source.parent = NULL; open.list.add(source); num = open.Find(source.pos)->data.FindWalkableAdjacents(adjacents); closed.list.add(open.Find(source.pos)->data); open.list.del(open.Find(source.pos)); while (isfinish == NULL) { for (int i = 0; i < num; i++) { adjacents.list.At(i)->data.parent = &source; adjacents.list.At(i)->data.CalculateF(destination); adjacents.list.At(i)->data.h = adjacents.list.At(i)->data.pos.DistanceTo(destination); if (adjacents.list.At(i)->data.pos.DistanceManhattan(destination) == 0) { closed.list.add(adjacents.list.At(i)->data); isfinish = true; break; } if (closed.Find(adjacents.list.At(i)->data.pos)) { // if this adjacent square is already in the closed list ignore it continue; // Go to the next adjacent square } if (open.Find(adjacents.list.At(i)->data.pos) == NULL) { open.list.add(adjacents.list.At(i)->data); } else { // if its already in the open list } } adjacents.list.clear(); closest = open.GetNodeLowestScore(); num = open.Find(closest->data.pos)->data.FindWalkableAdjacents(adjacents); closed.list.add(closest->data); source = closest->data; } for (int i = 0; i < closed.list.count(); i++) { last_path.PushBack(closed.list.At(i)->data.pos); LOG("Point: %d, %d", last_path.At(i)->x, last_path.At(i)->y); } last_path.Flip(); } // TODO 2: Create three lists: open, close // Add the origin tile to open // Iterate while we have tile in the open list // TODO 3: Move the lowest score cell from open list to the closed list // TODO 4: If we just added the destination, we are done! // Backtrack to create the final path // Use the Pathnode::parent and Flip() the path when you are finish // TODO 5: Fill a list of all adjancent nodes // TODO 6: Iterate adjancent nodes: // ignore nodes in the closed list // If it is NOT found, calculate its F and add it to the open list // If it is already in the open list, check if it is a better path (compare G) // If it is a better path, Update the parent return -1; }
// ---------------------------------------------------------------------------------- // Actual A* algorithm: return number of steps in the creation of the path or -1 ---- // ---------------------------------------------------------------------------------- int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination) { if (IsWalkable(origin) && IsWalkable(destination)) { // TODO 2: Create three lists: open, close ,adjacent PathList open; PathList closed; PathList adjacent; // Add the origin tile to open open.list.add(PathNode(0, 0, origin, NULL)); // Iterate while we have tile in the open list do { // TODO 3: Move the lowest score cell from open list to the closed list p2List_item<PathNode>* lowest_score = open.GetNodeLowestScore(); p2List_item<PathNode>* node = closed.list.add(lowest_score->data); // delete de lowest score from the open list open.list.del(lowest_score); // TODO 4: If we just added the destination, we are done! if (node->data.pos == destination) { //clean the path we used before last_path.Clear(); // Backtrack to create the final path const PathNode* path_node = &node->data; while (path_node) { // Use the Pathnode::parent and Flip() the path when you are finish last_path.PushBack(path_node->pos); path_node = path_node->parent; } last_path.Flip(); return last_path.Count(); } // TODO 5: Fill a list of all adjancent nodes node->data.FindWalkableAdjacents(adjacent); p2List_item<PathNode>* adjacent_items = adjacent.list.start; // TODO 6: Iterate adjancent nodes: for (; adjacent_items; adjacent_items = adjacent_items->next) { // ignore nodes in the closed list if (closed.Find(adjacent_items->data.pos) != NULL) { continue; } p2List_item<PathNode>* adjacent_open = open.Find(adjacent_items->data.pos); // If it is NOT found, calculate its F and add it to the open list if (adjacent_open == NULL) { adjacent_items->data.CalculateF(destination); open.list.add(adjacent_items->data); } else // If it is already in the open list, check if it is a better path (compare G) { if (adjacent_open->data.g > adjacent_items->data.g) { // If it is a better path, Update the parent adjacent_open->data.parent = adjacent_items->data.parent; adjacent_open->data.CalculateF(destination); } } } } while (open.list.count()>0); } return -1; }
// ---------------------------------------------------------------------------------- // Actual A* algorithm: return number of steps in the creation of the path or -1 ---- // ---------------------------------------------------------------------------------- int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination) { // TODO 1: if origin or destination are not walkable, return -1 if (!IsWalkable(origin) || !IsWalkable(destination)) return -1; // TODO 2: Create two lists: open, close // Add the origin tile to open // Iterate while we have tile in the open list PathList open; PathList close; PathNode Origin; PathNode Destination; p2List_item<PathNode>* current_node; current_node = open.list.start; Origin.pos = origin; Destination.pos = destination; if (open.Find(origin) == nullptr) open.list.add(Origin); p2List_item<PathNode>* lowest = nullptr; // lowest = open.list.start; while (open.list.count() > 0 && current_node) { open.list.add(current_node->data); lowest = open.GetNodeLowestScore(); open.list.del(open.GetNodeLowestScore()); close.list.add(open.GetNodeLowestScore()->data); if (destination == lowest->data.pos) { last_path.PushBack(lowest->data.pos); last_path.Flip(); } current_node = current_node->next; } // TODO 3: Move the lowest score cell from open list to the closed list // TODO 4: If we just added the destination, we are done! // Backtrack to create the final path // Use the Pathnode::parent and Flip() the path when you are finish // TODO 5: Fill a list of all adjancent nodes // TODO 6: Iterate adjancent nodes: // ignore nodes in the closed list // If it is NOT found, calculate its F and add it to the open list // If it is already in the open list, check if it is a better path (compare G) // If it is a better path, Update the parent return -1; }
// ---------------------------------------------------------------------------------- // Actual A* algorithm: return number of steps in the creation of the path or -1 ---- // ---------------------------------------------------------------------------------- int j1PathFinding::CreatePath(const iPoint& origin, const iPoint& destination) { int ret = -1; int iterations = 0; if(IsWalkable(origin) && IsWalkable(destination)) { PathList open; PathList closed; PathList adjacent; // Start pushing the origin in the open list open.list.add(PathNode(0, 0, origin, NULL)); // Iterate while we have open destinations to visit do { // Move the lowest score cell from open list to the closed list p2List_item<PathNode>* lowest = open.GetNodeLowestScore(); p2List_item<PathNode>* node = closed.list.add(lowest->data); open.list.del(lowest); // If destination was added, we are done! if(node->data.pos == destination) { last_path.Clear(); // Backtrack to create the final path const PathNode* path_node = &node->data; while(path_node) { last_path.PushBack(path_node->pos); path_node = path_node->parent; } last_path.Flip(); ret = last_path.Count(); LOG("Created path of %d steps in %d iterations", ret, iterations); break; } // Fill a list with all adjacent nodes adjacent.list.clear(); node->data.FindWalkableAdjacents(adjacent); p2List_item<PathNode>* item = adjacent.list.start; for(; item; item = item->next) { if(closed.Find(item->data.pos) != NULL) continue; p2List_item<PathNode>* adjacent_in_open = open.Find(item->data.pos); if(adjacent_in_open == NULL) { item->data.CalculateF(destination); open.list.add(item->data); } else { if(adjacent_in_open->data.g > item->data.g + 1) { adjacent_in_open->data.parent = item->data.parent; adjacent_in_open->data.CalculateF(destination); } } } ++iterations; } while(open.list.count() > 0); } return ret; }
inline bool IsWalkable(const Coord &c) { return IsWalkable(c.x, c.y); }