forked from UNN/2026-rff_mp
added Astar
This commit is contained in:
parent
5a978707d8
commit
4d0d97116e
|
|
@ -2,6 +2,7 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
|
||||
class cell{
|
||||
private:
|
||||
|
|
@ -373,9 +374,6 @@ class DFSStrategy : public PathFindingStrategy {
|
|||
bool** visited = new bool*[width];
|
||||
cell*** parent = new cell**[width];
|
||||
|
||||
|
||||
cell** stack = new cell*[width * height];
|
||||
int top = 0;
|
||||
for (int x = 0; x < width; x++) {
|
||||
visited[x] = new bool[height];
|
||||
parent[x] = new cell*[height];
|
||||
|
|
@ -386,6 +384,8 @@ class DFSStrategy : public PathFindingStrategy {
|
|||
}
|
||||
}
|
||||
|
||||
cell** stack = new cell*[width * height];
|
||||
int top = 0;
|
||||
stack[top] = start;
|
||||
top++;
|
||||
visited[start->getX()][start->getY()] = true;
|
||||
|
|
@ -442,9 +442,143 @@ class DFSStrategy : public PathFindingStrategy {
|
|||
};
|
||||
|
||||
class AStarStrategy : public PathFindingStrategy {
|
||||
private:
|
||||
int heuristic(cell* current, cell* exit) {return std::abs(current->getX() - exit->getX()) + std::abs(current->getY() - exit->getY());}
|
||||
|
||||
public:
|
||||
cell** findPath(maze* m, cell* start, cell* exit) override {
|
||||
// здесь будет алгоритм A*
|
||||
int width = m->getWidth();
|
||||
int height = m->getHeight();
|
||||
|
||||
bool** closed = new bool*[width]; /*клетка [x][y] посещена (да/нет)*/
|
||||
bool** inOpen = new bool*[width]; /*клетка [x][y] имеет потенциал к посещению (да/нет)*/
|
||||
int** gScore = new int*[width]; /* до клетка [x][y] от старта gSchore[x][y] шагов*/
|
||||
int** fScore = new int*[width]; /*f = h + g, где g - эвристика клетки[x][y]*/
|
||||
|
||||
cell*** parent = new cell**[width];
|
||||
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
closed[x] = new bool[height];
|
||||
inOpen[x] = new bool[height];
|
||||
gScore[x] = new int[height];
|
||||
fScore[x] = new int[height];
|
||||
|
||||
parent[x] = new cell*[height];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
closed[x][y] = false;
|
||||
inOpen[x][y] = false;
|
||||
|
||||
gScore[x][y] = width * height + 100000; /*тупо большое число чтоб было больше чем клеток в лаберинте*/
|
||||
fScore[x][y] = width * height + 100000;
|
||||
|
||||
parent[x][y] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
cell** open = new cell*[width * height]; /*клетки с потенциалом на посещение*/
|
||||
int openCount = 0; /*это количество потенц клеток, а также индекс следующего незанятого места*/
|
||||
|
||||
int sx = start->getX();
|
||||
int sy = start->getY();
|
||||
|
||||
gScore[sx][sy] = 0;
|
||||
fScore[sx][sy] = heuristic(start, exit);
|
||||
|
||||
open[openCount] = start;
|
||||
openCount++;
|
||||
|
||||
inOpen[sx][sy] = true;
|
||||
bool found = false;
|
||||
|
||||
while (openCount > 0) {
|
||||
int bestIndex = 0;
|
||||
|
||||
for (int i = 1; i < openCount; i++) {
|
||||
int ix = open[i]->getX();
|
||||
int iy = open[i]->getY();
|
||||
|
||||
int bx = open[bestIndex]->getX();
|
||||
int by = open[bestIndex]->getY();
|
||||
|
||||
if (fScore[ix][iy] < fScore[bx][by]) {
|
||||
bestIndex = i; /*(fSchore наименьший в [bestIndex])*/
|
||||
}
|
||||
}
|
||||
|
||||
cell* current = open[bestIndex];
|
||||
|
||||
if (current == exit) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int cx = current->getX();
|
||||
int cy = current->getY();
|
||||
|
||||
open[bestIndex] = open[openCount - 1];
|
||||
openCount--;
|
||||
|
||||
inOpen[cx][cy] = false;
|
||||
closed[cx][cy] = true;
|
||||
|
||||
cell** neighbors = m->getNeighbors(current);
|
||||
|
||||
for (int i = 0; neighbors[i] != nullptr; i++) {
|
||||
cell* next = neighbors[i];
|
||||
|
||||
int nx = next->getX();
|
||||
int ny = next->getY();
|
||||
|
||||
if (closed[nx][ny]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int tentativeG = gScore[cx][cy] + 1;
|
||||
|
||||
if (tentativeG < gScore[nx][ny]) {
|
||||
parent[nx][ny] = current;
|
||||
|
||||
gScore[nx][ny] = tentativeG;
|
||||
fScore[nx][ny] = gScore[nx][ny] + heuristic(next, exit);
|
||||
|
||||
if (!inOpen[nx][ny]) {
|
||||
open[openCount] = next;
|
||||
openCount++;
|
||||
|
||||
inOpen[nx][ny] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete[] neighbors;
|
||||
}
|
||||
|
||||
cell** path;
|
||||
if (found) {
|
||||
path = PathBuilder::buildPath(start, exit, parent);
|
||||
}
|
||||
else {
|
||||
path = new cell*[1];
|
||||
path[0] = nullptr;
|
||||
}
|
||||
|
||||
delete[] open;
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
delete[] closed[x];
|
||||
delete[] inOpen[x];
|
||||
delete[] gScore[x];
|
||||
delete[] fScore[x];
|
||||
delete[] parent[x];
|
||||
}
|
||||
delete[] closed;
|
||||
delete[] inOpen;
|
||||
delete[] gScore;
|
||||
delete[] fScore;
|
||||
delete[] parent;
|
||||
|
||||
return path;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user