HOG2
SearchUnit.cpp
Go to the documentation of this file.
1 /*
2  * $Id: SearchUnit.cpp
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 10/4/04.
6  * Modified by Nathan Sturtevant on 02/29/20.
7  *
8  * This file is part of HOG2. See https://github.com/nathansttt/hog2 for licensing information.
9  *
10  */
11 
12 #include <iostream>
13 #include "SearchUnit.h"
14 
15 using namespace GraphAbstractionConstants;
16 using namespace std;
17 
18 static const bool verbose = false;
19 
20 SearchUnit::SearchUnit(int _x, int _y, AbsMapUnit *_target, SearchAlgorithm *alg)
21 :AbsMapUnit(_x, _y)
22 {
23  target = _target;
24  algorithm = alg;
25  s_algorithm = 0;
26  spread_cache = 0;
27  onTarget = false;
28  nodesExpanded = 0;
29  nodesTouched = 0;
30  targetTime = 0;
31 }
32 
33 //SearchUnit::SearchUnit(int _x, int _y, unit *_target, spreadExecSearchAlgorithm *alg)
34 //:unit(_x, _y, _target)
35 //{
36 // unitType = kWorldObject;
37 // algorithm = alg;
38 // s_algorithm = alg;
39 // spread_cache = 0;
40 // onTarget = false;
41 // nodesExpanded = 0;
42 // nodesTouched = 0;
43 //}
44 //
45 //SearchUnit::SearchUnit(int _x, int _y, int _r, int _g, int _b, unit *_target, SearchAlgorithm *alg)
46 //:unit(_x, _y, _r, _g, _b, _target)
47 //{
48 // unitType = kWorldObject;
49 // algorithm = alg;
50 // s_algorithm = 0;
51 // spread_cache = 0;
52 // onTarget = false;
53 // nodesExpanded = 0;
54 // nodesTouched = 0;
55 //}
56 //
57 //SearchUnit::SearchUnit(int _x, int _y, float _r, float _g, float _b, unit *_target, SearchAlgorithm *alg)
58 //:unit(_x, _y, _r, _g, _b, _target)
59 //{
60 // unitType = kWorldObject;
61 // algorithm = alg;
62 // s_algorithm = 0;
63 // spread_cache = 0;
64 // onTarget = false;
65 // nodesExpanded = 0;
66 // nodesTouched = 0;
67 //}
68 
69 //SearchUnit::SearchUnit(int _x, int _y, int _r, int _g, int _b, unit *_target, SearchAlgorithm *alg)
70 //:unit(_x, _y, _r, _g, _b, _target)
71 //{
72 // unitType = kWorldObject;
73 // algorithm = alg;
74 // onTarget = false;
75 // nodesExpanded = 0;
76 // nodesTouched = 0;
77 //}
78 
80 {
81  if (algorithm)
82  delete algorithm;
83  algorithm = 0;
84  if (spread_cache)
85  delete spread_cache;
86  spread_cache = 0;
87 }
88 
90 {
91  if (moves.size() > 0)
92  {
93  if (s_algorithm && (spread_cache == 0))
94  {
98  }
99  dir = moves.back();
100  moves.pop_back();
101  // if (verbose)
102  // printf("SU %p: returning cached move 0x%X\n", this, (int)dir);
103  return true;
104  }
105  return false;
106 }
107 
109 {
110  if (getCachedMove(res))
111  return true;
112 
113  Map *map = mp->GetMap();
114  MapAbstraction *aMap = mp->GetMapAbstraction();
115 
116  // if we have a cache to be used, use it!
117  if (spread_cache)
118  {
120  node *next_start = spread_cache->tail()->n;
121  int targx, targy;
122  xyLoc l;
123  target->GetLocation(l);
124  targx = l.x;
125  targy = l.y;
126 
127  // Get a path by path-planning
128  node *to = aMap->GetAbstractGraph(0)->GetNode(map->GetNodeNum(targx, targy));
129 
130  s_algorithm->setTargets(mp->GetMapAbstraction(), next_start, to, rp);
131  delete spread_cache;
132  spread_cache = 0;
133  res = moves.back();
134  moves.pop_back();
135  return true;
136  }
137 
138  // Check if we have a target defined
139  if (!target)
140  {
141  if (verbose)
142  printf("SU %s: No target, doing nothing\n", this->GetName());
143  return false;
144  }
145 
146  // Get the position of the target
147  int targx, targy;
148  xyLoc l;
149  target->GetLocation(l);
150  targx = l.x;
151  targy = l.y;
152 
153  // Get a path by path-planning
154  Graph *g0 = aMap->GetAbstractGraph(0);
155  // Get the start and goal nodes
156  node *from = g0->GetNode(map->GetNodeNum(loc.x, loc.y));
157  node *to = g0->GetNode(map->GetNodeNum(targx, targy));
158 
159  if (from == to)
160  {
161  if (!onTarget)
162  {
163  if (verbose)
164  {
165  printf("STAY ON TARGET!\n");
166  printf("%p target time %1.4f\n", (void*)this, targetTime);
167  }
168  if (simInfo)
169  targetTime = simInfo->GetSimulationTime();
170  }
171  onTarget = true;
172 // return kStay;
173  }
174  else
175  onTarget = false;
176 // if (verbose)
177 // printf("SU %p: Getting new path\n", this);
178  path *p;
179  p = algorithm->GetPath(aMap, from, to, rp);
182 
183  // returning an empty path means there is no path between the start and goal
184  if (p == NULL)
185  {
186  if (verbose)
187  printf("SU %s: Path returned NIL\n", this->GetName());
188  return false;
189  }
190 
191  if (!(p->n && p->next && p->next->n && (loc.x == p->n->GetLabelL(kFirstData))
192  && (loc.y == p->n->GetLabelL(kFirstData+1))))
193  {
194  if (p->n)
195  std::cout << *p->n << std::endl;
196  if ((p->next) && (p->next->n))
197  std::cout << *p->next->n << std::endl;
198  std::cout << loc.x << ", " << loc.y << std::endl;
199  }
200 
201  // a valid path must have at least 2 nodes and start where the unit is located
202  assert(p->n && p->next && p->next->n && (loc.x == p->n->GetLabelL(kFirstData))
203  && (loc.y == p->n->GetLabelL(kFirstData+1)));
204 
205  addPathToCache(p);
206  if (s_algorithm)
207  {
208  node *next_start = p->tail()->n;
209  s_algorithm->setTargets(mp->GetMapAbstraction(), next_start, to, rp);
210  }
211  delete p;
212 
213  assert(moves.size() > 0);
214 
215  res = moves.back();
216  moves.pop_back();
217 // if (verbose)
218 // printf("SU %p: returning move 0x%X\n", this, (int)dir);
219  return true;
220 }
221 
223 {
224  // we are at the last move; abort recursion
225  if (p->next == NULL)
226  return;
227  // there is another move; add it first to cache
228  if (p->next->next)
230 
231  // ----- Ok, we have a path starting at (x,y) [the current location] and
232  // having at least one more state ----------------------------------------
233 
234  // Take the first move off the path and execute it
235  int result = kStay;
236 
237  // Decide on the horizontal move
238  switch ((p->n->GetLabelL(kFirstData)-p->next->n->GetLabelL(kFirstData)))
239  {
240  case -1: result = kE; break;
241  case 0: break;
242  case 1: result = kW; break;
243  default :
244  printf("SU: %s : The (x) nodes in the path are not next to each other!\n",
245  this->GetName());
246  printf("Distance is %ld\n",
248  std::cout << *p->n << "\n" << *p->next->n << "\n";
249  exit(10); break;
250  }
251 
252  // Tack the vertical move onto it
253  // Notice the exploit of particular encoding of kStay, kE, etc. labels
254  switch ((p->n->GetLabelL(kFirstData+1)-p->next->n->GetLabelL(kFirstData+1)))
255  {
256  case -1: result = result|kS; break;
257  case 0: break;
258  case 1: result = result|kN; break;
259  default :
260  printf("SU: %s : The (y) nodes in the path are not next to each other!\n",
261  this->GetName());
262  printf("Distance is %ld\n",
263  p->n->GetLabelL(kFirstData+1)-p->next->n->GetLabelL(kFirstData+1));
264  std::cout << *p->n << "\n" << *p->next->n << "\n";
265  exit(10); break;
266  }
267  moves.push_back((tDirection)result);
268 }
269 
270 void SearchUnit::updateLocation(int _x, int _y, bool success, AbsMapSimulationInfo *)
271 {
272  if (!success)
273  {
274  moves.clear();
275  delete spread_cache;
276  spread_cache = 0;
277  if (verbose)
278  printf("SU %s: clearing cached moves, (%d,%d)\n", this->GetName(),_x,_y);
279  }
280  loc.x = _x; loc.y = _y;
281 }
282 
283 void SearchUnit::OpenGLDraw(const AbsMapEnvironment *ame, const AbsMapSimulationInfo *si) const
284 {
285  printf("Drawing unit %p\n", this);
286  GLdouble xx, yy, zz, rad;
287  Map *map = ame->GetMap();
288 
289  int posx = loc.x, posy = loc.y;
290  map->GetOpenGLCoord(posx, posy, xx, yy, zz, rad);
291  glColor3f(r, g, b);
292  glBegin(GL_LINE_STRIP);
293  glVertex3f(xx, yy, zz-rad/2);
294  for (int t = moves.size()-1; t >= 0; t--)
295  {
296  posx += ((moves[t]&kE)?1:0) - ((moves[t]&kW)?1:0);
297  posy += ((moves[t]&kS)?1:0) - ((moves[t]&kN)?1:0);
298 
299  map->GetOpenGLCoord(posx, posy, xx, yy, zz, rad);
300 
301  glVertex3f(xx, yy, zz-rad/2);
302  }
303  glEnd();
304 
305  // draw object
306  map->GetOpenGLCoord(loc.x, loc.y, xx, yy, zz, rad);
307  if (onTarget)
308  {
309  double perc = (1.0-sqrt(sqrt(abs(sin(targetTime+0.25*si->GetSimulationTime())))));
310  glColor3f(r*perc, g*perc, b*perc);
311  }
312  else
313  glColor3f(r, g, b);
314  DrawSphere(xx, yy, zz, rad);
315 
316  // draw target
317  if (target)
318  {
319  xyLoc tloc;
320  target->GetLocation(tloc);
321  map->GetOpenGLCoord(tloc.x, tloc.y, xx, yy, zz, rad);
322 
323  double perc = (1.0-sqrt(sqrt(abs(sin(targetTime+0.25*si->GetSimulationTime())))));
324  glColor3f(r*perc, g*perc, b*perc);
325 
326  DrawPyramid(xx, yy, zz, 1.1*rad, 0.75*rad);
327  }
328 }
329 
331 {
332  if (((nodesExpanded == 0) && (nodesTouched != 0)) ||
333  ((nodesExpanded != 0) && (nodesTouched == 0)))
334  {
335  printf("Error; somehow nodes touched/expanded are inconsistent. t:%d e:%d\n",
337  }
338  // printf("SearchUnit::LogStats(nodesExpanded=%d, nodesTouched=%d)\n",nodesExpanded,nodesTouched);
339  if (nodesExpanded != 0)
340  stats->AddStat("nodesExpanded", GetName(), (long)nodesExpanded);
341  if (nodesTouched != 0)
342  stats->AddStat("nodesTouched", GetName(), (long)nodesTouched);
344 }
345 
347 {
348  algorithm->LogFinalStats(stats);
349 }
350 
351 //void SearchUnit::printRoundStats(FILE *f)
352 //{
353 // fprintf(f," %d", nodesExpanded);
354 // nodesExpanded = 0;
355 //}
SearchUnit::getCachedMove
bool getCachedMove(tDirection &dir)
Definition: SearchUnit.cpp:89
GraphAbstractionConstants
Definition: GraphAbstraction.h:22
MapProvider::GetMap
virtual Map * GetMap() const =0
loc::x
int x
Definition: MapGenerators.cpp:296
SearchUnit::addPathToCache
virtual void addPathToCache(path *p)
Definition: SearchUnit.cpp:222
SearchAlgorithm::LogFinalStats
virtual void LogFinalStats(StatCollection *)
Definition: SearchAlgorithm.h:33
SearchUnit::OpenGLDraw
virtual void OpenGLDraw(const AbsMapEnvironment *, const AbsMapSimulationInfo *) const
Definition: SearchUnit.cpp:283
Map::GetNodeNum
int GetNodeNum(int x, int y, tCorner c=kNone)
Gets the abstract Graph node number for this tile.
Definition: Map.cpp:2339
MapProvider::GetMapAbstraction
virtual MapAbstraction * GetMapAbstraction()=0
SimulationInfo
Definition: SimulationInfo.h:13
SearchAlgorithm::GetNodesTouched
uint64_t GetNodesTouched()
Definition: SearchAlgorithm.h:32
SearchUnit::~SearchUnit
virtual ~SearchUnit()
Definition: SearchUnit.cpp:79
verbose
static const bool verbose
Definition: SearchUnit.cpp:18
MapProvider
Definition: MapProvider.h:23
loc::y
int y
Definition: MapGenerators.cpp:296
SearchUnit::nodesExpanded
int nodesExpanded
Definition: SearchUnit.h:54
SimulationInfo::GetSimulationTime
virtual double GetSimulationTime() const =0
xyLoc::y
uint16_t y
Definition: Map2DEnvironment.h:42
AbsMapUnit
A simple map-based unit.
Definition: AbsMapUnit.h:24
kW
@ kW
Definition: Map2DEnvironment.h:78
path::n
node * n
Definition: Path.h:22
SearchAlgorithm::GetNodesExpanded
uint64_t GetNodesExpanded()
Definition: SearchAlgorithm.h:31
DrawSphere
void DrawSphere(GLdouble _x, GLdouble _y, GLdouble _z, GLdouble tRadius)
Definition: GLUtil.cpp:433
xyLoc
Definition: Map2DEnvironment.h:37
AbsMapUnit::r
GLfloat r
Definition: AbsMapUnit.h:42
Graph
A generic Graph class.
Definition: Graph.h:66
SearchUnit::moves
std::vector< tDirection > moves
Definition: SearchUnit.h:56
Graph::GetNode
node * GetNode(unsigned long num)
Definition: Graph.cpp:152
xyLoc::x
uint16_t x
Definition: Map2DEnvironment.h:41
SearchUnit::targetTime
double targetTime
Definition: SearchUnit.h:64
kStay
@ kStay
Definition: Map2DEnvironment.h:79
spreadExecSearchAlgorithm::think
virtual path * think()=0
do next processing for path, returns avaliability of path moves
loc
Definition: MapGenerators.cpp:296
SearchUnit::makeMove
virtual bool makeMove(MapProvider *, reservationProvider *, AbsMapSimulationInfo *simInfo, tDirection &dir)
Definition: SearchUnit.cpp:108
SearchUnit::GetName
virtual const char * GetName()
Definition: SearchUnit.h:30
kE
@ kE
Definition: Map2DEnvironment.h:78
GraphAbstractionConstants::kFirstData
@ kFirstData
Definition: GraphAbstraction.h:34
SearchUnit::target
AbsMapUnit * target
Definition: SearchUnit.h:62
AbsMapUnit::b
GLfloat b
Definition: AbsMapUnit.h:42
AbsMapUnit::g
GLfloat g
Definition: AbsMapUnit.h:42
tDirection
tDirection
Definition: Map2DEnvironment.h:77
SearchUnit::SearchUnit
SearchUnit(int x, int y, AbsMapUnit *target, SearchAlgorithm *alg)
Definition: SearchUnit.cpp:20
SearchUnit::spread_cache
path * spread_cache
Definition: SearchUnit.h:60
SearchAlgorithm::GetPath
virtual path * GetPath(GraphAbstraction *aMap, node *from, node *to, reservationProvider *rp=0)=0
SearchUnit::nodesTouched
int nodesTouched
Definition: SearchUnit.h:55
SearchUnit.h
spreadExecSearchAlgorithm::setTargets
virtual void setTargets(GraphAbstraction *_aMap, node *s, node *e, reservationProvider *_rp=0)
Definition: SpreadExecSearchAlgorithm.h:23
kN
@ kN
Definition: Map2DEnvironment.h:78
SearchUnit::algorithm
SearchAlgorithm * algorithm
Definition: SearchUnit.h:58
SearchUnit::updateLocation
virtual void updateLocation(int _x, int _y, bool, AbsMapSimulationInfo *)
Definition: SearchUnit.cpp:270
StatCollection
The StatCollection class is for collecting stats across different parts of the simulation.
Definition: StatCollection.h:34
path::tail
path * tail()
Definition: Path.h:28
std
Definition: CanonicalGraphEnvironment.h:26
SearchUnit::s_algorithm
spreadExecSearchAlgorithm * s_algorithm
Definition: SearchUnit.h:59
kS
@ kS
Definition: Map2DEnvironment.h:78
reservationProvider
Definition: ReservationProvider.h:33
SearchAlgorithm
A generic algorithm which can be used for pathfinding.
Definition: SearchAlgorithm.h:25
SearchUnit::onTarget
bool onTarget
Definition: SearchUnit.h:65
StatCollection::AddStat
void AddStat(const char *category, const char *owner, double value)
Add a new stat entry for the given category, owner and value.
Definition: StatCollection.cpp:67
Map::GetOpenGLCoord
bool GetOpenGLCoord(int _x, int _y, GLdouble &x, GLdouble &y, GLdouble &z, GLdouble &radius) const
Get the openGL coordinates of a given tile.
Definition: Map.cpp:1826
path::next
path * next
Definition: Path.h:23
node::GetLabelL
long GetLabelL(unsigned int index) const
Definition: Graph.h:220
path
A linked list of nodes which form a continuous path.
Definition: Path.h:20
AbsMapUnit::GetLocation
virtual void GetLocation(xyLoc &l)
Definition: AbsMapUnit.h:34
SearchUnit::LogFinalStats
void LogFinalStats(StatCollection *stats)
log any final one-time stats before a simulation is ended
Definition: SearchUnit.cpp:346
node
Nodes to be stored within a Graph.
Definition: Graph.h:170
Map
A tile-based representation of the world.
Definition: Map.h:142
DrawPyramid
void DrawPyramid(GLfloat x, GLfloat y, GLfloat z, GLfloat height, GLfloat width)
Draw a pyramid with the tip at the given location, given height, and width from center to edge as wid...
Definition: GLUtil.cpp:185
SearchUnit::LogStats
void LogStats(StatCollection *stats)
log an stats that may have been computed during the last run
Definition: SearchUnit.cpp:330