Robot.java
Go to the documentation of this file.
1 
6 import java.util.List;
7 import java.util.LinkedList;
8 import java.util.Map;
9 import java.util.HashMap;
10 import java.util.TreeMap;
11 public interface Robot
12 {
14  public class Robot_Specs implements Cloneable
15  {
17  public int attack;
18 
20  public int defense;
21 
23  public int power;
24 
26  public int charge;
27 
29  public Object clone() throws CloneNotSupportedException
30  { return super.clone(); }
31  }
32 
37  public class Robot_Status implements Cloneable
38  {
40  public int power;
41 
43  public int charge;
44 
46  public int health;
47 
49  public int defense_boost;
50 
59  public int[] capsules;
60 
62  public Robot_Status() { capsules = new int[0]; }
63 
65  public Object clone() throws CloneNotSupportedException
66  {
67  Robot_Status to_return = (Robot_Status)(super.clone());
68  to_return.capsules = capsules.clone();
69  return to_return;
70  }
71  };
72 
74  public enum GridObject { EMPTY, BLOCKED, SELF, ALLY, ENEMY, WALL, FORT, CAPSULE };
75 
77  public enum Direction { UP, DOWN, LEFT, RIGHT };
78 
80  public class GridCell implements Cloneable
81  {
83  public int x_coord;
84 
86  public int y_coord;
87 
90 
93 
95  public int capsule_power;
96 
98  public Object clone() throws CloneNotSupportedException
99  { return super.clone(); }
100  }
101 
103  public enum AttackType { MELEE, RANGED, CAPSULE };
104 
107  public class AttackNotice
108  {
110  GridCell origin;
111 
113  AttackType form;
114 
116  int damage;
117  }
118 
120  public enum AttackResult { MISSED, HIT, DESTROYED_TARGET };
121 
125  public class RobotUtility
126  {
128  public abstract static class FSPPredicate
129  {
130  public abstract boolean validCell(GridCell cell);
131  }
132 
139  public static GridCell findNearestAlly(GridCell origin, GridCell[][] grid)
140  {
141  GridCell[] path = findShortestPathInternal(origin, new RoboSim.SimGridAllyDeterminant(origin), new FSPPredicate() {
142  public boolean validCell(GridCell cell) { return true; }}, grid);
143 
144  if(path==null)
145  return null;
146  else
147  return path[path.length-1];
148  }
149 
163  public static GridCell[] findShortestPath(GridCell origin, final GridCell target, GridCell[][] grid)
164  {
165  return findShortestPathInternal(origin,new FSPPredicate () {
166  public boolean validCell(GridCell maybeTarget)
167  {
168  return maybeTarget==target;
169  }
170  },
171  new FSPPredicate() {
172  public boolean validCell(GridCell maybePassable)
173  {
174  return maybePassable.contents==GridObject.EMPTY;
175  }
176  },
177  grid);
178  }
179 
180  private static GridCell[] findShortestPathInternal(GridCell origin, FSPPredicate isTarget, FSPPredicate isPassable, GridCell[][] grid)
181  {
182  //Offsets to handle incomplete world map
183  int x_offset = grid[0][0].x_coord;
184  int y_offset = grid[0][0].y_coord;
185 
186  //Structures to efficiently handle accounting
187  TreeMap<Integer,LinkedList<GridCell>> unvisited_nodes = new TreeMap<Integer,LinkedList<GridCell>>(); //this is really a multimap
188  Map<GridCell,LinkedList<GridCell>> current_costs = new HashMap<GridCell,LinkedList<GridCell>>();
189 
190  //Origin's shortest path is simply itself
191  LinkedList<GridCell> origin_path = new LinkedList<GridCell>();
192  origin_path.add(origin);
193 
194  //Initialize graph search with origin
195  current_costs.put(origin,origin_path);
196  unvisited_nodes.put(0,origin_path);
197 
198  while(unvisited_nodes.size()!=0)
199  {
200  Map.Entry<Integer,LinkedList<GridCell>> current_entry = unvisited_nodes.firstEntry();
201  int our_cost = current_entry.getKey();
202  GridCell our_cell = current_entry.getValue().pop();
203  LinkedList<GridCell> current_path = current_costs.get(our_cell);
204 
205  //If we are a destination, algorithm has finished: return our current path
206  if(isTarget.validCell(our_cell))
207  return current_path.toArray(new GridCell[0]);
208 
209  //Erase our cost mapping from unvisited_nodes if necessary
210  if(current_entry.getValue().size()==0)
211  unvisited_nodes.remove(our_cost);
212 
213  /*We are adjacent to up to 4 nodes, with
214  coordinates relative to ours as follows:
215  (-1,0),(1,0),(0,-1),(0,1)*/
216  LinkedList<GridCell> adjacent_nodes = new LinkedList<GridCell>();
217  int gridX_value = our_cell.x_coord - x_offset;
218  int gridY_value = our_cell.y_coord - y_offset;
219  if(gridX_value!=0)
220  adjacent_nodes.add(grid[gridX_value-1][gridY_value]);
221  if(gridX_value!=grid.length-1)
222  adjacent_nodes.add(grid[gridX_value+1][gridY_value]);
223  if(gridY_value!=0)
224  adjacent_nodes.add(grid[gridX_value][gridY_value-1]);
225  if(gridY_value!=grid[0].length-1)
226  adjacent_nodes.add(grid[gridX_value][gridY_value+1]);
227 
228  /*Iterate over adjacent nodes, add to or update
229  entry in unvisited_nodes and current_costs if
230  necessary*/
231  for(GridCell x : adjacent_nodes)
232  {
233  //If we're not passable, we can't be used as an adjacent cell, unless we're a target
234  if(!isPassable.validCell(x) && !isTarget.validCell(x))
235  continue;
236 
237  //Generate proposed path
238  LinkedList<GridCell> x_proposed_path = (LinkedList<GridCell>)(current_path.clone());
239  x_proposed_path.add(x);
240 
241  //current least cost path
242  List<GridCell> clcp = current_costs.get(x);
243 
244  if(clcp!=null && clcp.size()-1>our_cost+1)
245  {
246  LinkedList<GridCell> old_unvisited = unvisited_nodes.get(clcp.size()-1);
247  old_unvisited.removeFirstOccurrence(x);
248  if(old_unvisited.size()==0)
249  unvisited_nodes.remove(clcp.size()-1);
250  }
251  else if(clcp!=null && clcp.size()-1<=our_cost+1)
252  continue;
253 
254  LinkedList<GridCell> new_unvisited = unvisited_nodes.get(our_cost+1);
255  if(new_unvisited==null)
256  {
257  new_unvisited = new LinkedList<GridCell>();
258  unvisited_nodes.put(our_cost+1,new_unvisited);
259  }
260  new_unvisited.add(x);
261  current_costs.put(x,x_proposed_path);
262  }
263  }
264 
265  /*Loop is over, and we didn't find a path to the target :(
266  Return null.*/
267  return null;
268  }
269  }
270 
286  Robot_Specs createRobot(WorldAPI api, int skill_points, byte[] message);
287 
289  enum BuildStatus { WALL, FORT, CAPSULE, ROBOT };
290 
303  void act(WorldAPI api, Robot_Status status, byte[][] received_radio);
304 }
Direction fort_orientation
Definition: Robot.java:92
static GridCell[] findShortestPath(GridCell origin, final GridCell target, GridCell[][] grid)
Definition: Robot.java:163
Object clone()
Definition: Robot.java:98
Definition: Robot.java:11
static GridCell[] findShortestPathInternal(GridCell origin, FSPPredicate isTarget, FSPPredicate isPassable, GridCell[][] grid)
Definition: Robot.java:180
abstract boolean validCell(GridCell cell)
void act(WorldAPI api, Robot_Status status, byte[][] received_radio)
static GridCell findNearestAlly(GridCell origin, GridCell[][] grid)
Definition: Robot.java:139
Object clone()
Definition: Robot.java:65
Object clone()
Definition: Robot.java:29
GridObject contents
Definition: Robot.java:89
int capsule_power
Definition: Robot.java:95
Robot_Specs createRobot(WorldAPI api, int skill_points, byte[] message)