robot_api::RobotUtility Class Reference

#include <robot_api.hpp>

Static Public Member Functions

static GridCellfindNearestAlly (GridCell &origin, std::vector< std::vector< GridCell > > &grid)
 
static std::list< GridCell * > findShortestPath (GridCell &origin, const GridCell &target, std::vector< std::vector< GridCell > > &grid)
 

Static Private Member Functions

static std::list< GridCell * > findShortestPathInternal (GridCell &origin, const std::function< bool(const GridCell &)> &isTarget, const std::function< bool(const GridCell &)> &isPassable, std::vector< std::vector< GridCell > > &grid)
 

Detailed Description

RobotUtility class
Provides utilities for students to use in Robot implementations.

Definition at line 146 of file robot_api.hpp.

Member Function Documentation

GridCell * robot_api::RobotUtility::findNearestAlly ( GridCell origin,
std::vector< std::vector< GridCell > > &  grid 
)
static

Find nearest neighbor:
Finds the nearest ally to cell, approximately as the crow flies.

Parameters
origincell to find
gridgrid to analyze
Returns
nearest ally, or null if we have no allies in grid

Definition at line 19 of file robot_api.cpp.

References findShortestPathInternal().

Referenced by RoboSim::RoboAPIImplementor::sendMessage().

20  {
21  auto path = findShortestPathInternal(origin, RoboSim::SimGridAllyDeterminant{origin}, [](const GridCell& ignored) { return true; }, grid);
22 
23  if(path.size()==0)
24  return NULL;
25  else
26  return *(--path.end());
27  }
static std::list< GridCell * > findShortestPathInternal(GridCell &origin, const std::function< bool(const GridCell &)> &isTarget, const std::function< bool(const GridCell &)> &isPassable, std::vector< std::vector< GridCell > > &grid)
Definition: robot_api.cpp:50

Here is the call graph for this function:

Here is the caller graph for this function:

list< GridCell * > robot_api::RobotUtility::findShortestPath ( GridCell origin,
const GridCell target,
std::vector< std::vector< GridCell > > &  grid 
)
static

Shortest path calculator:
Finds the shortest path from one grid cell to another.

This uses Dijkstra's algorithm to attempt to find the shortest path from one grid cell to another. Cells are adjacent if they are up, down, left, or right of each other. Cells are not adjacent if they are diagonal to one another.

Parameters
originstarting grid cell
targetending grid cell
gridgrid to analyze
Returns
a path guaranteed to be the shortest path from the origin to the target. Will return null if no path could be found in the given grid.

Definition at line 29 of file robot_api.cpp.

References robot_api::GridCell::contents, robot_api::EMPTY, and findShortestPathInternal().

Referenced by RoboSim::RoboAPIImplementor::capsuleAttack(), RoboSim::RoboAPIImplementor::rangedAttack(), and DemoBot::searchAndDestroy().

30  {
31  return findShortestPathInternal(origin,[&target](const GridCell& maybeTarget)
32  {
33  //normal == would compare by value;
34  //this simulates Java's "same object" test
35  //I /think/ compare-by-value would work too here, but why risk it?
36  //This is probably faster, anyway.
37  return &maybeTarget==&target;
38  },
39  [](const GridCell& maybePassable)
40  {
41  return maybePassable.contents==EMPTY;
42  }, grid);
43  }
GridObject contents
Definition: robot_api.hpp:83
static std::list< GridCell * > findShortestPathInternal(GridCell &origin, const std::function< bool(const GridCell &)> &isTarget, const std::function< bool(const GridCell &)> &isPassable, std::vector< std::vector< GridCell > > &grid)
Definition: robot_api.cpp:50

Here is the call graph for this function:

Here is the caller graph for this function:

list< GridCell * > robot_api::RobotUtility::findShortestPathInternal ( GridCell origin,
const std::function< bool(const GridCell &)> &  isTarget,
const std::function< bool(const GridCell &)> &  isPassable,
std::vector< std::vector< GridCell > > &  grid 
)
staticprivate

Definition at line 50 of file robot_api.cpp.

References a::x, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

Referenced by findNearestAlly(), and findShortestPath().

51  {
52  //Offsets to handle incomplete world map
53  int x_offset = grid[0][0].x_coord;
54  int y_offset = grid[0][0].y_coord;
55 
56  //Structures to efficiently handle accounting
57  multimap<int,GridCell*> unvisited_nodes;
58  unordered_map<GridCell*,list<GridCell*> > current_costs;
59 
60  //Origin's shortest path is nothing
61  list<GridCell*> origin_path = {};
62 
63  //Initialize graph search with origin
64  current_costs[&origin] = origin_path;
65  unvisited_nodes.insert(make_pair(0,&origin));
66 
67  while(unvisited_nodes.size()!=0)
68  {
69  int our_cost;
70  GridCell* our_cell;
71  {
72  auto current_entry = unvisited_nodes.begin();
73  our_cost = current_entry->first;
74  our_cell = current_entry->second;
75  //Anonymous block because current_entry is dangling iterator after this
76  unvisited_nodes.erase(current_entry);
77  }
78 
79  list<GridCell*>& current_path = current_costs[our_cell];
80 
81  //If we are a destination, algorithm has finished: return our current path
82  if(isTarget(*our_cell))
83  return current_path;
84 
85  /*We are adjacent to up to 4 nodes, with
86  coordinates relative to ours as follows:
87  (-1,0),(1,0),(0,-1),(0,1)*/
88  list<GridCell*> adjacent_nodes;
89  int gridX_value = our_cell->x_coord - x_offset;
90  int gridY_value = our_cell->y_coord - y_offset;
91  if(gridX_value!=0)
92  adjacent_nodes.push_back(&grid[gridX_value-1][gridY_value]);
93  if(gridX_value!=grid.size()-1)
94  adjacent_nodes.push_back(&grid[gridX_value+1][gridY_value]);
95  if(gridY_value!=0)
96  adjacent_nodes.push_back(&grid[gridX_value][gridY_value-1]);
97  if(gridY_value!=grid[0].size()-1)
98  adjacent_nodes.push_back(&grid[gridX_value][gridY_value+1]);
99 
100  /*Iterate over adjacent nodes, add to or update
101  entry in unvisited_nodes and current_costs if
102  necessary*/
103  for(GridCell* x : adjacent_nodes)
104  {
105  //If we're not passable, we can't be used as an adjacent cell, unless we're a target
106  if(!isPassable(*x) && !isTarget(*x))
107  continue;
108 
109  //Generate proposed path
110  list<GridCell*> x_proposed_path = current_path;
111  x_proposed_path.push_back(x);
112 
113  //current least cost path
114  if(current_costs.count(x))
115  {
116  list<GridCell*>& clcp = current_costs[x];
117  if(clcp.size()-1>our_cost+1)
118  {
119  auto old_range = unvisited_nodes.equal_range(clcp.size()-1);
120  for(auto i = old_range.first; i!=old_range.second; ++i)
121  if(i->second==x)
122  {
123  unvisited_nodes.erase(i);
124  break;
125  }
126  }
127  else
128  continue;
129  }
130 
131  unvisited_nodes.insert(make_pair(our_cost+1,x));
132  current_costs[x]=x_proposed_path;
133  }
134  }
135 
136  /*Loop is over, and we didn't find a path to the target :(
137  Return empty path.*/
138  return list<GridCell*>();
139  }
int x
Definition: test.cpp:1

Here is the caller graph for this function:


The documentation for this class was generated from the following files: