RoboSim::RoboAPIImplementor Class Reference
Inheritance diagram for RoboSim::RoboAPIImplementor:
Collaboration diagram for RoboSim::RoboAPIImplementor:

Public Member Functions

 RoboAPIImplementor (RoboSim &rsim_, RobotData &actingRobot_)
 
AttackResult meleeAttack (int power, GridCell &adjacent_cell)
 
AttackResult rangedAttack (int power, GridCell &nonadjacent_cell)
 
AttackResult capsuleAttack (int power_of_capsule, GridCell &cell)
 
void defend (int power)
 
void move (int steps, Direction way)
 
void pick_up_capsule (GridCell &adjacent_cell)
 
void drop_capsule (GridCell &adjacent_cell, int power_of_capsule)
 
BuildStatus getBuildStatus ()
 
GridCellgetBuildTarget ()
 
int getInvestedBuildPower ()
 
void setBuildTarget (BuildStatus status, GridCell *location)
 
void setBuildTarget (BuildStatus status, GridCell *location, vector< uint8_t > message)
 
void build (int power)
 
void repair (int power)
 
void charge (int power, GridCell &ally)
 
void sendMessage (vector< uint8_t > message, int power)
 
vector< vector< GridCell > > getVisibleNeighborhood ()
 
vector< vector< GridCell > > getWorld (int power)
 
void scanEnemy (Robot_Specs &enemySpecs, Robot_Status &enemyStatus, GridCell toScan)
 

Private Member Functions

bool isAdjacent (GridCell adjacent_cell)
 
bool calculateHit (int attack, int defense)
 
AttackResult processAttack (int attack, GridCell &cell_to_attack, int power)
 
void finalizeBuilding (vector< uint8_t > creation_message)
 

Private Attributes

RoboSimrsim
 
RobotDataactingRobot
 

Detailed Description

The implementing class for the WorldAPI reference. We can't just use ourselves for this because students could downcast us to our real type and manipulate the simulator in untoward ways (not that any of you would do that, and I would catch it when I reviewed your code anyway, but still).

Definition at line 93 of file RoboSim.hpp.

Constructor & Destructor Documentation

RoboSim::RoboAPIImplementor::RoboAPIImplementor ( RoboSim rsim_,
RobotData actingRobot_ 
)
inline

Constructor

Parameters
actingRobot_data for robot attempting to act in the simulator

Definition at line 104 of file RoboSim.hpp.

Referenced by processAttack().

104 : rsim(rsim_), actingRobot(actingRobot_) { };

Here is the caller graph for this function:

Member Function Documentation

void RoboSim::RoboAPIImplementor::build ( int  power)
inlinevirtual
Parameters
powerhow much power to apply to building the current target. Must not be more than remaining power needed to finish building target.

Implements WorldAPI.

Definition at line 188 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Status::charge, robot_api::RobotData::investedPower, robot_api::RobotData::player, robot_api::Robot_Status::power, and robot_api::RobotData::status.

189  {
190  if(power > actingRobot.status.power || power < 0)
191  throw RoboSimExecutionException("attempted to apply invalid power to build task",actingRobot.player,*actingRobot.assoc_cell);
192  actingRobot.status.charge-=power;
193  actingRobot.status.power-=power;
194  actingRobot.investedPower+=power;
195  }
Robot_Status status
Definition: robot_api.hpp:109
GridCell * assoc_cell
Definition: robot_api.hpp:107
bool RoboSim::RoboAPIImplementor::calculateHit ( int  attack,
int  defense 
)
inlineprivate

Did the attacker hit the defender?

Parameters
attackattack skill of attacker (including bonuses/penalties)
defensedefense skill of defender (including bonuses)
Returns
whether the attacker hit

Definition at line 126 of file RoboSim.hpp.

Referenced by processAttack().

127  {
128  int luckOfAttacker = rand()%10;
129  return luckOfAttacker+attack-defense>=5;
130  }

Here is the caller graph for this function:

AttackResult RoboSim::RoboAPIImplementor::capsuleAttack ( int  power_of_capsule,
GridCell cell 
)
virtual

Capsule attack: attack with a capsule

Parameters
power_of_capsulepower of the capsule to use in the attack
cellGridCell (may be adjacent or nonadjacent) to attack

Implements WorldAPI.

Definition at line 306 of file RoboSim.cpp.

References robot_api::ALLY, robot_api::BLOCKED, robot_api::CAPSULE, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::RobotUtility::findShortestPath(), robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::SELF, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

