forked from UNN/2026-rff_mp
added Astar
This commit is contained in:
parent
5a978707d8
commit
4d0d97116e
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user