added Astar

This commit is contained in:
solovevds 2026-05-22 20:25:06 +03:00
parent 5a978707d8
commit 4d0d97116e

View File

@ -2,6 +2,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <stdexcept> #include <stdexcept>
#include <cmath>
class cell{ class cell{
private: private:
@ -373,9 +374,6 @@ class DFSStrategy : public PathFindingStrategy {
bool** visited = new bool*[width]; bool** visited = new bool*[width];
cell*** parent = new cell**[width]; cell*** parent = new cell**[width];
cell** stack = new cell*[width * height];
int top = 0;
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
visited[x] = new bool[height]; visited[x] = new bool[height];
parent[x] = new cell*[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; stack[top] = start;
top++; top++;
visited[start->getX()][start->getY()] = true; visited[start->getX()][start->getY()] = true;
@ -442,9 +442,143 @@ class DFSStrategy : public PathFindingStrategy {
}; };
class AStarStrategy : 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: public:
cell** findPath(maze* m, cell* start, cell* exit) override { 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;
} }
}; };