-
Notifications
You must be signed in to change notification settings - Fork 27
/
astar.hpp
122 lines (113 loc) · 2.35 KB
/
astar.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "player.hpp"
#include <stack>
#include <queue>
const int greed = 100;
const int deltaStep = 4;
Point aimPoint;
namespace astar
{
class Node
{
private:
Point location;
Node *parent;
int weight;
public:
Node(Point l = Point(0,0), Node *p = NULL)
{
location = l;
weight = 0;
setParent(p);
}
int getHeuristicWeight() const
{
return greed*(abs(aimPoint.x - location.x) + abs(aimPoint.y - location.y)) + weight;
}
Point getLocation() const
{
return location;
}
int getWeight() const
{
return weight;
}
void setParent(astar::Node *p)
{
parent = p;
if(parent == NULL)
weight = 0;
else if((parent->getLocation().x - location.x) && (parent->getLocation().y - location.y))
weight = 14 + parent->getWeight();
else
weight = 10 + parent->getWeight();
}
void addToStack(stack<Point> &s)
{
s.push(location);
if(parent != NULL)
{
parent->addToStack(s);
}
}
};
inline bool operator<(const Node &l, const Node &r)
{
return l.getHeuristicWeight() > r.getHeuristicWeight();
}
}
priority_queue<astar::Node, vector<astar::Node> > open;
void aStar(astar::Node n, stack<Point> &s)
{
int y = n.getLocation().y;
int x = n.getLocation().x;
if(!open.empty())
open.pop();
if(!isValid(y,x))
{
aStar(open.top(), s);
return;
}
if(imgg.at<uchar>(y,x) >= 128 || imgv.at<uchar>(y,x) >= 128)
{
aStar(open.top(), s);
return;
}
imgv.at<uchar>(y,x) = 255;
if(abs(y - aimPoint.y) + abs(x - aimPoint.x) <= 5*deltaStep)
{
n.addToStack(s);
while(!open.empty())
open.pop();
return;
}
for(int j=-deltaStep; j<=deltaStep; j+=deltaStep)
{
for(int i=-deltaStep; i<=deltaStep; i+=deltaStep)
{
if(j || i)
if(isValid(y+j,x+i))
if((imgv.at<uchar>(y+j,x+i) == 0) && (imgg.at<uchar>(y+j,x+i) < 128))
{
astar::Node *newNode = new astar::Node(Point(x+i,y+j), &n);
if(newNode != NULL)
open.push(*newNode);
}
}
}
if(!open.empty())
aStar(open.top(), s);
}
void getPath(Point start, Point finish, stack<Point> &path)
{
imgv = Scalar(0);
while(!open.empty())
open.pop();
while(!path.empty())
path.pop();
if(abs(start.x - finish.x) + abs(start.y - finish.y) <= 5*deltaStep)
return;
aimPoint = finish;
astar::Node *startNode = new astar::Node(start);
open.push(*startNode);
aStar(*startNode, path);
}