307 {
308  //Error checking, *sigh*...
309 
310  //Does cell exist in grid?
311  if(cell.x_coord > rsim.worldGrid.size() || cell.y_coord > rsim.worldGrid[0].size() || cell.x_coord < 0 || cell.y_coord < 0)
312  throw RoboSimExecutionException("passed invalid cell coordinates to capsuleAttack()",actingRobot.player,*actingRobot.assoc_cell,cell);
313 
314  //Cell to attack
315  GridCell& cell_to_attack = rsim.worldGrid[cell.x_coord][cell.y_coord];
316 
317  //Do we have a capsule of this power rating?
318  auto capsule_it = find(actingRobot.status.capsules.begin(),actingRobot.status.capsules.end(),power_of_capsule);
319 
320  if(capsule_it==actingRobot.status.capsules.end())
321  throw RoboSimExecutionException(string("passed invalid power to capsuleAttack(): doesn't have capsule of power ")+to_string(power_of_capsule),actingRobot.player,*actingRobot.assoc_cell);
322 
323  //Can we use this capsule? (attack + defense >= power)
324  if(actingRobot.specs.attack + actingRobot.specs.defense < power_of_capsule)
325  throw RoboSimExecutionException("attempted to use capsule of greater power than attack+defense",actingRobot.player,*actingRobot.assoc_cell);
326 
327  //Can we hit the target? Range is power of capsule + defense.
328  list<GridCell*> shortest_path = robot_api::RobotUtility::findShortestPath(*actingRobot.assoc_cell,cell_to_attack,rsim.worldGrid);
329 
330  if(!shortest_path.size())
331  throw RoboSimExecutionException("no clear shot to target",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
332 
333  if(shortest_path.size() > power_of_capsule + actingRobot.specs.defense)
334  throw RoboSimExecutionException("target not in range",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
335 
336  //Is there an enemy, fort, or wall at the cell's location?
337  switch(cell_to_attack.contents)
338  {
339  case EMPTY:
340  throw RoboSimExecutionException("attempted to attack empty cell",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
341  case BLOCKED:
342  throw RoboSimExecutionException("attempted to attack blocked tile",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
343  case SELF:
344  if(cell_to_attack.occupant_data->player==actingRobot.player)
345  throw RoboSimExecutionException("attempted to attack ally",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
346  break;
347  case CAPSULE:
348  throw RoboSimExecutionException("attempted to attack energy capsule",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
349  case ALLY:
350  throw RoboSimExecutionException("ERROR in RoboSim.RoboAPIImplementor.capsuleAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
351  }
352 
353  /*Okay, if we're still here, we can use the capsule.
354  Need to delete capsule from robot status structure.
355  */
356  actingRobot.status.capsules.erase(capsule_it);
357 
358  //Process attack
359  return processAttack(actingRobot.specs.attack + power_of_capsule,cell_to_attack,(int)(ceil(0.1 * power_of_capsule * actingRobot.specs.attack)));
360 }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
AttackResult processAttack(int attack, GridCell &cell_to_attack, int power)
Definition: RoboSim.cpp:123
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
static std::list< GridCell * > findShortestPath(GridCell &origin, const GridCell &target, std::vector< std::vector< GridCell > > &grid)
Definition: robot_api.cpp:29

Here is the call graph for this function:

void RoboSim::RoboAPIImplementor::charge ( int  power,
GridCell ally 
)
inlinevirtual

Spend power to charge an adjacent ally robot. 1-for-1 efficiency.

Parameters
poweramount of power to use for charging ally
allycell containing ally to charge. Must be adjacent.

Implements WorldAPI.

Definition at line 210 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Status::charge, robot_api::GridCell::contents, robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::Robot_Status::power, robot_api::SELF, robot_api::RobotData::status, RoboSim::worldGrid, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

211  {
212  //Check that we're using a valid amount of power
213  if(power > actingRobot.status.power || power < 1)
214  throw RoboSimExecutionException("attempted charge with illegal power level",actingRobot.player,*actingRobot.assoc_cell);
215 
216  //Are cells adjacent?
217  if(!isAdjacent(ally))
218  throw RoboSimExecutionException("attempted to charge nonadjacent cell",actingRobot.player,*actingRobot.assoc_cell);
219 
220  //Does cell exist in grid?
221  //(could put this in isAdjacent() method but want to give students more useful error messages)
222  if(ally.x_coord > rsim.worldGrid.size() || ally.y_coord > rsim.worldGrid[0].size() || ally.x_coord < 0 || ally.y_coord < 0)
223  throw RoboSimExecutionException("passed invalid cell coordinates to charge()",actingRobot.player,*actingRobot.assoc_cell,ally);
224 
225  //Safe to use this now, checked for oob condition from student
226  GridCell& allied_cell = rsim.worldGrid[ally.x_coord][ally.y_coord];
227 
228  //Is there an ally in that cell?
229  if(allied_cell.contents!=SELF || allied_cell.occupant_data->player!=actingRobot.player)
230  throw RoboSimExecutionException("attempted to charge non-ally, or cell with no robot in it",actingRobot.player,*actingRobot.assoc_cell,allied_cell);
231 
232  //Perform the charge
233  actingRobot.status.power-=power;
234  actingRobot.status.charge-=power;
235  allied_cell.occupant_data->status.charge+=power;
236  }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void RoboSim::RoboAPIImplementor::defend ( int  power)
inlinevirtual

Defend: increase defense

Parameters
powerpower to use for defense (may not exceed defense skill)

Implements WorldAPI.

Definition at line 145 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Status::charge, robot_api::Robot_Specs::defense, robot_api::Robot_Status::defense_boost, robot_api::RobotData::player, robot_api::Robot_Specs::power, robot_api::RobotData::specs, and robot_api::RobotData::status.

146  {
147  //Error checking
148  if(power < 0 || power > actingRobot.specs.defense || power > actingRobot.specs.power || power > actingRobot.status.charge)
149  throw RoboSimExecutionException("attempted to defend with negative power",actingRobot.player, *actingRobot.assoc_cell);
150 
151  //This one's easy
152  actingRobot.status.charge-=power;
154  }
Robot_Status status
Definition: robot_api.hpp:109
GridCell * assoc_cell
Definition: robot_api.hpp:107
void RoboSim::RoboAPIImplementor::drop_capsule ( GridCell adjacent_cell,
int  power_of_capsule 
)
virtual

drop_capsule: drop a capsule (for an ally to pick up, presumably)

Parameters
adjacent_cellwhere to drop capsule (must be adjacent)
power_of_capsulehow powerful a capsule to drop

Implements WorldAPI.

Definition at line 469 of file RoboSim.cpp.

References robot_api::CAPSULE, robot_api::GridCell::capsule_power, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

470 {
471  //Error checking, *sigh*...
472  //Does cell exist in grid?
473  if(adjacent_cell.x_coord > rsim.worldGrid.size() || adjacent_cell.y_coord > rsim.worldGrid[0].size() || adjacent_cell.x_coord < 0 || adjacent_cell.y_coord < 0)
474  throw RoboSimExecutionException("passed invalid cell coordinates to pick_up_capsule()",actingRobot.player,*actingRobot.assoc_cell,adjacent_cell);
475 
476  //Cell in question
477  GridCell& gridCell = rsim.worldGrid[adjacent_cell.x_coord][adjacent_cell.y_coord];
478 
479  //Cell must be adjacent
480  if(!isAdjacent(adjacent_cell))
481  throw RoboSimExecutionException("attempted to pick up capsule in nonadjacent cell",actingRobot.player,*actingRobot.assoc_cell,gridCell);
482 
483  //Is the cell empty?
484  if(gridCell.contents!=EMPTY)
485  throw RoboSimExecutionException("attempted to place capsule in nonempty cell",actingRobot.player,*actingRobot.assoc_cell,gridCell);
486 
487  //Do we have such a capsule?
488  auto it = find(actingRobot.status.capsules.begin(),actingRobot.status.capsules.end(),power_of_capsule);
489  if(it==actingRobot.status.capsules.end())
490  throw RoboSimExecutionException(string("attempted to drop capsule with power ")+to_string(power_of_capsule)+", having no such capsule",actingRobot.player,*actingRobot.assoc_cell,gridCell);
491 
492  //Okay. We're good. Drop the capsule
493  gridCell.contents = CAPSULE;
494  gridCell.capsule_power = power_of_capsule;
495 
496  //Delete it from our inventory
497  actingRobot.status.capsules.erase(it);
498 }
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void RoboSim::RoboAPIImplementor::finalizeBuilding ( vector< uint8_t >  creation_message)
private

Definition at line 500 of file RoboSim.cpp.

References robot_api::RobotData::assoc_cell, robot_api::CAPSULE, robot_api::Robot_Status::charge, RoboSim::checkSpecsValid(), Robot::createRobot(), robot_api::EMPTY, robot_api::FORT, robot_api::Robot_Status::health, robot_api::NOTHING, robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::Robot_Specs::power, RBP_CALL_CONSTRUCTOR, robot_api::ROBOT, robot_api::RobotData::robot, robot_api::SELF, robot_api::RobotData::specs, robot_api::RobotData::status, robot_api::WALL, and RoboSim::WALL_HEALTH.

501 {
502  //Nothing to finalize if not building anything
504  return;
505 
506  //What do we have to finalize?
507  int capsule_power = actingRobot.investedPower/10;
508  switch(actingRobot.whatBuilding)
509  {
510  case WALL:
511  if(actingRobot.investedPower >= 50)
512  {
515  }
516  else
518  break;
519 
520  case FORT:
521  if(actingRobot.investedPower >= 75)
522  {
525  }
526  else
528  break;
529 
530  case CAPSULE:
531  if(capsule_power!=0)
532  {
534  throw RoboSimExecutionException("attempted to finish building capsule when already at max capsule capacity",actingRobot.player,*actingRobot.assoc_cell);
535  actingRobot.status.capsules.push_back(capsule_power);
536  }
537  break;
538 
539  case ROBOT:
540  int skill_points = actingRobot.investedPower/20;
541  if(skill_points!=0)
542  {
543  //Check creation message correct size
544  if(creation_message.size()!=0 && creation_message.size()!=64)
545  throw RoboSimExecutionException("passed incorrect sized creation message to setBuildTarget()",actingRobot.player,*actingRobot.assoc_cell,*actingRobot.invested_assoc_cell);
546 
547  //Set default creation message if we don't have one
548  if(!creation_message.size())
549  {
550  creation_message.resize(64);
551  creation_message[1] = rsim.turnOrder.size() % 256;
552  creation_message[0] = rsim.turnOrder.size() / 256;
553  }
554 
555  //Create the robot
557  Robot* robot;
558  try
559  {
561  }
562  catch(...)
563  {
564  throw RoboSimExecutionException("something went wrong calling student's constructor", actingRobot.player,*actingRobot.assoc_cell, *actingRobot.invested_assoc_cell);
565  }
566  rsim.turnOrder.emplace_back();
567  RobotData& data = *(rsim.turnOrder.rbegin());
568  data.robot = robot;
571  data.player = actingRobot.player;
572  data.specs = checkSpecsValid(data.robot->createRobot(NULL, skill_points, creation_message), actingRobot.player, skill_points);
573  data.status.charge = data.status.health = data.specs.power*10;
574  }
575  else
577  break;
578  }
579 }
RobotData * occupant_data
Definition: robot_api.hpp:96
Definition: Robot.hpp:19
virtual Robot_Specs createRobot(WorldAPI *api, int skill_points, std::vector< std::uint8_t > message)=0
#define RBP_CALL_CONSTRUCTOR(x)
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
static const int WALL_HEALTH
Definition: RoboSim.hpp:39
BuildStatus whatBuilding
Definition: robot_api.hpp:114
vector< RobotData > turnOrder
Definition: RoboSim.hpp:44
static Robot_Specs checkSpecsValid(Robot_Specs proposed, int player, int skill_points)
Definition: RoboSim.cpp:58
GridCell * assoc_cell
Definition: robot_api.hpp:107
GridCell * invested_assoc_cell
Definition: robot_api.hpp:116

Here is the call graph for this function:

BuildStatus RoboSim::RoboAPIImplementor::getBuildStatus ( )
inlinevirtual

Tells us what we're in the middle of building.

Returns
BuildStatus object indicating what we're building. Is null if we're not building anything.

Implements WorldAPI.

Definition at line 160 of file RoboSim.hpp.

References robot_api::RobotData::whatBuilding.

161  {
162  return actingRobot.whatBuilding;
163  }
BuildStatus whatBuilding
Definition: robot_api.hpp:114
GridCell* RoboSim::RoboAPIImplementor::getBuildTarget ( )
inlinevirtual
Returns
GridCell indicating the target of our building efforts. Is null if we're not building anything.

Implements WorldAPI.

Definition at line 165 of file RoboSim.hpp.

References robot_api::RobotData::invested_assoc_cell.

166  {
168  }
GridCell * invested_assoc_cell
Definition: robot_api.hpp:116
int RoboSim::RoboAPIImplementor::getInvestedBuildPower ( )
inlinevirtual
Returns
how much we've invested in our current build target.

Implements WorldAPI.

Definition at line 170 of file RoboSim.hpp.

References robot_api::RobotData::investedPower.

171  {
172  return actingRobot.investedPower;
173  }
vector<vector<GridCell> > RoboSim::RoboAPIImplementor::getVisibleNeighborhood ( )
inlinevirtual

Gets a copy of the portion of the world visible to the robot. Range is equal to defense skill. Does not cost any power.

Returns
a 2-dimensional array containing a GridCell for each cell visible to the robot.

Implements WorldAPI.

Definition at line 266 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Specs::defense, RoboSim::getSanitizedSubGrid(), robot_api::RobotData::player, robot_api::SELF, robot_api::RobotData::specs, RoboSim::worldGrid, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

267  {
268  //YAY! No parameters means NO ERROR CHECKING! YAY!
269  const int range = actingRobot.specs.defense;
270  const int xloc = actingRobot.assoc_cell->x_coord;
271  const int yloc = actingRobot.assoc_cell->y_coord;
272  const int x_left = (xloc - range < 0) ? 0 : (xloc - range);
273  const int x_right = (xloc + range > rsim.worldGrid.size()-1) ? (rsim.worldGrid.size()-1) : (xloc + range);
274  const int y_up = (yloc - range < 0) ? 0 : (yloc - range);
275  const int y_down = (yloc + range > rsim.worldGrid[0].size() - 1) ? (rsim.worldGrid[0].size()-1) : (yloc + range);
276  vector<vector<GridCell> > to_return = rsim.getSanitizedSubGrid(x_left,y_up,x_right,y_down,actingRobot.player);
277 
278  //Set associated cell to SELF instead of ALLY
279  to_return[xloc - x_left][yloc - y_up].contents=SELF;
280  return to_return;
281  }
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
vector< vector< GridCell > > getSanitizedSubGrid(int x_left, int y_up, int x_right, int y_down, int player) const
Definition: RoboSim.cpp:34

Here is the call graph for this function:

vector<vector<GridCell> > RoboSim::RoboAPIImplementor::getWorld ( int  power)
inlinevirtual

Gets a copy of the entire world. Takes 3 power, plus additional if jamming is taking place (which won't be; jamming is not implemented).

Parameters
powerto spend attempting to get the world
Returns
a 2-dimensional array containing a GridCell for each cell in the world. Will be null if jamming has prevented the world from being retrieved.

Implements WorldAPI.

Definition at line 283 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, RoboSim::getSanitizedSubGrid(), robot_api::RobotData::player, robot_api::SELF, RoboSim::worldGrid, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

284  {
285  if(power!=3)
286  throw RoboSimExecutionException("tried to get world with invalid power (not equal to 3)",actingRobot.player,*actingRobot.assoc_cell);
287 
288  vector<vector<GridCell> > to_return = rsim.getSanitizedSubGrid(0,0,rsim.worldGrid.size()-1,rsim.worldGrid[0].size()-1,actingRobot.player);
289 
290  //Set self to self instead of ally
292  return to_return;
293  }
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
vector< vector< GridCell > > getSanitizedSubGrid(int x_left, int y_up, int x_right, int y_down, int player) const
Definition: RoboSim.cpp:34

Here is the call graph for this function:

bool RoboSim::RoboAPIImplementor::isAdjacent ( GridCell  adjacent_cell)
inlineprivate

Utility method to check whether student's robot is adjacent to cell it is attacking. Note: diagonal cells are not adjacent.

Parameters
adjacent_cellcell to compare with student's robot's position

Definition at line 112 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

113  {
114  return (abs(actingRobot.assoc_cell->x_coord-adjacent_cell.x_coord)==1 &&
115  actingRobot.assoc_cell->y_coord == adjacent_cell.y_coord ||
116  abs(actingRobot.assoc_cell->y_coord-adjacent_cell.y_coord)==1 &&
117  actingRobot.assoc_cell->x_coord == adjacent_cell.x_coord);
118  }
GridCell * assoc_cell
Definition: robot_api.hpp:107
AttackResult RoboSim::RoboAPIImplementor::meleeAttack ( int  power,
GridCell adjacent_cell 
)
virtual

Melee attack: attack an adjacent grid cell

Parameters
powerPower to use for attack (may not exceed attack skill)
adjacent_cellAdjacent GridCell to attack
Returns
AttackResult indicating whether attack succeeded and/or destroyed target of attack.

Implements WorldAPI.

Definition at line 189 of file RoboSim.cpp.

References robot_api::ALLY, robot_api::BLOCKED, robot_api::CAPSULE, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::SELF, robot_api::GridCell::wallforthealth, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

190 {
191  //Lots of error checking here (as everywhere...)
192 
193  //Check that we're using a valid amount of power
194  if(power > actingRobot.status.power || power > actingRobot.specs.attack || power < 1)
195  throw RoboSimExecutionException("attempted melee attack with illegal power level",actingRobot.player,*actingRobot.assoc_cell);
196 
197  //Are cells adjacent?
198  if(!isAdjacent(adjacent_cell))
199  throw RoboSimExecutionException("attempted to melee attack nonadjacent cell",actingRobot.player,*actingRobot.assoc_cell);
200 
201  //Does cell exist in grid?
202  //(could put this in isAdjacent() method but want to give students more useful error messages)
203  if(adjacent_cell.x_coord > rsim.worldGrid.size() || adjacent_cell.y_coord > rsim.worldGrid[0].size() ||
204  adjacent_cell.x_coord < 0 || adjacent_cell.y_coord < 0)
205  throw RoboSimExecutionException("passed invalid cell coordinates to meleeAttack()",actingRobot.player,*actingRobot.assoc_cell,adjacent_cell);
206 
207  //Safe to use this now, checked for oob condition from student
208  GridCell& cell_to_attack = rsim.worldGrid[adjacent_cell.x_coord][adjacent_cell.y_coord];
209 
210  //Is there an enemy, fort, or wall at the cell's location?
211  switch(cell_to_attack.contents)
212  {
213  case EMPTY:
214  throw RoboSimExecutionException("attempted to attack empty cell",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
215  case BLOCKED:
216  throw RoboSimExecutionException("attempted to attack blocked tile",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
217  case SELF:
218  if(cell_to_attack.occupant_data->player==actingRobot.player)
219  throw RoboSimExecutionException("attempted to attack ally",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
220  break;
221  case CAPSULE:
222  throw RoboSimExecutionException("attempted to attack energy capsule",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
223  case ALLY:
224  throw RoboSimExecutionException("ERROR in RoboSim.RoboAPIImplementor.meleeAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
225  }
226 
227  //Okay, if we haven't thrown an exception, the cell is valid to attack. Perform the attack.
228  //Update this robot's charge status and power status.
229  actingRobot.status.charge-=power;
230  actingRobot.status.power-=power;
231 
232  //Begin calculation of our attack power
233  int raw_attack = actingRobot.specs.attack;
234 
235  //If we're outside a fort attacking someone in the fort, range penalty applies
236  if(cell_to_attack.wallforthealth > 0 && cell_to_attack.occupant_data!=NULL)
237  raw_attack/=2;
238 
239  //Attack adds power of attack to raw skill
240  int attack = raw_attack + power;
241 
242  //Process attack
243  return processAttack(attack,cell_to_attack,power);
244 }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
AttackResult processAttack(int attack, GridCell &cell_to_attack, int power)
Definition: RoboSim.cpp:123
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void RoboSim::RoboAPIImplementor::move ( int  steps,
Direction  way 
)
virtual

move: move robot

Parameters
stepshow far to move
waywhich way to move

Implements WorldAPI.

Definition at line 362 of file RoboSim.cpp.

References robot_api::DOWN, robot_api::EMPTY, robot_api::FORT, robot_api::LEFT, robot_api::RIGHT, robot_api::SELF, and robot_api::UP.

363 {
364  if(steps<1)
365  return;
366 
367  int x_coord = actingRobot.assoc_cell->x_coord;
368  const int actor_x = x_coord;
369  int y_coord = actingRobot.assoc_cell->y_coord;
370  const int actor_y = y_coord;
371  switch(way)
372  {
373  case UP:
374  y_coord-=steps;
375  break;
376  case DOWN:
377  y_coord+=steps;
378  break;
379  case LEFT:
380  x_coord-=steps;
381  break;
382  case RIGHT:
383  x_coord+=steps;
384  break;
385  }
386 
387  //Is our destination in the map?
388  if(x_coord < 0 || x_coord > rsim.worldGrid.size() || y_coord < 0 || y_coord > rsim.worldGrid[0].size())
389  throw RoboSimExecutionException("attempted to move out of bounds",actingRobot.player,*actingRobot.assoc_cell);
390 
391  //Is our destination empty?
392  if(rsim.worldGrid[x_coord][y_coord].contents!=EMPTY && rsim.worldGrid[x_coord][y_coord].contents!=FORT)
393  throw RoboSimExecutionException("attempted to move onto illegal cell",actingRobot.player,*actingRobot.assoc_cell,rsim.worldGrid[x_coord][y_coord]);
394 
395  //Are we approaching the fort from the right angle?
396  if(rsim.worldGrid[x_coord][y_coord].contents==FORT && rsim.worldGrid[x_coord][y_coord].fort_orientation!=way)
397  throw RoboSimExecutionException("attempted to move onto a fort from an illegal direction",actingRobot.player,*actingRobot.assoc_cell,rsim.worldGrid[x_coord][y_coord]);
398 
399  //Okay, now we have to make sure each step is empty
400  const bool x_left = x_coord<actor_x;
401  const bool y_left = y_coord<actor_y;
402  if(x_coord!=actor_x)
403  {
404  for(int i=(x_left ? actor_x-1 : actor_x+1); i!=x_coord; i=(x_left ? i-1 : i+1))
405  if(rsim.worldGrid[i][y_coord].contents!=EMPTY)
406  throw RoboSimExecutionException("attempted to cross illegal cell",actingRobot.player,*actingRobot.assoc_cell,rsim.worldGrid[i][y_coord]);
407  }
408  else
409  {
410  for(int i=(y_left ? actor_y-1 : actor_y+1); i!=y_coord; i=(y_left ? i-1 : i+1))
411  if(rsim.worldGrid[x_coord][i].contents!=EMPTY)
412  throw RoboSimExecutionException("attempted to cross illegal cell",actingRobot.player,*actingRobot.assoc_cell,rsim.worldGrid[x_coord][i]);
413  }
414 
415  //Okay, now: do we have enough power/charge?
416  if(steps > actingRobot.status.power)
417  throw RoboSimExecutionException("attempted to move too far (not enough power)",actingRobot.player,*actingRobot.assoc_cell,rsim.worldGrid[x_coord][y_coord]);
418 
419  //Account for power cost
420  actingRobot.status.power-=steps;
421  actingRobot.status.charge-=steps;
422 
423  //Change position of robot.
426  actingRobot.assoc_cell = &rsim.worldGrid[x_coord][y_coord];
429 }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void RoboSim::RoboAPIImplementor::pick_up_capsule ( GridCell adjacent_cell)
virtual

pick_up_capsule: pick up a capsule

Parameters
adjacent_cellGridCell where capsule is that you want to pick up (must be adjacent)

Implements WorldAPI.

Definition at line 431 of file RoboSim.cpp.

References robot_api::CAPSULE, robot_api::GridCell::capsule_power, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

432 {
433  //Error checking, *sigh*...
434 
435  //Does cell exist in grid?
436  if(adjacent_cell.x_coord > rsim.worldGrid.size() || adjacent_cell.y_coord > rsim.worldGrid[0].size() || adjacent_cell.x_coord < 0 || adjacent_cell.y_coord < 0)
437  throw RoboSimExecutionException("passed invalid cell coordinates to pick_up_capsule()",actingRobot.player,*actingRobot.assoc_cell,adjacent_cell);
438 
439  //Cell in question
440  GridCell& gridCell = rsim.worldGrid[adjacent_cell.x_coord][adjacent_cell.y_coord];
441 
442  //Cell must be adjacent
443  if(!isAdjacent(adjacent_cell))
444  throw RoboSimExecutionException("attempted to pick up capsule in nonadjacent cell",actingRobot.player,*actingRobot.assoc_cell,gridCell);
445 
446  //We need at least one power.
447  if(actingRobot.status.power==0)
448  throw RoboSimExecutionException("attempted to pick up capsule with no power",actingRobot.player,*actingRobot.assoc_cell,gridCell);
449 
450  //Is there actually a capsule there?
451  if(gridCell.contents!=CAPSULE)
452  throw RoboSimExecutionException("attempted to pick up capsule from cell with no capsule",actingRobot.player,*actingRobot.assoc_cell,gridCell);
453 
454  //Do we have "room" for this capsule?
456  throw RoboSimExecutionException("attempted to pick up too many capsules",actingRobot.player,*actingRobot.assoc_cell,gridCell);
457 
458  //If still here, yes.
459 
460  //Decrement our power
462 
463  //Put capsule in our inventory, delete it from world
464  actingRobot.status.capsules.push_back(gridCell.capsule_power);
465  gridCell.contents = EMPTY;
466  gridCell.capsule_power = 0;
467 }
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
AttackResult RoboSim::RoboAPIImplementor::processAttack ( int  attack,
GridCell cell_to_attack,
int  power 
)
private

Process attack, assigning damage and deleting destroyed objects if necessary.

Parameters
attackattack skill of attacker (including bonuses/penalties)
cell_to_attackcell attacker is attacking containing enemy or obstacle
damagedamage if attack hits

Definition at line 123 of file RoboSim.cpp.

References calculateHit(), robot_api::GridCell::contents, robot_api::Robot_Specs::defense, robot_api::Robot_Status::defense_boost, robot_api::DESTROYED_TARGET, robot_api::EMPTY, robot_api::FORT, robot_api::Robot_Status::health, robot_api::HIT, robot_api::RobotData::invested_assoc_cell, robot_api::MISSED, robot_api::NOTHING, robot_api::GridCell::occupant_data, RoboAPIImplementor(), rsim, robot_api::SELF, robot_api::RobotData::specs, robot_api::RobotData::status, RoboSim::turnOrder, RoboSim::turnOrder_pos, robot_api::WALL, and robot_api::GridCell::wallforthealth.

124 {
125  //Holds result of attack
126  AttackResult to_return = MISSED;
127 
128  //Calculate defense skill of opponent
129  int defense = 0;
130  switch(cell_to_attack.contents)
131  {
132  case SELF:
133  defense = cell_to_attack.occupant_data->specs.defense + cell_to_attack.occupant_data->status.defense_boost;
134  break;
135 
136  case FORT:
137  case WALL:
138  defense = 10;
139  break;
140  }
141 
142 
143  //If we hit, damage the opponent
144  if(calculateHit(attack,defense))
145  {
146  //We hit
147  to_return = HIT;
148 
149  if(cell_to_attack.occupant_data!=NULL)
150  {
151  //we're a robot
152  for(int i=0; true; i++)
153  if(&rsim.turnOrder[i]==cell_to_attack.occupant_data)
154  {
155  if((cell_to_attack.occupant_data->status.health-=power)<=0)
156  {
157  //We destroyed the opponent!
158  to_return = DESTROYED_TARGET;
159 
160  //Handle in-progress build, reusing setBuildTarget() to handle interruption of build due to death
161  RoboAPIImplementor(rsim,*(cell_to_attack.occupant_data)).setBuildTarget(NOTHING,cell_to_attack.occupant_data->invested_assoc_cell);
162 
163  //Handle cell
164  cell_to_attack.occupant_data = NULL;
165  cell_to_attack.contents = cell_to_attack.wallforthealth>0 ? FORT : EMPTY;
166 
167  //Handle turnOrder position
168  rsim.turnOrder.erase(rsim.turnOrder.begin()+i);
169  if(i<rsim.turnOrder_pos)
171  }
172  break;
173  }
174  }
175  else
176  if((cell_to_attack.wallforthealth-=power)<=0)
177  {
178  //We destroyed the target!
179  to_return = DESTROYED_TARGET;
180 
181  cell_to_attack.wallforthealth = 0;
182  cell_to_attack.contents = EMPTY;
183  }
184  }
185 
186  return to_return;
187 }
RobotData * occupant_data
Definition: robot_api.hpp:96
RoboAPIImplementor(RoboSim &rsim_, RobotData &actingRobot_)
Definition: RoboSim.hpp:104
int turnOrder_pos
Definition: RoboSim.hpp:45
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
vector< RobotData > turnOrder
Definition: RoboSim.hpp:44
GridCell * invested_assoc_cell
Definition: robot_api.hpp:116
bool calculateHit(int attack, int defense)
Definition: RoboSim.hpp:126

Here is the call graph for this function:

AttackResult RoboSim::RoboAPIImplementor::rangedAttack ( int  power,
GridCell nonadjacent_cell 
)
virtual

Ranged attack: attack nonadjacent grid cell within certain range

Parameters
powerPower to use for attack (may not exceed attack skill)
nonadjacent_cellnon-adjacent GridCell to attack
Returns
AttackResult indicating whether attack succeeded and/or destroyed target of attack.

Implements WorldAPI.

Definition at line 246 of file RoboSim.cpp.

References robot_api::ALLY, robot_api::BLOCKED, robot_api::CAPSULE, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::RobotUtility::findShortestPath(), robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::SELF, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

247 {
248  //Lots of error checking here (as everywhere...)
249 
250  //Check that we're using a valid amount of power
251  if(power > actingRobot.status.power || power > actingRobot.specs.attack || power < 1)
252  throw RoboSimExecutionException("attempted ranged attack with illegal power level",actingRobot.player,*actingRobot.assoc_cell);
253 
254  //Does cell exist in grid?
255  //(could put this in isAdjacent() method but want to give students more useful error messages)
256  if(nonadjacent_cell.x_coord > rsim.worldGrid.size() || nonadjacent_cell.y_coord > rsim.worldGrid[0].size() ||
257  nonadjacent_cell.x_coord < 0 || nonadjacent_cell.y_coord < 0)
258  throw RoboSimExecutionException("passed invalid cell coordinates to rangedAttack()",actingRobot.player,*actingRobot.assoc_cell,nonadjacent_cell);
259 
260  //Are cells nonadjacent?
261  if(isAdjacent(nonadjacent_cell))
262  throw RoboSimExecutionException("attempted to range attack adjacent cell",actingRobot.player,*actingRobot.assoc_cell);
263 
264  //Safe to use this now, checked for oob condition from student
265  GridCell& cell_to_attack = rsim.worldGrid[nonadjacent_cell.x_coord][nonadjacent_cell.y_coord];
266 
267  //Do we have a "clear shot"?
268  list<GridCell*> shortest_path = robot_api::RobotUtility::findShortestPath(*actingRobot.assoc_cell,cell_to_attack,rsim.worldGrid);
269  if(!shortest_path.size()) //we don't have a clear shot
270  throw RoboSimExecutionException("attempted to range attack cell with no clear path",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
271  else if(shortest_path.size()>actingRobot.specs.defense) //out of range
272  throw RoboSimExecutionException("attempted to range attack cell more than (defense) tiles away",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
273 
274  //Is there an enemy, fort, or wall at the cell's location?
275  switch(cell_to_attack.contents)
276  {
277  case EMPTY:
278  throw RoboSimExecutionException("attempted to attack empty cell",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
279  case BLOCKED:
280  throw RoboSimExecutionException("attempted to attack blocked tile",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
281  case SELF:
282  if(cell_to_attack.occupant_data->player==actingRobot.player)
283  throw RoboSimExecutionException("attempted to attack ally",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
284  break;
285  case CAPSULE:
286  throw RoboSimExecutionException("attempted to attack energy capsule",actingRobot.player,*actingRobot.assoc_cell,cell_to_attack);
287  case ALLY:
288  throw RoboSimExecutionException("ERROR in RoboSim.RoboAPIImplementor.rangedAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
289  }
290 
291  //Okay, if we haven't thrown an exception, the cell is valid to attack. Perform the attack.
292  //Update this robot's charge status.
293  actingRobot.status.charge-=power;
294  actingRobot.status.power-=power;
295 
296  //Begin calculation of our attack power
297  int raw_attack = actingRobot.specs.attack/2;
298 
299  //Attack adds power of attack to raw skill
300  int attack = raw_attack + power;
301 
302  //Process attack
303  return processAttack(attack,cell_to_attack,power);
304 }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
AttackResult processAttack(int attack, GridCell &cell_to_attack, int power)
Definition: RoboSim.cpp:123
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
static std::list< GridCell * > findShortestPath(GridCell &origin, const GridCell &target, std::vector< std::vector< GridCell > > &grid)
Definition: robot_api.cpp:29

Here is the call graph for this function:

void RoboSim::RoboAPIImplementor::repair ( int  power)
inlinevirtual

Spend power to repair yourself. 2 power restores 1 health.

Parameters
poweramount of power to spend on repairs. Should be even.

Implements WorldAPI.

Definition at line 197 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Specs::charge, robot_api::Robot_Status::charge, robot_api::Robot_Status::health, robot_api::RobotData::player, robot_api::Robot_Status::power, robot_api::RobotData::specs, and robot_api::RobotData::status.

198  {
199  if(power > actingRobot.status.power || power < 0)
200  throw RoboSimExecutionException("attempted to apply invalid power to repair task",actingRobot.player,*actingRobot.assoc_cell);
201  actingRobot.status.charge-=power;
202  actingRobot.status.power-=power;
203  actingRobot.status.health+=power/2;
204 
205  //Can't have more health than charge skill*10
208  }
Robot_Status status
Definition: robot_api.hpp:109
GridCell * assoc_cell
Definition: robot_api.hpp:107
void RoboSim::RoboAPIImplementor::scanEnemy ( Robot_Specs enemySpecs,
Robot_Status enemyStatus,
GridCell  toScan 
)
inlinevirtual

Scans an enemy (or ally), retrieving information about the robot. The cell scanned must be visible (within defense cells from us).
Takes 1 power.

Parameters
enemySpecsempty Robot_Specs object to be filled in
enemyStatusempty Robot_Status object to be filled in
toScancell containing robot we want to scan

Implements WorldAPI.

Definition at line 295 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::Robot_Specs::attack, robot_api::Robot_Status::capsules, robot_api::Robot_Specs::charge, robot_api::Robot_Status::charge, robot_api::GridCell::contents, robot_api::Robot_Specs::defense, robot_api::Robot_Status::defense_boost, robot_api::Robot_Status::health, robot_api::GridCell::occupant_data, robot_api::RobotData::player, robot_api::Robot_Specs::power, robot_api::Robot_Status::power, robot_api::SELF, robot_api::RobotData::specs, robot_api::RobotData::status, RoboSim::worldGrid, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

296  {
297  if(toScan.x_coord < 0 || toScan.x_coord >= rsim.worldGrid.size() || toScan.y_coord < 0 || toScan.y_coord >= rsim.worldGrid[0].size() || actingRobot.status.power==0)
298  throw RoboSimExecutionException("Invalid parameters passed to scanEnemy()",actingRobot.player,*actingRobot.assoc_cell);
299 
300  GridCell& cell = rsim.worldGrid[toScan.x_coord][toScan.y_coord];
301 
302  //Are we within range?
304  throw RoboSimExecutionException("attempted to scan farther than range", actingRobot.player, *actingRobot.assoc_cell);
305 
306  //Is there a robot in this cell?
307  if(cell.contents != SELF)
308  throw RoboSimExecutionException("attempted to scan invalid cell (no robot in cell)", actingRobot.player, *actingRobot.assoc_cell, cell);
309 
310  //Register cost
313 
314  //Okay, we're good. Fill in the data.
315  enemySpecs.attack = cell.occupant_data->specs.attack;
316  enemySpecs.defense = cell.occupant_data->specs.defense;
317  enemySpecs.power = cell.occupant_data->specs.power;
318  enemySpecs.charge = cell.occupant_data->specs.charge;
319  enemyStatus.power = cell.occupant_data->status.power;
320  enemyStatus.charge = cell.occupant_data->status.charge;
321  enemyStatus.health = cell.occupant_data->status.health;
322  enemyStatus.defense_boost = cell.occupant_data->status.defense_boost;
323  enemyStatus.capsules = cell.occupant_data->status.capsules;
324  }
RobotData * occupant_data
Definition: robot_api.hpp:96
GridObject contents
Definition: robot_api.hpp:83
Robot_Status status
Definition: robot_api.hpp:109
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void RoboSim::RoboAPIImplementor::sendMessage ( vector< uint8_t >  message,
int  power 
)
inlinevirtual

Spend additional power to get radio messages unavailable because of jamming.

Parameters
poweramount of power to spend to attempt to overcome jamming
Returns
messages received after additional power spent. Will include all messages included in simulator's call to act(). May be null if no messages were received. Sends a message to an ally or allies.
Parameters
message64-byte array containing message to transmit
poweramount of power to use for sending message

Implements WorldAPI.

Definition at line 238 of file RoboSim.hpp.

References robot_api::RobotData::assoc_cell, robot_api::RobotData::buffered_radio, robot_api::RobotUtility::findNearestAlly(), robot_api::GridCell::occupant_data, robot_api::RobotData::player, RoboSim::turnOrder, RoboSim::worldGrid, and a::x.

239  {
240  if(power < 1 || power > 2)
241  throw RoboSimExecutionException("attempted to send message with invalid power", actingRobot.player,*actingRobot.assoc_cell);
242 
243  if(message.size()!=64)
244  throw RoboSimExecutionException("attempted to send message byte array of incorrect length", actingRobot.player,*actingRobot.assoc_cell);
245 
246  GridCell* target = NULL;
247  if(power==1)
248  {
249  target = RobotUtility::findNearestAlly(*actingRobot.assoc_cell,rsim.worldGrid);
250  if(target!=NULL)
251  {
252  /*There's a way to "cheat" here and set up a power-free comm channel
253  *between two allied robots. If you can find it ... let me know, and
254  *you'll get extra credit :). Additional credit for a bugfix.*/
255  target->occupant_data->buffered_radio.push_back(message);
256  }
257  return;
258  }
259  else //power==2
260  for(RobotData& x : rsim.turnOrder)
261  if(&x!=&actingRobot && x.player==actingRobot.player)
262  x.buffered_radio.push_back(message);
263  }
RobotData * occupant_data
Definition: robot_api.hpp:96
vector< vector< uint8_t > > buffered_radio
Definition: robot_api.hpp:119
int x
Definition: test.cpp:1
vector< RobotData > turnOrder
Definition: RoboSim.hpp:44
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43

Here is the call graph for this function:

void RoboSim::RoboAPIImplementor::setBuildTarget ( BuildStatus  status,
GridCell location 
)
inlinevirtual

Tells the simulator the robot is beginning to build something in an adjacent cell (or, for capsules, inside itself).
In order to mark a capsule or robot as "done", call this method with both parameters null. This will destroy any in-progress build.

Note that you must not move from your current cell while in the process of building anything other than a capsule. If you do, you will lose any in-progress work on a wall or fort, and a robot will be automatically finalized with however many skill points you've invested up to that point.

Parameters
statuswhat we're going to start building (or, in the case of an energy capsule, resume building)
locationwhere to direct our building efforts. Must be an adjacent, empty location, or null if status=capsule.

Implements WorldAPI.

Definition at line 181 of file RoboSim.hpp.

182  {
183  setBuildTarget(status,location,vector<uint8_t>());
184  }
void setBuildTarget(BuildStatus status, GridCell *location)
Definition: RoboSim.hpp:181
void RoboSim::RoboAPIImplementor::setBuildTarget ( BuildStatus  status,
GridCell location,
vector< uint8_t >  message 
)
virtual

Tells the simulator the robot is beginning to build something in an adjacent cell (or, for capsules, inside itself).
In order to mark a capsule or robot as "done", call this method with both parameters null. This will destroy any in-progress build.

Note that you must not move from your current cell while in the process of building anything other than a capsule. If you do, you will lose any in-progress work on a wall or fort, and a robot will be automatically finalized with however many skill points you've invested up to that point.

Parameters
statuswhat we're going to start building (or, in the case of an energy capsule, resume building)
locationwhere to direct our building efforts. Must be an adjacent, empty location, or null if status=capsule.
creation_messagemessage to send to newly created robot (if we're finalizing one)

Implements WorldAPI.

Definition at line 581 of file RoboSim.cpp.

References robot_api::BLOCKED, robot_api::CAPSULE, robot_api::GridCell::contents, robot_api::EMPTY, robot_api::NOTHING, robot_api::GridCell::x_coord, and robot_api::GridCell::y_coord.

582 {
583  //If we're in the middle of building something, finalize it.
585  finalizeBuilding(message);
586 
587  //Error checking, *sigh*...
588 
589  //Does cell exist in grid?
590  if(location!=NULL && (location->x_coord > rsim.worldGrid.size() || location->y_coord > rsim.worldGrid[0].size() || location->x_coord < 0 || location->y_coord < 0))
591  throw RoboSimExecutionException("passed invalid cell coordinates to setBuildTarget()",actingRobot.player,*actingRobot.assoc_cell,*location);
592 
593  //Cell in question
594  GridCell* gridCell = (location!=NULL ? &rsim.worldGrid[location->x_coord][location->y_coord] : NULL);
595 
596  //Update status
597  actingRobot.whatBuilding = status;
599  actingRobot.invested_assoc_cell = gridCell;
600 
601  //CAN pass us null, so special-case it
602  if(location==NULL)
603  {
604  //We must be building capsule, then.
606  throw RoboSimExecutionException("passed null to setBuildTarget() location with non-null and non-capsule build target",actingRobot.player,*actingRobot.assoc_cell);
607  return;
608  }
609 
610  //If location NOT null, must not be building capsule
611  if(status == NOTHING || status == CAPSULE)
612  throw RoboSimExecutionException("attempted to target capsule or null building on non-null adjacent cell",actingRobot.player,*actingRobot.assoc_cell,*location);
613 
614  //Cell must be adjacent
615  if(!isAdjacent(*location))
616  throw RoboSimExecutionException("attempted to set build target to nonadjacent cell",actingRobot.player,*actingRobot.assoc_cell,*gridCell);
617 
618  //Is the cell empty?
619  if(gridCell->contents!=EMPTY)
620  throw RoboSimExecutionException("attempted to set build target to nonempty cell",actingRobot.player,*actingRobot.assoc_cell,*gridCell);
621 
622  //Okay, block off cell since we're building there now.
623  gridCell->contents = BLOCKED;
624 }
GridObject contents
Definition: robot_api.hpp:83
BuildStatus whatBuilding
Definition: robot_api.hpp:114
bool isAdjacent(GridCell adjacent_cell)
Definition: RoboSim.hpp:112
GridCell * assoc_cell
Definition: robot_api.hpp:107
vector< vector< GridCell > > worldGrid
Definition: RoboSim.hpp:43
void finalizeBuilding(vector< uint8_t > creation_message)
Definition: RoboSim.cpp:500
GridCell * invested_assoc_cell
Definition: robot_api.hpp:116

Member Data Documentation

RobotData& RoboSim::RoboAPIImplementor::actingRobot
private

Definition at line 97 of file RoboSim.hpp.

RoboSim& RoboSim::RoboAPIImplementor::rsim
private

Definition at line 96 of file RoboSim.hpp.

Referenced by processAttack().


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