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) throws Exception {
33  super(name, champion, board, row, column);
34  }
35 
43  public HeuristicPlayer(String name, boolean champion, Board board, int tileId) throws Exception {
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(pos.getRow(), pos.getCol(), 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 [] opp = board.getOpponentMove(playerId);
77 
78  for (int i=0 ; board.isWalkable(pos.getId(), direction) && i<Const.viewDistance ; ++i) {
79  pos = new Position(pos.getRow(), pos.getCol(), direction);
80  if (opp[MOVE_TILE_ID] == pos.getId())
81  return i+1;
82  }
83  return Const.noOpponent;
84  }
85 
92  double evaluate (int currentPos, int direction) {
93  int opDist = opponetInDirection (currentPos, direction);
94  int supDist = supplyInDirection(currentPos, direction);
95 
96  // saturate
97  opDist = (opDist == Const.noOpponent) ? 0: opDist;
98  supDist = (supDist == Const.noSupply) ? 0 : supDist;
99  return ((supDist != 0)? (1.0/supDist * Const.supplyFactor) : 0)
100  - ((opDist != 0) ? (1.0/opDist * Const.opponentFactor) : 0);
101  }
102 
111  int[] getNextMove(int currentPos) {
113  int N = dirs.size();
114  double[] eval = new double[N];
115  int [] eval_dir = new int[N];
116 
117  for (int i =0, dir = dirs.get() ; dir != Const.EOR ; dir = dirs.get(), ++i) {
118  if (board.isWalkable(currentPos, dir))
119  eval[i] = evaluate(currentPos, dir);
120  else
121  eval[i] = Double.NEGATIVE_INFINITY;
122  eval_dir[i] = dir;
123  }
124  int dir;
125  if (isUnevaluated(eval, N)) {
127  do
128  dir = r.get();
129  while (!board.isWalkable(currentPos, dir));
130  }
131  else {
132  dir = directionOfMax (eval, eval_dir, N);
133  }
134  Position new_pos = new Position( Position.toRow(currentPos), Position.toCol(currentPos), dir );
135  int [] ret = {new_pos.getId(), new_pos.getRow(), new_pos.getCol(), dir};
136  return ret;
137  }
138 
156  @Override
157  int[] move(int id) {
158  // Initialize return array with the current data
159  int[] ret = getNextMove(id);
160  y = Position.toRow(ret[MOVE_TILE_ID]);
161  x = Position.toCol(ret[MOVE_TILE_ID]);
162 
163  int supplyFlag =0, moveFlag =1;
164  // In case of a champion player, try also to pick a supply
165  if (champion && (board.tryPickSupply(ret[MOVE_TILE_ID]) != Const.noSupply)) {
166  ++score; // keep score
167  ++supplyFlag;
168  }
169  ++dirCounter[ret[MOVE_DICE]]; // update direction counters
170  board.updateMove(ret, playerId);
171 
172  // Update supply and opponent distance
173  int smin =DirRange.End, omin =DirRange.End;
174  for (int d = DirRange.Begin ; d<DirRange.End ; d += DirRange.Step) {
175  int s = supplyInDirection (ret[MOVE_TILE_ID], d);
176  int o = opponetInDirection(ret[MOVE_TILE_ID], d);
177  if (s >= 0 && s < smin) smin = s;
178  if (o >= 0 && o < omin) omin = o;
179  }
180  // update path
181  Integer[] p = {
182  ret[MOVE_TILE_ID], ret[MOVE_DICE], moveFlag, supplyFlag,
183  dirCounter[Direction.UP], dirCounter[Direction.RIGHT], dirCounter[Direction.DOWN], dirCounter[Direction.LEFT],
184  (smin != DirRange.End)? smin:Const.noSupply, (omin != DirRange.End)? omin:Const.noOpponent
185  };
186  path.add(p);
187  return ret;
188  }
189 
193  void statistics() {
194  if (!path.isEmpty()) {
195  Integer[] last = path.get(path.size()-1);
196  String who = String.format("%12s", name);
197  System.out.print(who + ": score[" + score + "]" + ", dice =" + last[1] + ", tileId =" + last[0] + " (" + Position.toRow(last[0]) + ", " + Position.toCol(last[0]) + ")");
198  if (last[2] == 0)
199  System.out.println(" *Can not move.");
200  else if (last[3] != 0)
201  System.out.println(" *Found a supply.");
202  else
203  System.out.println("");
204  // extra prints for heuristic
205  if (last[8] != Const.noSupply) System.out.println(" supply =" + last[8]);
206  else System.out.println(" supply = blind");
207  if (last[9] != Const.noOpponent) System.out.println(" opponent =" + last[9]);
208  else System.out.println(" opponent = blind");
209  }
210  }
211 
216  String who = String.format("%12s", name);
217  System.out.println();
218  System.out.println(who + ": score[" + score + "]");
219  System.out.println(" Moves up: " + dirCounter[Direction.UP]);
220  System.out.println(" Moves right: " + dirCounter[Direction.RIGHT]);
221  System.out.println(" Moves down: " + dirCounter[Direction.DOWN]);
222  System.out.println(" Moves left: " + dirCounter[Direction.LEFT]);
223  }
224 
240  private int directionOfMax (double[] eval, int[] eval_dir, int N) {
241  double M = Double.NEGATIVE_INFINITY;
242  int M_idx = 0;
243  for (int i =0; i < N ; ++i) {
244  if (eval[i] > M) {
245  M = eval[i];
246  M_idx = i;
247  }
248  }
249  return eval_dir[M_idx];
250  }
251 
258  private boolean isUnevaluated (double[] eval, int N) {
259  for (int i =0 ; i<N ; ++i)
260  if (eval[i] != 0 && eval[i] != Double.NEGATIVE_INFINITY)
261  return false;
262  return true;
263  }
264 
270 }
This class represents the game&#39;s player who cheats.
static final int RIGHT
East direction.
Definition: Common.java:75
static final int MOVE_DICE
The index of dice information.
Definition: Player.java:27
This class is the representation of the games&#39;s board.
Definition: Board.java:25
Class to hold constant values for entire application.
Definition: Common.java:21
Helper C++-like enumerator class to hold direction.
Definition: Common.java:73
boolean champion
Champion indicate a player who plays against the Minotaur.
Definition: Player.java:224
static final int End
Iterator style end of range direction (one place after the last)
Definition: Common.java:65
int x
The column coordinate of the player on the board.
Definition: Player.java:222
static final int Step
Step for iterator style direction.
Definition: Common.java:66
static final int MOVE_TILE_ID
Index of the tileId information of the move.
Definition: Player.java:24
This class represents the game&#39;s player.
Definition: Player.java:21
Board board
Reference to the session&#39;s boards.
Definition: Player.java:220
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
Parameters to control move evaluation.
Definition: Common.java:33
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
supply distance factor
Definition: Common.java:34
Helper C++ like enumerator class for direction ranged loops.
Definition: Common.java:63
int getId()
Read access to id coordinate.
Definition: Common.java:154
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 getRow()
Read access to virtual row coordinate.
Definition: Common.java:152
int y
The row coordinate of the player on the board.
Definition: Player.java:223
int getCol()
Read access to virtual column coordinate.
Definition: Common.java:153
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:174
int score
The current score of the player.
Definition: Player.java:221
static final int EOR
Number to indicate the End Of Range.
Definition: Common.java:27
static int toCol(int id)
Takes Id coordinate and return the corresponding column coordinate.
Definition: Common.java:182
An Application wide board position implementation holding just the id coordinate. ...
Definition: Common.java:112
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:24
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:196
boolean hasSupply(int tileId)
Utility function to check if there is a supply on the tile or not.
Definition: Board.java:200
boolean isWalkable(int tileId, int direction)
Predicate to check if a direction is Walkable.
Definition: Board.java:171
static final int LEFT
West direction.
Definition: Common.java:77
static final int UP
North direction.
Definition: Common.java:74
static final int noOpponent
Number to indicate the absent of supply.
Definition: Common.java:25
void updateMove(int[] m, int playerId)
Utility to update the moves of each player.
Definition: Board.java:275
String name
The name of the player.
Definition: Player.java:219
static final int DOWN
South direction.
Definition: Common.java:76
int [] getNextMove(int currentPos)
Selects the best possible move to return.
static final int Begin
Iterator style begin of range direction (starting north)
Definition: Common.java:64
ArrayList< Integer[]> path
our history.
Definition: Player.java:226
int [] getOpponentMove(int playerId)
Boards utility to give access to other player moves.
Definition: Board.java:261
int tryPickSupply(int tileId)
Try to pick supply from a tile.
Definition: Board.java:213
int playerId
The unique identifier of the player.
Definition: Player.java:218
Class to create shuffled ranges of numbers.
Definition: Common.java:251
int get()
Extract and return the first item from the range.
Definition: Common.java:229