4 import java.util.ArrayList;
6 import java.util.Random;
7 import java.lang.reflect.Constructor;
17 this(message,
player,-1,-1,-1,-1);
22 this(message,
player,cell.x_coord,cell.y_coord,-1,-1);
27 this(message,
player,cell.x_coord,cell.y_coord,cell2.x_coord,cell2.y_coord);
32 super(
"Player "+player_+
" "+message+(x1!=-1 ?
" with robot at coordinates ["+x1+
"]["+y1+
"]" :
"")+(x2!=-1 ?
", coordinates of invalid cell are ["+x2+
"]["+y2+
"]" :
""));
47 switch(potential_ally.contents)
54 SimGridCell origin_downcast = (SimGridCell)(
origin);
55 SimGridCell potential_ally_downcast = (SimGridCell)(potential_ally);
106 return ((
SimGridCell)(to_convert)).occupant_data.player;
121 final int x_length = x_right - x_left + 1;
122 final int y_height = y_down - y_up + 1;
125 for(
int i=x_left; i<=x_right; i++)
126 for(
int j=y_up; j<=y_down; j++)
127 to_return[i-x_left][j-y_up] =
worldGrid[i][j];
142 for(
int i=0; i<simgrid.length; i++)
143 for(
int j=0; j<simgrid[0].length; j++)
150 catch(CloneNotSupportedException e)
152 throw new RuntimeException(
"Problem in sanitizeGrid() clone attempt. This is not the student's fault.");
161 to_return[i][j] = sanitized;
169 if(proposed.attack + proposed.defense + proposed.power + proposed.charge != skill_points)
189 for(
int i=0; i<length; i++)
192 for(
int j=0; j<width; j++)
197 worldGrid[i][j].contents = Robot.GridObject.EMPTY;
202 generator =
new Random();
205 turnOrder =
new ArrayList<RobotData>(combatants.length*initial_robots_per_combatant);
211 for(String player : combatants)
213 Constructor gen_robot;
216 gen_robot = Class.forName(player).getConstructor();
218 catch(ClassNotFoundException e)
222 catch(NoSuchMethodException e)
226 for(
int i=0; i<initial_robots_per_combatant; i++)
231 x_pos = generator.nextInt(length);
232 y_pos = generator.nextInt(width);
233 }
while(
worldGrid[x_pos][y_pos].contents!=
Robot.GridObject.EMPTY);
235 worldGrid[x_pos][y_pos].contents = Robot.GridObject.SELF;
237 data.assoc_cell =
worldGrid[x_pos][y_pos];
240 data.robot = (
Robot)(gen_robot.newInstance());
246 data.player = player;
247 byte[] creation_message =
new byte[64];
248 creation_message[1] = (byte)(turnOrder_pos % 256);
249 creation_message[0] = (byte)(turnOrder_pos / 256);
252 data.status.charge = data.status.health = data.specs.power*10;
253 data.buffered_radio =
new ArrayList<byte[]>();
259 for(
int i=0; i<obstacles; i++)
264 x_pos = generator.nextInt(length);
265 y_pos = generator.nextInt(width);
266 }
while(
worldGrid[x_pos][y_pos].contents!=
Robot.GridObject.EMPTY);
267 worldGrid[x_pos][y_pos].contents = Robot.GridObject.WALL;
300 actingRobot.assoc_cell.y_coord == adjacent_cell.y_coord ||
301 Math.abs(actingRobot.assoc_cell.y_coord-adjacent_cell.y_coord)==1 &&
313 int luckOfAttacker = generator.nextInt(10);
314 return luckOfAttacker+attack-defense>=5;
330 switch(cell_to_attack.contents)
333 defense = cell_to_attack.occupant_data.specs.defense + cell_to_attack.occupant_data.status.defense_boost;
347 to_return = Robot.AttackResult.HIT;
349 if(cell_to_attack.occupant_data!=null)
352 for(
int i=0;
true; i++)
353 if(
turnOrder.get(i)==cell_to_attack.occupant_data)
355 if((cell_to_attack.occupant_data.status.health-=power)<=0)
358 to_return = Robot.AttackResult.DESTROYED_TARGET;
364 cell_to_attack.occupant_data = null;
365 cell_to_attack.contents = cell_to_attack.wallforthealth>0 ? Robot.GridObject.FORT : Robot.GridObject.EMPTY;
376 if((cell_to_attack.wallforthealth-=power)<=0)
379 to_return = Robot.AttackResult.DESTROYED_TARGET;
381 cell_to_attack.wallforthealth = 0;
382 cell_to_attack.contents = Robot.GridObject.EMPTY;
392 if(adjacent_cell==null)
393 throw new RoboSimExecutionException(
"passed null as argument to meleeAttack()",
actingRobot.
player);
406 adjacent_cell.
x_coord < 0 || adjacent_cell.y_coord < 0)
426 throw new RuntimeException(
"ERROR in RoboSim.RoboAPIImplementor.meleeAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
431 actingRobot.status.charge-=power;
432 actingRobot.status.power-=power;
435 int raw_attack = actingRobot.specs.attack;
442 int attack = raw_attack + power;
451 if(nonadjacent_cell==null)
462 nonadjacent_cell.
x_coord < 0 || nonadjacent_cell.y_coord < 0)
473 Robot.GridCell[] shortest_path = Robot.RobotUtility.findShortestPath(actingRobot.assoc_cell,cell_to_attack,
worldGrid);
474 if(shortest_path==null)
480 switch(cell_to_attack.contents)
493 throw new RuntimeException(
"ERROR in RoboSim.RoboAPIImplementor.rangedAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
498 actingRobot.status.charge-=power;
499 actingRobot.status.power-=power;
502 int raw_attack = actingRobot.specs.attack/2;
505 int attack = raw_attack + power;
525 int capsule_index = ArrayUtility.linearSearch(actingRobot.status.capsules,power_of_capsule);
527 if(capsule_index==-1)
535 Robot.GridCell[] shortest_path = Robot.RobotUtility.findShortestPath(actingRobot.assoc_cell,cell_to_attack,
worldGrid);
537 if(shortest_path==null)
544 switch(cell_to_attack.contents)
557 throw new RuntimeException(
"ERROR in RoboSim.RoboAPIImplementor.capsuleAttack(). This is probably not the student's fault. Contact Patrick Simmons about this message. (Not the Doobie Brother...)");
563 actingRobot.status.capsules = ArrayUtility.deleteElement(actingRobot.status.capsules,capsule_index);
565 int[] newCapsules =
new int[actingRobot.status.capsules.length-1];
566 boolean deleted_capsule =
false;
567 for(
int i=0,j=0; i<actingRobot.status.capsules.length; i++,j++)
571 deleted_capsule=
true;
575 newCapsules[j]=actingRobot.status.capsules[i];
589 actingRobot.status.charge-=power;
590 actingRobot.status.defense_boost+=power;
598 int x_coord = actingRobot.assoc_cell.x_coord;
599 final int actor_x = x_coord;
600 int y_coord = actingRobot.assoc_cell.y_coord;
601 final int actor_y = y_coord;
619 if(x_coord < 0 || x_coord >
worldGrid.length || y_coord < 0 || y_coord >
worldGrid[0].length)
623 if(worldGrid[x_coord][y_coord].contents!=
Robot.GridObject.EMPTY && worldGrid[x_coord][y_coord].contents!=
Robot.GridObject.FORT)
627 if(worldGrid[x_coord][y_coord].contents==
Robot.GridObject.FORT && worldGrid[x_coord][y_coord].fort_orientation!=way)
631 final boolean x_left = x_coord<actor_x;
632 final boolean y_left = y_coord<actor_y;
635 for(
int i=(x_left ? actor_x-1 : actor_x+1); i!=x_coord; i=(x_left ? i-1 : i+1))
636 if(worldGrid[i][y_coord].contents!=
Robot.GridObject.EMPTY)
641 for(
int i=(y_left ? actor_y-1 : actor_y+1); i!=y_coord; i=(y_left ? i-1 : i+1))
642 if(worldGrid[x_coord][i].contents!=
Robot.GridObject.EMPTY)
651 actingRobot.status.power-=steps;
652 actingRobot.status.charge-=steps;
655 actingRobot.assoc_cell.contents = Robot.GridObject.EMPTY;
656 actingRobot.assoc_cell.occupant_data = null;
657 actingRobot.assoc_cell = worldGrid[x_coord][y_coord];
658 actingRobot.assoc_cell.contents = Robot.GridObject.SELF;
659 actingRobot.assoc_cell.occupant_data =
actingRobot;
666 if(adjacent_cell==null)
695 actingRobot.status.power--;
698 actingRobot.status.capsules = ArrayUtility.addElement(actingRobot.status.capsules,gridCell.capsule_power);
699 gridCell.contents = Robot.GridObject.EMPTY;
700 gridCell.capsule_power = 0;
707 if(adjacent_cell==null)
726 int index = ArrayUtility.linearSearch(actingRobot.status.capsules,power_of_capsule);
731 gridCell.contents = Robot.GridObject.CAPSULE;
732 gridCell.capsule_power = power_of_capsule;
735 ArrayUtility.deleteElement(actingRobot.status.capsules,index);
740 return actingRobot.whatBuilding;
745 return actingRobot.invested_assoc_cell;
750 return actingRobot.investedPower;
765 actingRobot.invested_assoc_cell.contents = Robot.GridObject.WALL;
766 actingRobot.invested_assoc_cell.wallforthealth =
WALL_HEALTH;
769 actingRobot.invested_assoc_cell.contents = Robot.GridObject.EMPTY;
775 actingRobot.invested_assoc_cell.contents = Robot.GridObject.FORT;
776 actingRobot.invested_assoc_cell.wallforthealth =
WALL_HEALTH;
779 actingRobot.invested_assoc_cell.contents = Robot.GridObject.EMPTY;
783 int capsule_power = actingRobot.investedPower/10;
788 actingRobot.status.capsules = ArrayUtility.addElement(actingRobot.status.capsules,capsule_power);
793 int skill_points = actingRobot.investedPower/20;
797 if(creation_message!=null && creation_message.length!=64)
801 if(creation_message==null)
803 creation_message =
new byte[64];
804 creation_message[1] = (byte)(
turnOrder.size() % 256);
805 creation_message[0] = (byte)(
turnOrder.size() / 256);
809 actingRobot.invested_assoc_cell.contents = Robot.GridObject.SELF;
811 data.assoc_cell = actingRobot.invested_assoc_cell;
820 data.player = actingRobot.player;
823 data.status.charge = data.status.health = data.specs.power*10;
824 data.buffered_radio =
new ArrayList<byte[]>();
828 actingRobot.invested_assoc_cell.contents = Robot.GridObject.EMPTY;
854 actingRobot.whatBuilding = status;
855 actingRobot.investedPower = 0;
856 actingRobot.invested_assoc_cell = gridCell;
868 if(status == null || status ==
Robot.BuildStatus.CAPSULE)
880 gridCell.contents = Robot.GridObject.BLOCKED;
887 actingRobot.status.charge-=power;
888 actingRobot.status.power-=power;
889 actingRobot.investedPower+=power;
896 actingRobot.status.charge-=power;
897 actingRobot.status.power-=power;
898 actingRobot.status.health+=power/2;
902 actingRobot.status.health = actingRobot.specs.charge*10;
909 throw new RoboSimExecutionException(
"passed null as argument to charge()",
actingRobot.
player);
932 actingRobot.status.power-=power;
933 actingRobot.status.charge-=power;
934 allied_cell.occupant_data.status.charge+=power;
939 if(power < 1 || power > 2)
942 if(message.length!=64)
948 target = Robot.RobotUtility.findNearestAlly(actingRobot.assoc_cell,
worldGrid);
954 ((
SimGridCell)(target)).occupant_data.buffered_radio.add(message);
961 x.buffered_radio.add(message);
968 final int range = actingRobot.specs.defense;
969 final int xloc = actingRobot.assoc_cell.x_coord;
970 final int yloc = actingRobot.assoc_cell.y_coord;
971 final int x_left = (xloc - range < 0) ? 0 : (xloc - range);
972 final int x_right = (xloc + range > worldGrid.length-1) ? (
worldGrid.length-1) : (xloc + range);
973 final int y_up = (yloc - range < 0) ? 0 : (yloc - range);
974 final int y_down = (yloc + range >
worldGrid[0].length - 1) ? (
worldGrid[0].length-1) : (yloc + range);
978 to_return[xloc - x_left][yloc - y_up].contents=Robot.GridObject.SELF;
990 to_return[actingRobot.assoc_cell.x_coord][actingRobot.assoc_cell.y_coord].contents=Robot.GridObject.SELF;
996 if(enemySpecs==null || enemyStatus==null || toScan==null
1011 actingRobot.status.power--;
1012 actingRobot.status.charge--;
1015 enemySpecs.attack = cell.occupant_data.specs.attack;
1016 enemySpecs.defense = cell.occupant_data.specs.defense;
1017 enemySpecs.power = cell.occupant_data.specs.power;
1018 enemySpecs.charge = cell.occupant_data.specs.charge;
1019 enemyStatus.power = cell.occupant_data.status.power;
1020 enemyStatus.charge = cell.occupant_data.status.charge;
1021 enemyStatus.health = cell.occupant_data.status.health;
1022 enemyStatus.defense_boost = cell.occupant_data.status.defense_boost;
1023 enemyStatus.capsules = cell.occupant_data.status.capsules.clone();
1040 data.status.charge = Math.min(data.status.charge + data.specs.charge, data.specs.charge*10);
1044 data.status.power = Math.min(data.specs.power, data.status.charge);
1047 data.status.defense_boost = 0;
1055 catch(CloneNotSupportedException e)
1057 throw new RuntimeException(
"error cloning in executeSingleTimeStep. This is not the student's fault.");
1061 data.robot.act(student_api,clonedStatus,data.buffered_radio.toArray(
new byte[0][]));
1064 String player = turnOrder.get(0).player;
1065 for(
int i=1; i<turnOrder.size(); i++)
1066 if(!
turnOrder.get(i).player.equals(player))
RoboSimExecutionException(String message, String player, Robot.GridCell cell)
Robot.GridCell getBuildTarget()
void setBuildTarget(Robot.BuildStatus status, Robot.GridCell location, byte[] message)
void finalizeBuilding(byte[] creation_message)
void setBuildTarget(Robot.BuildStatus status, Robot.GridCell location)
Robot.AttackResult processAttack(int attack, SimGridCell cell_to_attack, int power)
void pick_up_capsule(Robot.GridCell adjacent_cell)
String getOccupantPlayer(Robot.GridCell to_convert)
ArrayList< RobotData > turnOrder
SimGridCell[][] getSubGrid(int x_left, int y_up, int x_right, int y_down)
SimGridCell[][] worldGrid
Robot.GridCell[][] getVisibleNeighborhood()
List< byte[]> buffered_radio
void sendMessage(byte[] message, int power)
RoboAPIImplementor(RobotData actingRobot_)
boolean validCell(Robot.GridCell potential_ally)
static Robot.Robot_Specs checkSpecsValid(Robot.Robot_Specs proposed, String player, int skill_points)
SimGridCell invested_assoc_cell
Robot.AttackResult meleeAttack(int power, Robot.GridCell adjacent_cell)
Robot.BuildStatus getBuildStatus()
Robot.AttackResult rangedAttack(int power, Robot.GridCell nonadjacent_cell)
Robot.AttackResult capsuleAttack(int power_of_capsule, Robot.GridCell cell)
Robot.GridCell[][] getWorldGrid()
void charge(int power, Robot.GridCell ally)
void scanEnemy(Robot.Robot_Specs enemySpecs, Robot.Robot_Status enemyStatus, Robot.GridCell toScan)
boolean calculateHit(int attack, int defense)
Robot.Robot_Status status
RoboSimExecutionException(String message, String player)
int getInvestedBuildPower()
void move(int steps, Robot.Direction way)
boolean isAdjacent(Robot.GridCell adjacent_cell)
void drop_capsule(Robot.GridCell adjacent_cell, int power_of_capsule)
RoboSim(String[] combatants, int initial_robots_per_combatant, int skill_points, int length, int width, int obstacles)
SimGridAllyDeterminant(Robot.GridCell origin_)
static Robot.GridCell[][] sanitizeGrid(SimGridCell[][] simgrid, String player)
RoboSimExecutionException(String message, String player_, int x1, int y1, int x2, int y2)
Robot.GridCell[][] getWorld(int power)
Robot.BuildStatus whatBuilding
String executeSingleTimeStep()
RoboSimExecutionException(String message, String player, Robot.GridCell cell, Robot.GridCell cell2)
Robot_Specs createRobot(WorldAPI api, int skill_points, byte[] message)