-
Notifications
You must be signed in to change notification settings - Fork 2
/
Pathfinder.cs
100 lines (89 loc) · 2.42 KB
/
Pathfinder.cs
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
using System;
using System.Collections;
namespace Rails
{
public delegate bool PathfinderMethod(Pathfinder f, int x, int y, int d, int i, int j, out IComparable val);
public class Pathfinder
{
Map map;
int gridW, gridH;
bool[,] b;
IComparable[,] val;
int[,] gradient;
public Pathfinder(Map map, IComparable initialValue)
{
this.map = map;
gridW = map.GridSize.Width;
gridH = map.GridSize.Height;
b = new Boolean[gridW, gridH];
val = new IComparable[gridW, gridH];
gradient = new int[gridW, gridH];
for (int x=0; x<gridW; x++)
for (int y=0; y<gridH; y++)
{
val[x, y] = initialValue;
gradient[x, y] = -1;
}
}
public void SetValue(int x, int y, IComparable val)
{
this.val[x, y] = val;
b[x, y] = true;
}
public IComparable GetValue(int x, int y)
{
return this.val[x, y];
}
public void Find(PathfinderMethod method, IsValidSite isValidSite)
{
// loop until we run out of terrain
bool done;
do
{
// clear the map of interesting spots for the next loop
done = true;
bool[,] b2 = new bool[gridW, gridH];
// scan all the interesting spots found in the previous loop
for (int x=0; x<gridW; x++)
for (int y=0; y<gridH; y++)
if (b[x, y])
{
int i, j;
// examine adjacent mileposts
IComparable cost;
for (int d=0; d<6; d++)
if (map.GetAdjacent(x, y, d, out i, out j))
if (map[i, j].Terrain != TerrainType.Inaccessible)
if (isValidSite == null || isValidSite(i, j))
// call the pathfinder method delegate
if (method(this, x, y, d, i, j, out cost))
{
// if the cost is at least as good as previously found,
// store the result and mark as interesting for the
// next loop
if (cost.CompareTo(val[i, j]) < 0)
{
val[i, j] = cost;
gradient[i, j] = d;
b2[i, j] = true;
done = false;
}
}
}
// hand off interesting spots for next loop
b = b2;
}
while (!done);
}
public Stack GetGradientStack(int x, int y)
{
Stack stack = new Stack();
while (gradient[x, y] != -1)
{
stack.Push(gradient[x, y]);
map.GetAdjacent(x, y, (gradient[x, y] + 3) % 6, out x, out y);
}
return stack;
}
}
}