Labyrinth
A labyrinth game assignment
HeuristicPlayer.java
Go to the documentation of this file.
1 
13 package host.labyrinth;
14 
19 class HeuristicPlayer extends Player {
20 
32  public HeuristicPlayer(String name, boolean champion, Board board, int row, int column) {
33  super(name, champion, board, row, column);
34  }
35 
43  public HeuristicPlayer(String name, boolean champion, Board board, int tileId) {
44  super(name, champion, board, tileId);
45  }
57  int supplyInDirection(int currentPos, int direction) {
58  Position pos = new Position(Position.toRow(currentPos), Position.toCol(currentPos));
59 
60  for (int i=0 ; board.isWalkable(pos.getId(), direction) && i<Const.viewDistance ; ++i) {
61  pos = new Position(Position.toRow(pos.getId()), Position.toCol(pos.getId()), direction);
62  if (board.hasSupply(pos.getId()))
63  return i+1;
64  }
65  return Const.noSupply;
66  }
67 
74  int opponetInDirection(int currentPos, int direction) {
75  Position pos = new Position(Position.toRow(currentPos), Position.toCol(currentPos));
76  int [][] opps = board.getOpponentMoves(playerId);
77 
78  for (int i=0 ; board.isWalkable(pos.getId(), direction) && i<Const.viewDistance ; ++i) {
79  pos = new Position(Position.toRow(pos.getId()), Position.toCol(pos.getId()), direction);
80  for (int o =0 ; o<opps.length; ++o) {
81  if (opps[o][0] == pos.getId())
82  return i+1;
83  }
84  }
85  return Const.noOpponent;
86  }
87 
94  double evaluate (int currentPos, int direction) {
95  int opDist = opponetInDirection (currentPos, direction);
96  int supDist = supplyInDirection(currentPos, direction);
97 
98  // saturate
99  opDist = (opDist == Const.noOpponent) ? 0: opDist;
100  supDist = (supDist == Const.noSupply) ? 0 : supDist;
101  return ((supDist != 0)? (1.0/supDist * Const.supplyFactor) : 0)
102  - ((opDist != 0) ? (1.0/opDist * Const.opponentFactor) : 0);
103  }
104 
105  // Must return a new move always
106  int getNextMove(int currentPos) {
108  int N = dirs.size();
109  double[] eval = new double[N];
110  int [] eval_dir = new int[N];
111 
112  for (int i =0, dir = dirs.get() ; dir != Const.EOR ; dir = dirs.get(), ++i) {
113  if (board.isWalkable(currentPos, dir))
114  eval[i] = evaluate(currentPos, dir);
115  else
116  eval[i] = Double.NEGATIVE_INFINITY;
117  eval_dir[i] = dir;
118  }
119  int dir;
120  if (isUnevaluated(eval, N)) {
122  do
123  dir = r.get();
124  while (!board.isWalkable(currentPos, dir));
125  }
126  else {
127  dir = directionOfMax (eval, eval_dir, N);
128  }
129  Position new_pos = new Position( Position.toRow(currentPos), Position.toCol(currentPos), dir );
130  return new_pos.getId();
131  }
132 
150  @Override
151  int[] move(int id) {
152  // Initialize return array with the current data
153  int[] ret = new int[Const.moveItems];
154  ret[0] = getNextMove(id);
155  ret[1] = y = Position.toRow(ret[0]);
156  ret[2] = x = Position.toCol(ret[0]);
157  int supplyFlag =0, moveFlag =1;
158  // In case of a champion player, try also to pick a supply
159  if (champion && (ret[3] = board.tryPickSupply(ret[0])) != Const.noSupply) {
160  ++score; // keep score
161  ++supplyFlag;
162  }
163  int dir = Direction.get(id, ret[0]); // update direction counters
164  ++dirCounter[dir];
165  board.updateMove(ret, playerId);
166 
167  // Update supply and opponent distance
168  int smin =DirRange.End, omin =DirRange.End;
169  for (int d = DirRange.Begin ; d<DirRange.End ; d += DirRange.Step) {
170  int s = supplyInDirection (ret[0], d);
171  int o = opponetInDirection(ret[0], d);
172  if (s >= 0 && s < smin) smin = s;
173  if (o >= 0 && o < omin) omin = o;
174  }
175  // update path
176  Integer[] p = {
177  ret[0], dir, moveFlag, supplyFlag,
178  dirCounter[Direction.UP], dirCounter[Direction.RIGHT], dirCounter[Direction.DOWN], dirCounter[Direction.LEFT],
179  (smin != DirRange.End)? smin:Const.noSupply, (omin != DirRange.End)? omin:Const.noOpponent
180  };
181  path.add(p);
182  return ret;
183  }
184 
188  void statistics() {
189  if (!path.isEmpty()) {
190  Integer[] last = path.get(path.size()-1);
191  String who = String.format("%12s", name);
192  System.out.print(who + ": score[" + score + "]" + ", dice =" + last[1] + ", tileId =" + last[0] + " (" + Position.toRow(last[0]) + ", " + Position.toCol(last[0]) + ")");
193  if (last[2] == 0)
194  System.out.println(" *Can not move.");
195  else if (last[3] != 0)
196  System.out.println(" *Found a supply.");
197  else
198  System.out.println("");
199  // extra prints for heuristic
200  if (last[8] != Const.noSupply) System.out.println(" supply distance =" + last[8]);
201  else System.out.println(" supply distance = blind");
202  if (last[9] != Const.noOpponent) System.out.println(" opponent distance =" + last[9]);
203  else System.out.println(" opponent distance = blind");
204  }
205  }
206 
211  String who = String.format("%12s", name);
212  System.out.println();
213  System.out.println(who + ": score[" + score + "]");
214  System.out.println(" Moves up: " + dirCounter[Direction.UP]);
215  System.out.println(" Moves right: " + dirCounter[Direction.RIGHT]);
216  System.out.println(" Moves down: " + dirCounter[Direction.DOWN]);
217  System.out.println(" Moves left: " + dirCounter[Direction.LEFT]);
218  }
219 
235  private int directionOfMax (double[] eval, int[] eval_dir, int N) {
236  double M = Double.NEGATIVE_INFINITY;
237  int M_idx = 0;
238  for (int i =0; i < N ; ++i) {
239  if (eval[i] > M) {
240  M = eval[i];
241  M_idx = i;
242  }
243  }
244  return eval_dir[M_idx];
245  }
246 
253  private boolean isUnevaluated (double[] eval, int N) {
254  for (int i =0 ; i<N ; ++i)
255  if (eval[i] != 0 && eval[i] != Double.NEGATIVE_INFINITY)
256  return false;
257  return true;
258  }
259 
265 }
This class represents the game&#39;s player who cheats.
static final int RIGHT
East direction.
Definition: Common.java:68
int [][] getOpponentMoves(int playerId)
Boards utility to give access to other player moves.
Definition: Board.java:228
This class is the representation of the games&#39;s board.
Definition: Board.java:26
Class to hold constant values for entire application.
Definition: Common.java:21
Helper C++-like enumerator class to hold direction.
Definition: Common.java:66
boolean champion
Champion indicate a player who plays against the Minotaur.
Definition: Player.java:215
static final int End
Iterator style end of range direction (one place after the last)
Definition: Common.java:58
int x
The column coordinate of the player on the board.
Definition: Player.java:213
static final int Step
Step for iterator style direction.
Definition: Common.java:59
This class represents the game&#39;s player.
Definition: Player.java:21
Board board
Reference to the session&#39;s boards.
Definition: Player.java:211
int supplyInDirection(int currentPos, int direction)
Utility to get the distance of a possible supply in some direction.
int [] move(int id)
HeuristicPlayer&#39;s move.
void final_statistics()
Prints final statistics for the player.
static final double opponentFactor
Definition: Common.java:30
HeuristicPlayer(String name, boolean champion, Board board, int tileId)
Create a new player and put him at the row-column coordinates.
static final double supplyFactor
Definition: Common.java:31
Helper C++ like enumerator class for direction ranged loops.
Definition: Common.java:56
int getId()
Read access to id coordinate.
Definition: Common.java:143
static final int moveItems
The number of items return by move()
Definition: Common.java:27
static final int viewDistance
The max distance of the Heuristic player&#39;s ability to see.
Definition: Common.java:28
int opponetInDirection(int currentPos, int direction)
Utility to get the distance of a possible opponent in some direction.
int y
The row coordinate of the player on the board.
Definition: Player.java:214
double evaluate(int currentPos, int direction)
This is the main move evaluation function.
HeuristicPlayer(String name, boolean champion, Board board, int row, int column)
Create a new player and put him at the row-column coordinates.
static int toRow(int id)
Takes Id coordinate and return the corresponding row coordinate.
Definition: Common.java:163
int score
The current score of the player.
Definition: Player.java:212
static final int EOR
Number to indicate the End Of Range.
Definition: Common.java:26
static int toCol(int id)
Takes Id coordinate and return the corresponding column coordinate.
Definition: Common.java:171
An Application wide board position implementation holding just the id coordinate. ...
Definition: Common.java:102
void statistics()
Prints round information for the player.
int directionOfMax(double[] eval, int[] eval_dir, int N)
A small utility to extract the direction of maximum evaluation result.
static final int noSupply
Number to indicate the absent of supply.
Definition: Common.java:23
boolean isUnevaluated(double[] eval, int N)
A small utility to check if there is at least one evaluation result in the eval array.
Class to create ranges of numbers.
Definition: Common.java:185
boolean hasSupply(int tileId)
Utility function to check if there is a supply on the tile or not.
Definition: Board.java:188
boolean isWalkable(int tileId, int direction)
Predicate to check if a direction is Walkable.
Definition: Board.java:159
static final int LEFT
West direction.
Definition: Common.java:70
static final int UP
North direction.
Definition: Common.java:67
static int get(int fromId, int toId)
Definition: Common.java:79
static final int noOpponent
Number to indicate the absent of supply.
Definition: Common.java:24
void updateMove(int[] m, int playerId)
Utility to update the moves of each player.
Definition: Board.java:258
String name
The name of the player.
Definition: Player.java:210
static final int DOWN
South direction.
Definition: Common.java:69
static final int Begin
Iterator style begin of range direction (starting north)
Definition: Common.java:57
ArrayList< Integer[]> path
our history.
Definition: Player.java:217
int tryPickSupply(int tileId)
Try to pick supply from a tile.
Definition: Board.java:201
int playerId
The unique identifier of the player.
Definition: Player.java:209
Class to create shuffled ranges of numbers.
Definition: Common.java:240
int get()
Extract and return the first item from the range.
Definition: Common.java:218