Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
AStar.cs
浏览该文件的文档.
1using Engine;
2
3namespace Game {
4 public class AStar<T> {
5 public class Node {
6 public T Position;
7
9
10 public float F;
11
12 public float G;
13
14 public float H;
15 }
16
18
19 public DynamicArray<Node> m_nodesCache = [];
20
21 public DynamicArray<Node> m_openHeap = [];
22
23 public DynamicArray<T> m_neighbors = [];
24
25 public float PathCost { get; set; }
26
27 public DynamicArray<T> Path { get; set; }
28
29 public IAStarWorld<T> World { get; set; }
30
31 public IAStarStorage<T> OpenStorage { get; set; }
32
33 public IAStarStorage<T> ClosedStorage { get; set; }
34
35 public void BuildPathFromEndNode(Node startNode, Node endNode) {
36 PathCost = endNode.G;
37 Path.Clear();
38 for (Node node = endNode; node != startNode; node = (Node)ClosedStorage.Get(node.PreviousPosition)) {
39 Path.Add(node.Position);
40 }
41 }
42
43 public void FindPath(T start, T end, float minHeuristic, int maxPositionsToCheck) {
44 if (Path == null) {
45 throw new InvalidOperationException("Path not specified.");
46 }
47 if (World == null) {
48 throw new InvalidOperationException("AStar World not specified.");
49 }
50 if (OpenStorage == null) {
51 throw new InvalidOperationException("AStar OpenStorage not specified.");
52 }
53 if (OpenStorage == null) {
54 throw new InvalidOperationException("AStar ClosedStorage not specified.");
55 }
57 m_openHeap.Clear();
58 OpenStorage.Clear();
59 ClosedStorage.Clear();
60 Node node = NewNode(start, default, 0f, 0f);
61 OpenStorage.Set(start, node);
62 HeapEnqueue(node);
63 Node node2 = null;
64 int num = 0;
65 Node node3;
66 while (true) {
67 node3 = m_openHeap.Count > 0 ? HeapDequeue() : null;
68 if (node3 == null
69 || num >= maxPositionsToCheck) {
70 if (node2 != null) {
71 BuildPathFromEndNode(node, node2);
72 return;
73 }
74 Path.Clear();
75 PathCost = 0f;
76 return;
77 }
78 if (World.IsGoal(node3.Position)) {
79 break;
80 }
81 ClosedStorage.Set(node3.Position, node3);
82 OpenStorage.Set(node3.Position, null);
83 num++;
84 m_neighbors.Clear();
85 World.Neighbors(node3.Position, m_neighbors);
86 for (int i = 0; i < m_neighbors.Count; i++) {
87 T val = m_neighbors.Array[i];
88 if (ClosedStorage.Get(val) != null) {
89 continue;
90 }
91 float num2 = World.Cost(node3.Position, val);
92 if (num2 == 1f / 0f) {
93 continue;
94 }
95 float num3 = node3.G + num2;
96 float num4 = World.Heuristic(val, end);
97 if (node3 != node
98 && (node2 == null || num4 < node2.H)) {
99 node2 = node3;
100 }
101 Node node4 = (Node)OpenStorage.Get(val);
102 if (node4 != null) {
103 if (num3 < node4.G) {
104 node4.G = num3;
105 node4.F = num3 + node4.H;
106 node4.PreviousPosition = node3.Position;
107 HeapUpdate(node4);
108 }
109 }
110 else {
111 node4 = NewNode(val, node3.Position, num3, num4);
112 OpenStorage.Set(val, node4);
113 HeapEnqueue(node4);
114 }
115 }
116 }
117 BuildPathFromEndNode(node, node3);
118 }
119
120 public void HeapEnqueue(Node node) {
121 m_openHeap.Add(node);
123 }
124
125 public Node HeapDequeue() {
126 Node result = m_openHeap.Array[0];
127 if (m_openHeap.Count <= 1) {
128 m_openHeap.Clear();
129 return result;
130 }
131 m_openHeap.Array[0] = m_openHeap.Array[m_openHeap.Count - 1];
132 --m_openHeap.Count;
134 return result;
135 }
136
137 public void HeapUpdate(Node node) {
138 int pos = -1;
139 for (int i = 0; i < m_openHeap.Count; i++) {
140 if (m_openHeap.Array[i] == node) {
141 pos = i;
142 break;
143 }
144 }
146 }
147
148 public void HeapifyFromPosToEnd(int pos) {
149 while (true) {
150 int num = pos;
151 int num2 = 2 * pos + 1;
152 int num3 = 2 * pos + 2;
153 if (num2 < m_openHeap.Count
154 && m_openHeap.Array[num2].F < m_openHeap.Array[num].F) {
155 num = num2;
156 }
157 if (num3 < m_openHeap.Count
158 && m_openHeap.Array[num3].F < m_openHeap.Array[num].F) {
159 num = num3;
160 }
161 if (num != pos) {
162 Node node = m_openHeap.Array[num];
163 m_openHeap.Array[num] = m_openHeap.Array[pos];
164 m_openHeap.Array[pos] = node;
165 pos = num;
166 continue;
167 }
168 break;
169 }
170 }
171
172 public void HeapifyFromPosToStart(int pos) {
173 int num = pos;
174 while (num > 0) {
175 int num2 = (num - 1) / 2;
176 Node node = m_openHeap.Array[num2];
177 Node node2 = m_openHeap.Array[num];
178 if (node.F > node2.F) {
179 m_openHeap.Array[num2] = node2;
180 m_openHeap.Array[num] = node;
181 num = num2;
182 continue;
183 }
184 break;
185 }
186 }
187
188 public Node NewNode(T position, T previousPosition, float g, float h) {
189 while (m_nodesCacheIndex >= m_nodesCache.Count) {
190 m_nodesCache.Add(new Node());
191 }
192 Node obj = m_nodesCache.Array[m_nodesCacheIndex++];
193 obj.Position = position;
194 obj.PreviousPosition = previousPosition;
195 obj.F = g + h;
196 obj.G = g;
197 obj.H = h;
198 return obj;
199 }
200 }
201}
IAStarStorage< T > ClosedStorage
DynamicArray< T > m_neighbors
void HeapifyFromPosToStart(int pos)
Node NewNode(T position, T previousPosition, float g, float h)
void HeapEnqueue(Node node)
void BuildPathFromEndNode(Node startNode, Node endNode)
void FindPath(T start, T end, float minHeuristic, int maxPositionsToCheck)
DynamicArray< Node > m_nodesCache
void HeapUpdate(Node node)
IAStarWorld< T > World
DynamicArray< T > Path
IAStarStorage< T > OpenStorage
DynamicArray< Node > m_openHeap
void HeapifyFromPosToEnd(int pos)