HOG2
UnitSimulation.h
Go to the documentation of this file.
1 /*
2  * $Id: unitSimulation.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 9/30/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 #ifndef UNITSIMULATION_H
13 #define UNITSIMULATION_H
14 
15 #include <vector>
16 #include <queue>
17 #include "Unit.h"
18 #include "Timer.h"
19 #include "FPUtil.h"
20 #include "StatCollection.h"
21 #include "SearchEnvironment.h"
22 #include "OccupancyInterface.h"
23 #include "SimulationInfo.h"
24 
29 template <class state, class action>
30 class TimeStep {
31 public:
32  TimeStep(state s, double time)
33  :m_state(s), startTime(time) {}
34  TimeStep() { startTime = 0; }
35  state m_state;
36  double startTime;
37 };
38 
39 template <class state, class action, class environment>
40 class Unit;
41 
42 template <class state, class action, class environment>
43 class UnitGroup;
44 
45 
46 template <class state, class action, class environment>
47 class UnitInfo {
48 public:
49  UnitInfo() :stateHistory(0), converged(false) {}
51  int GetPriority() { return agent->GetPriority(); }
52  action lastMove;
53  state startState;
54  state lastState;
55  state currentState;
56 // double thinkTime, moveDist;
57  double lastTime;
58  double nextTime;
59  unsigned int historyIndex;
60  double totalDistance;
61  double totalThinking;
62  bool converged;
63  std::vector<TimeStep<state, action> > stateHistory;
64 };
65 
66 //template<class state, class action>
67 //class UnitInfoCompare {
68 //public:
69 // bool operator()(const UnitInfo<state, action> *u1, const UnitInfo<state, action> *u2);
70 //};
71 
72 
73 // kLockStep - each unit goes exactly to the next time
74 // kRealTime - each unit goes up thinkingTime*thinkingPenalty + movement time*speed
75 // kMinTime - each unit goes up at least step time, but can go longer
76 // that is, max(next time, thinkingTime*thinkingPenalty + movement time*speed)
77 enum tTimestep {
79 };
80 
84 template<class state, class action, class environment>
85 class UnitSimulation : public SimulationInfo<state, action, environment> {
86 public:
87  UnitSimulation(environment *se);
88  virtual ~UnitSimulation();
89 
91  virtual int AddUnit(Unit<state, action, environment> *u, double timeOffset = 0.);
92  unsigned int GetNumUnits() const;
93  Unit<state, action, environment> *GetUnit(unsigned int which);
94  unsigned int GetNumUnitGroups() const;
95 
98  virtual void ClearAllUnits();
99 
100  virtual void GetPublicUnitInfo(unsigned int which, PublicUnitInfo<state,action,environment> &info) const;
101 
102  environment *GetEnvironment() { return env; }
103 
104  void StepTime(double);
105  double GetSimulationTime() const { return currTime; }
106  double GetTimeToNextStep() const;
107  void SetStepType(tTimestep step) { stepType = step; }
108  tTimestep GetStepType() const { return stepType; }
109 
110  void SetPaused(bool val) { paused = val; }
111  bool GetPaused() { return paused; }
112 
113  bool Done();
114 
116  void SetThinkingPenalty(double pen) { penalty = pen; }
118  double GetThinkingPenalty() { return penalty; }
119 
120  virtual void OpenGLDraw() const;
121  virtual void OpenGLDraw(unsigned int whichUnit) const;
122 
123  void SetLogStats(bool val) { logStats = val; }
124  bool GetLogStats() { return logStats; }
125  StatCollection* GetStats() { return &stats; }
126 
127 
129  virtual unsigned int GetCurrentUnit() const { return currentActor; }
130 
131 protected:
132  void StepUnitTime(UnitInfo<state, action, environment> *ui, double timeStep);
133  bool MakeUnitMove(UnitInfo<state, action, environment> *theUnit, action where, double &moveCost);
134 
135  virtual void DoPreTimestepCalc();
136  virtual void DoTimestepCalc(double amount);
137  virtual void DoPostTimestepCalc();
138 
139  double penalty;
141  std::vector<UnitInfo<state, action, environment> *> units;
142  std::vector<UnitGroup<state, action, environment> *> unitGroups;
143  environment *env;
144  double currTime;
147  mutable unsigned int currentActor;
148 // SimulationInfo<state,action,environment> sinfo;
149 };
150 
151 template<class state, class action, class environment>
153 {
154  env = se;
155  stepType = kRealTime;
156  penalty = 0.;
157  currTime = 0.;
158  paused = false;
159  logStats = true;
160  unitGroups.push_back(new UnitGroup<state, action, environment>);
161  currentActor = 0;
162  // allocate default unit group!(?)
163 }
164 
165 template<class state, class action, class environment>
167  ClearAllUnits();
168  unitGroups.clear();
169 }
170 
171 template<class state, class action, class environment>
173 {
175  ui->agent = u;
176  u->GetLocation(ui->startState);
177  ui->currentState = ui->startState;
178  ui->lastState = ui->startState;
179  if (ui->agent->GetUnitGroup() == 0)
180  {
181  ui->agent->SetUnitGroup(unitGroups[0]);
182  }
183  ui->agent->GetUnitGroup()->UpdateLocation(ui->agent, env, ui->currentState, true, this );
184  ui->nextTime = currTime + timeOffset;
185  ui->totalThinking = 0.0;
186  ui->totalDistance = 0.0;
187  ui->historyIndex = 0;
188 
189  if (0)//(keepHistory)
190  {
192  ui->stateHistory.push_back(ts);
193  }
194  units.push_back(ui);
195  ui->agent->SetNum( units.size() - 1 );
196  return units.size()-1;
197 }
198 
199 template<class state, class action, class environment>
201 {
202  return units.size();
203 }
204 
205 template<class state, class action, class environment>
207 {
208  if (which < units.size())
209  return units[which]->agent;
210  return 0;
211 }
212 
213 template<class state, class action, class environment>
215 {
216  unitGroups.push_back(ug);
217  return unitGroups.size()-1;
218 }
219 
220 template<class state, class action, class environment>
222 {
223  return unitGroups.size();
224 }
225 
226 template<class state, class action, class environment>
228 {
229  if (which < unitGroups.size())
230  return units[which];
231  return 0;
232 }
233 
234 template<class state, class action, class environment>
236 {
237  info.init(units[which]->startState, units[which]->currentState,
238  units[which]->lastState, units[which]->lastMove,
239  units[which]->lastTime, units[which]->nextTime);
240 }
241 
242 template<class state, class action, class environment>
244 {
245  while (units.size() > 0)
246  {
247  UnitInfo<state, action, environment> *ui = units.back();
248  if (logStats)
249  ui->agent->LogFinalStats(&stats);
250  OccupancyInterface<state, action> *envInfo = env->GetOccupancyInfo();
251  if (envInfo)
252  envInfo->SetStateOccupied(ui->currentState, false);
253  units.pop_back();
254  delete ui->agent;
255  delete ui;
256  }
257 // while (unitGroups.size() > 0)
258 // {
259 // //unitGroups.back()->LogFinalStats(&stats);
260 // delete unitGroups.back();
261 // unitGroups.pop_back();
262 // }
263  //unitGroups.push_back(new unitGroup(this));
264  //sinfo = SimulationInfo<state,action,environment>();
265  currTime = 0.;
266  currentActor = 0;
267 }
268 
269 template<class state, class action, class environment>
271 {
272  // assumes that all units belong to a unit group
273  for (unsigned int i=0; i<unitGroups.size(); i++)
274  {
275  if (!unitGroups[i]->Done())
276  return false;
277  }
278  return true;
279 }
280 
281 //template<class state, class action, class environment>
282 //double UnitSimulation<state, action, environment>::SetUnitLocation(UnitInfo<state, action, environment> *ui,
283 // bool success, bool usetimer)
284 //{
285 // Timer t;
286 // if (usetimer)
287 // {
288 // t.StartTimer();
289 // }
290 // if (ui->agent->getUnitGroup() == 0)
291 // {
292 // ui->agent->UpdateLocation(ui->currentState, success);
293 // }
294 // else {
295 // u->agent->getUnitGroup()->updateLocation(ui->agent, ui->currentState, success);
296 // }
297 // if (usetimer)
298 // {
299 // return t.EndTimer();
300 // }
301 // return 0;
302 //}
303 
304 template<class state, class action, class environment>
306  double minimum = DBL_MAX;
307 
308  for ( unsigned int i = 0; i < units.size(); i++ ) {
309  if ( minimum > units[i]->nextTime - currTime )
310  minimum = units[i]->nextTime - currTime;
311  }
312  if ( minimum < 1./30. )
313  fprintf( stderr, "Warning: GetTimeToNextStep sank under 1./30. (%g).\n", minimum );
314  return minimum;
315 }
316 
317 
318 template<class state, class action, class environment>
320 {
321  //std::cout<<"StepTime\n";
322  if (paused)
323  {
324  return;
325  }
326  DoPreTimestepCalc();
327  if (logStats)
328  stats.AddStat("simulationTime", "UnitSimulation", currTime);
329  currTime += timeStep;
330  DoTimestepCalc(timeStep);
331  DoPostTimestepCalc();
332 
333  //std::cout<<"currTime "<<currTime<<std::endl;
334  //if (Done()) std::cout<<"DONE!!!\n";
335 }
336 
337 template<class state, class action, class environment>
339 {
340 }
341 
342 template<class state, class action, class environment>
344 {
345  for (unsigned int x = 0; x < units.size(); x++)
346  {
347  currentActor = x;
348  StepUnitTime(units[x], timeStep);
349 
350  if (stepType == kRealTime)
351  {
352  while (currTime > units[x]->nextTime)
353  StepUnitTime(units[x], 0);
354  }
355  }
356 }
357 
358 template<class state, class action, class environment>
360 {
361 }
362 
370 template<class state, class action, class environment>
372 {
373  if (currTime < theUnit->nextTime) return;
374 
375  double moveThinking=0, locThinking=0, moveTime=0;
376  action where;
377  Timer t;
379 
380  t.StartTimer();
381  // need to do if/then check - makemove ok or not? need to stay where you are?
382  if (u->GetUnitGroup()->MakeMove(u, env, this, where))
383  {
384  moveThinking = t.EndTimer();
385  theUnit->totalThinking += moveThinking;
386  theUnit->lastMove = where;
387  theUnit->lastTime = theUnit->nextTime;
388  theUnit->lastState = theUnit->currentState;
389  if (logStats)
390  stats.SumStat("MakeMoveThinkingTime", u->GetName(), moveThinking);
391 
392  bool success = MakeUnitMove(theUnit, where, moveTime);
393  //printf("Updating last state\n");
394 
395  t.StartTimer();
396  u->GetUnitGroup()->UpdateLocation(theUnit->agent, env, theUnit->currentState, success, this);
397  locThinking = t.EndTimer();
398  theUnit->totalThinking += locThinking;
399  if (logStats)
400  stats.SumStat("UpdateLocationThinkingTime", u->GetName(), locThinking);
401 
402  switch (stepType)
403  {
404  case kLockStep:
405  theUnit->nextTime = currTime + timeStep;
406  break;
407  case kUniTime:
408  theUnit->nextTime = currTime + 1.;
409  break;
410  case kRealTime:
411  //printf("Incrementing time from %f to %f\n", theUnit->nextTime, theUnit->nextTime+moveTime);
412  theUnit->nextTime += (locThinking+moveThinking)*penalty + moveTime;
413  break;
414  case kMinTime:
415  theUnit->nextTime += max((locThinking+moveThinking)*penalty + moveTime, timeStep);
416  break;
417  }
418  //u->GetUnitGroup()->LogStats(&stats);
419  u->LogStats(&stats);
420  }
421  else // stay where you are
422  {
423  theUnit->lastTime = theUnit->nextTime;
424  theUnit->lastState = theUnit->currentState;
425 
426  if ( stepType == kUniTime )
427  theUnit->nextTime = currTime + 1.;
428  else
429  theUnit->nextTime += theUnit->agent->GetSpeed();
430  theUnit->agent->GetUnitGroup()->UpdateLocation(theUnit->agent, env, theUnit->currentState, true, this);
431  }
432 
433 }
434 
435 template<class state, class action, class environment>
437 {
438  bool success = false;
439  moveCost = 0;
440  state oldState = theUnit->currentState;
441  env->ApplyAction(theUnit->currentState, where);
442  OccupancyInterface<state, action> *envInfo = env->GetOccupancyInfo();
443 
444  // TODO: Perhaps we need a legal action test here to handle the
445  // cases where we can't generate all possible actions.
446  bool legal = false;
447 
448  std::vector<action> succ;
449  env->GetActions(oldState, succ);
450  for (unsigned int x = 0; x < succ.size(); x++)
451  {
452  if (succ[x] == where)
453  {
454  legal = true;
455  break;
456  }
457  }
458 
459  if (legal &&
460  (!envInfo || (envInfo && envInfo->CanMove(oldState, theUnit->currentState))))
461  {
462  success = true;
463  moveCost = env->GCost(oldState, theUnit->currentState)*theUnit->agent->GetSpeed();
464  theUnit->totalDistance += env->GCost(oldState, theUnit->currentState);
465 
466  if (envInfo)
467  {
468  envInfo->MoveUnitOccupancy(oldState, theUnit->currentState);
469  }
470  }
471  else {
472 // if (!envInfo)
473 // success = true;
474 // else
475  success = false;
476 
477  theUnit->currentState = oldState;
478  }
479 
480  return success;
481 }
482 
483 /* ATTENTION!!!! This function gives away the current real information,
484  * this is a security issue but for performance we still did it!
485 */
486 template<class state, class action, class environment>
488 {
489  env->OpenGLDraw();
490  for (unsigned int x = 0; x < units.size(); x++)
491  {
492  currentActor = x;
493  units[x]->agent->OpenGLDraw(env, this);
494  }
495 
496  for (unsigned int x = 0; x <unitGroups.size(); x++)
497  unitGroups[x]->OpenGLDraw(env, this);
498 }
499 
500 template<class state, class action, class environment>
502 {
503  if (whichUnit >= units.size())
504  return;
505 
506  currentActor = whichUnit;
507  units[whichUnit]->agent->OpenGLDraw(env, this);
508 }
509 
510 
511 #endif
UnitSimulation::SetThinkingPenalty
void SetThinkingPenalty(double pen)
setPenalty for thinking.
Definition: UnitSimulation.h:116
UnitInfo::startState
state startState
Definition: UnitSimulation.h:53
UnitInfo::currentState
state currentState
Definition: UnitSimulation.h:55
UnitGroup
Definition: UnitGroup.h:31
UnitSimulation::stats
StatCollection stats
Definition: UnitSimulation.h:146
SimulationInfo
Definition: SimulationInfo.h:13
StatCollection.h
UnitSimulation::currentActor
unsigned int currentActor
Definition: UnitSimulation.h:147
UnitInfo::totalDistance
double totalDistance
Definition: UnitSimulation.h:60
UnitInfo::historyIndex
unsigned int historyIndex
Definition: UnitSimulation.h:59
Timer::StartTimer
void StartTimer()
Definition: Timer.cpp:9
UnitSimulation::GetEnvironment
environment * GetEnvironment()
Definition: UnitSimulation.h:102
UnitInfo::GetPriority
int GetPriority()
Definition: UnitSimulation.h:51
UnitSimulation::OpenGLDraw
virtual void OpenGLDraw() const
Definition: UnitSimulation.h:487
OccupancyInterface.h
UnitSimulation::DoTimestepCalc
virtual void DoTimestepCalc(double amount)
Definition: UnitSimulation.h:343
UnitSimulation::GetStats
StatCollection * GetStats()
Definition: UnitSimulation.h:125
FPUtil.h
UnitSimulation::GetTimeToNextStep
double GetTimeToNextStep() const
Definition: UnitSimulation.h:305
OccupancyInterface::SetStateOccupied
virtual void SetStateOccupied(const state &, bool)=0
UnitInfo::totalThinking
double totalThinking
Definition: UnitSimulation.h:61
kRealTime
@ kRealTime
Definition: UnitSimulation.h:78
UnitSimulation::SetStepType
void SetStepType(tTimestep step)
Definition: UnitSimulation.h:107
Unit::GetName
virtual const char * GetName()=0
PublicUnitInfo::init
void init(state &_startState, state &_currentState, state &_lastState, action _lastMove, double _lastTime, double _nextTime)
Definition: SimulationInfo.h:49
kUniTime
@ kUniTime
Definition: UnitSimulation.h:78
UnitSimulation::DoPostTimestepCalc
virtual void DoPostTimestepCalc()
Definition: UnitSimulation.h:359
UnitInfo::lastState
state lastState
Definition: UnitSimulation.h:54
UnitSimulation::env
environment * env
Definition: UnitSimulation.h:143
Timer.h
UnitSimulation::AddUnitGroup
int AddUnitGroup(UnitGroup< state, action, environment > *ug)
Definition: UnitSimulation.h:214
kLockStep
@ kLockStep
Definition: UnitSimulation.h:78
UnitSimulation::SetLogStats
void SetLogStats(bool val)
Definition: UnitSimulation.h:123
UnitInfo::lastMove
action lastMove
Definition: UnitSimulation.h:52
OccupancyInterface::MoveUnitOccupancy
virtual void MoveUnitOccupancy(const state &, const state &)=0
SimulationInfo.h
UnitSimulation::SetPaused
void SetPaused(bool val)
Definition: UnitSimulation.h:110
TimeStep::m_state
state m_state
Definition: UnitSimulation.h:35
UnitSimulation::MakeUnitMove
bool MakeUnitMove(UnitInfo< state, action, environment > *theUnit, action where, double &moveCost)
Definition: UnitSimulation.h:436
TimeStep::startTime
double startTime
Definition: UnitSimulation.h:36
Unit::GetLocation
virtual void GetLocation(state &)=0
UnitSimulation::ClearAllUnits
virtual void ClearAllUnits()
Definition: UnitSimulation.h:243
UnitInfo::converged
bool converged
Definition: UnitSimulation.h:62
UnitSimulation::paused
bool paused
Definition: UnitSimulation.h:140
UnitInfo
Definition: UnitSimulation.h:47
OccupancyInterface::CanMove
virtual bool CanMove(const state &, const state &)=0
UnitInfo::stateHistory
std::vector< TimeStep< state, action > > stateHistory
Definition: UnitSimulation.h:63
UnitSimulation::GetStepType
tTimestep GetStepType() const
Definition: UnitSimulation.h:108
TimeStep
Private per-unit unitSimulation data.
Definition: UnitSimulation.h:30
tTimestep
tTimestep
Definition: UnitSimulation.h:77
UnitSimulation::units
std::vector< UnitInfo< state, action, environment > * > units
Definition: UnitSimulation.h:141
UnitSimulation::StepTime
void StepTime(double)
Definition: UnitSimulation.h:319
UnitSimulation::UnitSimulation
UnitSimulation(environment *se)
Definition: UnitSimulation.h:152
TimeStep::TimeStep
TimeStep(state s, double time)
Definition: UnitSimulation.h:32
max
#define max(a, b)
Definition: MinimalSectorAbstraction.cpp:40
UnitSimulation::GetPublicUnitInfo
virtual void GetPublicUnitInfo(unsigned int which, PublicUnitInfo< state, action, environment > &info) const
Definition: UnitSimulation.h:235
UnitSimulation::stepType
tTimestep stepType
Definition: UnitSimulation.h:145
UnitSimulation::GetPaused
bool GetPaused()
Definition: UnitSimulation.h:111
UnitInfo::nextTime
double nextTime
Definition: UnitSimulation.h:58
StatCollection
The StatCollection class is for collecting stats across different parts of the simulation.
Definition: StatCollection.h:34
TimeStep::TimeStep
TimeStep()
Definition: UnitSimulation.h:34
UnitSimulation::~UnitSimulation
virtual ~UnitSimulation()
Definition: UnitSimulation.h:166
UnitSimulation::GetNumUnitGroups
unsigned int GetNumUnitGroups() const
Definition: UnitSimulation.h:221
UnitSimulation::GetSimulationTime
double GetSimulationTime() const
Definition: UnitSimulation.h:105
UnitSimulation
The basic simulation class for the world.
Definition: UnitSimulation.h:85
UnitInfo::lastTime
double lastTime
Definition: UnitSimulation.h:57
UnitInfo::UnitInfo
UnitInfo()
Definition: UnitSimulation.h:49
UnitSimulation::Done
bool Done()
Definition: UnitSimulation.h:270
UnitSimulation::GetNumUnits
unsigned int GetNumUnits() const
Definition: UnitSimulation.h:200
Unit::GetUnitGroup
UnitGroup< state, action, environment > * GetUnitGroup()
Definition: Unit.h:47
Unit::LogStats
virtual void LogStats(StatCollection *)
log an stats that may have been computed during the last run
Definition: Unit.h:40
UnitSimulation::DoPreTimestepCalc
virtual void DoPreTimestepCalc()
Definition: UnitSimulation.h:338
UnitSimulation::GetSimulationInfo
virtual SimulationInfo< state, action, environment > * GetSimulationInfo()
Definition: UnitSimulation.h:128
UnitSimulation::GetThinkingPenalty
double GetThinkingPenalty()
getPenalty for thinking.
Definition: UnitSimulation.h:118
UnitSimulation::AddUnit
virtual int AddUnit(Unit< state, action, environment > *u, double timeOffset=0.)
Definition: UnitSimulation.h:172
UnitSimulation::GetLogStats
bool GetLogStats()
Definition: UnitSimulation.h:124
kMinTime
@ kMinTime
Definition: UnitSimulation.h:78
Timer
Definition: Timer.h:19
UnitSimulation::penalty
double penalty
Definition: UnitSimulation.h:139
UnitSimulation::GetUnit
Unit< state, action, environment > * GetUnit(unsigned int which)
Definition: UnitSimulation.h:206
PublicUnitInfo
Definition: SimulationInfo.h:9
UnitSimulation::StepUnitTime
void StepUnitTime(UnitInfo< state, action, environment > *ui, double timeStep)
step time for a single unit.
Definition: UnitSimulation.h:371
UnitSimulation::GetCurrentUnit
virtual unsigned int GetCurrentUnit() const
Definition: UnitSimulation.h:129
UnitSimulation::currTime
double currTime
Definition: UnitSimulation.h:144
UnitSimulation::logStats
bool logStats
Definition: UnitSimulation.h:140
Timer::EndTimer
double EndTimer()
Definition: Timer.cpp:15
UnitSimulation::GetUnitGroup
UnitGroup< state, action, environment > * GetUnitGroup(unsigned int which)
Definition: UnitSimulation.h:227
UnitInfo::agent
Unit< state, action, environment > * agent
Definition: UnitSimulation.h:50
SearchEnvironment.h
UnitSimulation::unitGroups
std::vector< UnitGroup< state, action, environment > * > unitGroups
Definition: UnitSimulation.h:142
Unit.h
Unit
Definition: Unit.h:23
OccupancyInterface
Definition: OccupancyInterface.h:36