HOG2
DynamicWeightedGrid.cpp
Go to the documentation of this file.
1 //
2 // DynamicWeightedGrid.cpp
3 // Dynamic Weighted Abstraction
4 //
5 // Created by Nathan Sturtevant on 5/16/19.
6 // Copyright © 2019 University of Denver. All rights reserved.
7 //
8 
9 #include "DynamicWeightedGrid.h"
10 #include <cassert>
11 #include <algorithm>
12 #include <vector>
13 #include <random>
14 
15 namespace DWG {
16 
18  {
19  FILE *f = fopen(map, "r");
20  if (f == 0)
21  {
22  printf("Unable to open file '%s'\n", map);
23  exit(0);
24  }
25  char format[32];
26  int num = fscanf(f, "type %s\nheight %d\nwidth %d\nmap\n", format, &mHeight, &mWidth);
27  if (num != 3)
28  {
29  printf("Bad file format: '%s'\n", map);
30  exit(0);
31  }
32  terrain.resize(mWidth*mHeight);
33  char what;
34  for (uint16_t y = 0; y < mHeight; y++)
35  {
36  for (uint16_t x = 0; x < mWidth; x++)
37  {
38  fscanf(f, "%c", &what);
39  terrain[y*mWidth+x] = (what-'A');
40  }
41  fscanf(f, "%c", &what);
42  if (what != '\n')
43  printf("Error loading\n");
44  }
45  srand(1);
46  for (int x = 0; x < 20; x++)
47  costs.push_back(1+0.2*x);
48  std::random_device rd;
49  std::mt19937 g(rd());
50  // std::random_shuffle(costs.begin(), costs.end());
51  std::shuffle(costs.begin(), costs.end(), g);
52  }
53 
55  {
56  mWidth = width;
57  mHeight = height;
58 
59  terrain.resize(mWidth*mHeight);
60  for (uint16_t y = 0; y < mHeight; y++)
61  {
62  for (uint16_t x = 0; x < mWidth; x++)
63  {
64  terrain[y*mWidth+x] = kGround;
65  }
66  }
67  srand(1);
68  for (int x = 0; x < 20; x++)
69  costs.push_back(1+0.2*x);
70  std::random_device rd;
71  std::mt19937 g(rd());
72  // std::random_shuffle(costs.begin(), costs.end());
73  std::shuffle(costs.begin(), costs.end(), g);
74  }
75 
76  void DynamicWeightedGridEnvironment::GetSuccessors(const xyLoc &nodeID, std::vector<xyLoc> &neighbors) const
77  {
78  neighbors.clear();
79  if (nodeID.x > 0)
80  {
81  neighbors.push_back(nodeID);
82  neighbors.back().x--;
83  }
84  if (nodeID.y > 0)
85  {
86  neighbors.push_back(nodeID);
87  neighbors.back().y--;
88  }
89  if (nodeID.x+1 < mWidth)
90  {
91  neighbors.push_back(nodeID);
92  neighbors.back().x++;
93  }
94  if (nodeID.y+1 < mHeight)
95  {
96  neighbors.push_back(nodeID);
97  neighbors.back().y++;
98  }
99  if (nodeID.y > 0 && nodeID.x > 0)
100  {
101  neighbors.push_back(nodeID);
102  neighbors.back().x--;
103  neighbors.back().y--;
104  }
105  if (nodeID.y > 0 && nodeID.x+1 < mWidth)
106  {
107  neighbors.push_back(nodeID);
108  neighbors.back().x++;
109  neighbors.back().y--;
110  }
111  if (nodeID.y+1 < mHeight && nodeID.x+1 < mWidth)
112  {
113  neighbors.push_back(nodeID);
114  neighbors.back().x++;
115  neighbors.back().y++;
116  }
117  if (nodeID.y+1 < mHeight && nodeID.x > 0)
118  {
119  neighbors.push_back(nodeID);
120  neighbors.back().x--;
121  neighbors.back().y++;
122  }
123  }
124 
125  void DynamicWeightedGridEnvironment::GetActions(const xyLoc &nodeID, std::vector<tDirection> &actions) const
126  {
127  actions.clear();
128  if (nodeID.x > 0)
129  {
130  actions.push_back(kW);
131  }
132  if (nodeID.y > 0)
133  {
134  actions.push_back(kN);
135  }
136  if (nodeID.x+1 < mWidth)
137  {
138  actions.push_back(kE);
139  }
140  if (nodeID.y+1 < mHeight)
141  {
142  actions.push_back(kS);
143  }
144  if (nodeID.y > 0 && nodeID.x > 0)
145  {
146  actions.push_back(kNW);
147  }
148  if (nodeID.y > 0 && nodeID.x+1 < mWidth)
149  {
150  actions.push_back(kNE);
151  }
152  if (nodeID.y+1 < mHeight && nodeID.x+1 < mWidth)
153  {
154  actions.push_back(kSE);
155  }
156  if (nodeID.y+1 < mHeight && nodeID.x > 0)
157  {
158  actions.push_back(kSW);
159  }
160 
161  }
162 
164  {
165  switch (a)
166  {
167  case kN: s.y-=1; break;
168  case kS: s.y+=1; break;
169  case kE: s.x+=1; break;
170  case kW: s.x-=1; break;
171  case kNW: s.y-=1; s.x-=1; break;
172  case kSW: s.y+=1; s.x-=1; break;
173  case kNE: s.y-=1; s.x+=1; break;
174  case kSE: s.y+=1; s.x+=1; break;
175  default: break;
176  }
177  }
178 
180  {
181  switch (a)
182  {
183  case kN: a = kS; break;
184  case kNE: a = kSW; break;
185  case kE: a = kW; break;
186  case kSE: a = kNW; break;
187  case kS: a = kN; break;
188  case kSW: a = kNE; break;
189  case kW: a = kE; break;
190  case kNW: a = kSE; break;
191  default: break;
192  }
193  return true;
194  }
195 
197  {
198  assert(!"Not implemented");
199  return tDirection();
200 
201  }
202 
204  double DynamicWeightedGridEnvironment::HCost(const xyLoc &l1, const xyLoc &l2) const
205  {
206  const double DIAGONAL_COST = M_SQRT2;
207  double a = ((l1.x>l2.x)?(l1.x-l2.x):(l2.x-l1.x));
208  double b = ((l1.y>l2.y)?(l1.y-l2.y):(l2.y-l1.y));
209 // if (a == 0 && b == 0)
210 // return 0;
211  //return costs[terrain[l1.y*mWidth+l1.x]]*0.5+0.5*costs[terrain[l2.y*mWidth+l2.x]]-1+
212  return ((a>b)?(b*DIAGONAL_COST+a-b):(a*DIAGONAL_COST+b-a));
213  }
214 
215  double DynamicWeightedGridEnvironment::GCost(const xyLoc &node1, const xyLoc &node2) const
216  {
217  double base = 1.0;
218  if (node1.x != node2.x && node1.y != node2.y)
219  base = M_SQRT2;
220  double c1 = costs[terrain[node2.y*mWidth+node2.x]];
221  double c2 = costs[terrain[node1.y*mWidth+node1.x]];
222  double result = base*0.5*(c1+c2);
223  return result;
224  }
225 
227  {
228  xyLoc tmp = node;
229  ApplyAction(tmp, act);
230  return GCost(node, tmp);
231  }
232 
234  {
235  return node == goal;
236  }
237 
239  {
240  return node.y*mWidth+node.x;
241  }
242 
244  {
245  return act;
246  }
247 
249  {
250 
251  }
252 
254  {
255  float x, y, r;
256  GetCoordinate(l, x, y, r);
257  display.FillCircle({x, y}, r, GetColor());
258  //DynamicWeightedGrid<1>::GetTerrainColor((TerrainType)terrain[l.y*mWidth+l.x]));
259  }
260 
261  void DynamicWeightedGridEnvironment::GetCoordinate(const xyLoc &l, float &x, float &y, float &radius) const
262  {
263  float _scale, xOffset, yOffset;
264  if (mHeight > mWidth)
265  {
266  _scale = 2.0/(float)(mHeight);
267  xOffset = (2.0-mWidth*_scale)*0.5;
268  yOffset = 0;
269  }
270  else {
271  _scale = 2.0/(float)(mWidth);
272  yOffset = (2.0-mHeight*_scale)*0.5;
273  xOffset = 0;
274  }
275  float epsilon = _scale/2.0;
276  x = -1+l.x*_scale+epsilon+xOffset;
277  y = -1+l.y*_scale+epsilon+yOffset;
278  // x = (2*_x-width)*_scale+epsilon;
279  // y = (2*_y-height)*_scale+epsilon;
280  radius = epsilon;
281  }
282 }
DWG::DynamicWeightedGridEnvironment::GCost
double GCost(const xyLoc &node1, const xyLoc &node2) const
Definition: DynamicWeightedGrid.cpp:215
DWG
Definition: DynamicWeightedGrid.cpp:15
kSE
@ kSE
Definition: Map2DEnvironment.h:79
xyLoc::y
uint16_t y
Definition: Map2DEnvironment.h:42
kW
@ kW
Definition: Map2DEnvironment.h:78
DWG::DynamicWeightedGridEnvironment::GetAction
tDirection GetAction(const xyLoc &s1, const xyLoc &s2) const
Definition: DynamicWeightedGrid.cpp:196
DWG::DynamicWeightedGridEnvironment::GetCoordinate
void GetCoordinate(const xyLoc &l, float &x, float &y, float &r) const
Definition: DynamicWeightedGrid.cpp:261
xyLoc
Definition: Map2DEnvironment.h:37
width
int width
Definition: SFML_HOG.cpp:54
DWG::DynamicWeightedGridEnvironment::InvertAction
bool InvertAction(tDirection &a) const
Definition: DynamicWeightedGrid.cpp:179
xyLoc::x
uint16_t x
Definition: Map2DEnvironment.h:41
kE
@ kE
Definition: Map2DEnvironment.h:78
DWG::DynamicWeightedGridEnvironment::DynamicWeightedGridEnvironment
DynamicWeightedGridEnvironment(const char *map)
Definition: DynamicWeightedGrid.cpp:17
DWG::DynamicWeightedGridEnvironment::GetActionHash
uint64_t GetActionHash(tDirection act) const
Definition: DynamicWeightedGrid.cpp:243
costs
Definition: FringeSearch.h:15
DWG::kGround
@ kGround
Definition: DynamicWeightedGrid.h:23
Graphics::Display
Definition: Graphics.h:146
DWG::DynamicWeightedGridEnvironment::GetStateHash
uint64_t GetStateHash(const xyLoc &node) const
Definition: DynamicWeightedGrid.cpp:238
DWG::DynamicWeightedGridEnvironment::mHeight
int mHeight
Definition: DynamicWeightedGrid.h:256
DWG::DynamicWeightedGridEnvironment::Draw
void Draw(Graphics::Display &display) const
Definition: DynamicWeightedGrid.cpp:248
tDirection
tDirection
Definition: Map2DEnvironment.h:77
DWG::DynamicWeightedGridEnvironment::GoalTest
bool GoalTest(const xyLoc &node, const xyLoc &goal) const
Definition: DynamicWeightedGrid.cpp:233
SearchEnvironment< xyLoc, tDirection >::GetColor
virtual rgbColor GetColor() const
Definition: SearchEnvironment.h:105
height
int height
Definition: SFML_HOG.cpp:54
kN
@ kN
Definition: Map2DEnvironment.h:78
DWG::DynamicWeightedGridEnvironment::mWidth
int mWidth
Definition: DynamicWeightedGrid.h:256
DWG::DynamicWeightedGridEnvironment::terrain
std::vector< uint8_t > terrain
Definition: DynamicWeightedGrid.h:255
Graphics::Display::FillCircle
void FillCircle(rect r, rgbColor c)
Definition: Graphics.cpp:128
kS
@ kS
Definition: Map2DEnvironment.h:78
DWG::DynamicWeightedGridEnvironment::ApplyAction
void ApplyAction(xyLoc &s, tDirection a) const
Definition: DynamicWeightedGrid.cpp:163
kNE
@ kNE
Definition: Map2DEnvironment.h:78
DynamicWeightedGrid.h
DWG::DynamicWeightedGridEnvironment::HCost
double HCost(const xyLoc &node1, const xyLoc &node2) const
Heuristic value between two arbitrary nodes.
Definition: DynamicWeightedGrid.cpp:204
DWG::DynamicWeightedGridEnvironment::GetActions
void GetActions(const xyLoc &nodeID, std::vector< tDirection > &actions) const
Definition: DynamicWeightedGrid.cpp:125
DWG::DynamicWeightedGridEnvironment::GetSuccessors
void GetSuccessors(const xyLoc &nodeID, std::vector< xyLoc > &neighbors) const
Definition: DynamicWeightedGrid.cpp:76
kSW
@ kSW
Definition: Map2DEnvironment.h:79
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
kNW
@ kNW
Definition: Map2DEnvironment.h:78