Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b583d63095 | ||
|
|
da8ad7259a | ||
|
|
ee3dfb7cea |
@@ -1,6 +1,5 @@
|
|||||||
*bin/*
|
*bin/*
|
||||||
*doc/*
|
*doc/*
|
||||||
*report/*
|
|
||||||
*deliverable/*
|
*deliverable/*
|
||||||
*.project
|
*.project
|
||||||
*.classpath
|
*.classpath
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
@@ -269,13 +269,13 @@ public class Game {
|
|||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// Current project requirements
|
// Current project requirements
|
||||||
int lines = 6; //20;
|
int lines = 20;
|
||||||
int columns = 6; //10;
|
int columns = 10;
|
||||||
int numOfSnakes = 1; //3;
|
int numOfSnakes = 3;
|
||||||
int numOfLadders = 1; //3;
|
int numOfLadders = 3;
|
||||||
int numOfApples = 2; //6;
|
int numOfApples = 6;
|
||||||
int numOfPlayers = 2;
|
int numOfPlayers = 2;
|
||||||
boolean verbose = true;
|
boolean verbose = false;
|
||||||
|
|
||||||
// Print caption
|
// Print caption
|
||||||
System.out.println("================== Snake Game ==================");
|
System.out.println("================== Snake Game ==================");
|
||||||
|
|||||||
@@ -15,23 +15,13 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class HeuristicPlayer
|
public class HeuristicPlayer
|
||||||
extends Player {
|
extends Player {
|
||||||
// evaluate configuration
|
|
||||||
static final double FACTOR_TILE = 0.15;
|
|
||||||
static final double FACTOR_FWD_STEP = 0.55;
|
|
||||||
static final double FACTOR_BACK_STEP = -1.0;
|
|
||||||
static final double FACTOR_UP_POINTS = 0.3;
|
|
||||||
static final double FACTOR_DWN_POINTS= -1.0;
|
|
||||||
static final double FACTOR_INIT_EVAL = 1.0;
|
|
||||||
static final double FACTOR_ROUND = -1.0;
|
|
||||||
static final double FACTOR_GAME = 10.0;
|
|
||||||
|
|
||||||
/** @name Constructors */
|
/** @name Constructors */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/** Default doing nothing constructor */
|
/** Default doing nothing constructor */
|
||||||
public HeuristicPlayer() {
|
public HeuristicPlayer() {
|
||||||
super ();
|
super ();
|
||||||
path = new ArrayList<Integer[]>();
|
path = new ArrayList<Integer[]>();
|
||||||
evalData = new EvalData[board.getN() * board.getM() +1];
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief The main constructor
|
* @brief The main constructor
|
||||||
@@ -43,8 +33,7 @@ public class HeuristicPlayer
|
|||||||
*/
|
*/
|
||||||
HeuristicPlayer (int playerId, String name, Board board) {
|
HeuristicPlayer (int playerId, String name, Board board) {
|
||||||
super (playerId, name, board);
|
super (playerId, name, board);
|
||||||
path = new ArrayList<Integer[]>();
|
path = new ArrayList<Integer[]>();
|
||||||
evalData = new EvalData[board.getN() * board.getM() +1];
|
|
||||||
}
|
}
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
@@ -73,10 +62,19 @@ public class HeuristicPlayer
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
int getNextMove (int tile) {
|
int getNextMove (int tile) {
|
||||||
|
Map<Integer, Double> moves = new HashMap<Integer, Double>();
|
||||||
|
double max = Double.NEGATIVE_INFINITY;
|
||||||
|
double ev = Double.NEGATIVE_INFINITY;
|
||||||
int roll = 0;
|
int roll = 0;
|
||||||
|
|
||||||
// Evaluate each possible dice result and find the better one
|
// Evaluate each possible dice result and find the better one
|
||||||
roll = evalProcess(tile);
|
for (int r=1 ; r<=6 ; ++r) {
|
||||||
|
moves.put (new Integer(r), evaluate (tile, r));
|
||||||
|
if ((ev = moves.get(r)) > max) {
|
||||||
|
max = ev;
|
||||||
|
roll = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Do the move and get the move data
|
// Do the move and get the move data
|
||||||
Integer[] move_data = Arrays.stream(move (tile, roll, true))
|
Integer[] move_data = Arrays.stream(move (tile, roll, true))
|
||||||
.boxed()
|
.boxed()
|
||||||
@@ -121,51 +119,6 @@ public class HeuristicPlayer
|
|||||||
super.statistics(verbose, sum);
|
super.statistics(verbose, sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
int evalProcess (int tile) {
|
|
||||||
int[] check = new int[MOVE_DATA_SIZE];
|
|
||||||
int begin;
|
|
||||||
int end = board.getN() * board.getM();
|
|
||||||
int roll;
|
|
||||||
EvalData e = new EvalData();
|
|
||||||
|
|
||||||
for (int i =0 ; i<=end ; ++i) {
|
|
||||||
evalData[i] = new EvalData();
|
|
||||||
evalData[i].evaluation = Double.NEGATIVE_INFINITY;
|
|
||||||
}
|
|
||||||
for (begin =tile ; begin < end ; ++begin) {
|
|
||||||
if ((board.checkLadder(begin, false) != begin) ||
|
|
||||||
(board.checkSnake(begin) != begin))
|
|
||||||
continue;
|
|
||||||
int initRound = evalData[begin].round;
|
|
||||||
double initEval = evalData[begin].evaluation;
|
|
||||||
for (roll = 1 ; roll <= 6 ; ++roll) {
|
|
||||||
check = move (begin, roll, false);
|
|
||||||
e.game = _saturate (check);
|
|
||||||
e.round = initRound +1;
|
|
||||||
e.from = begin;
|
|
||||||
e.roll = roll;
|
|
||||||
e.steps = check[MOVE_STEPS_IDX];
|
|
||||||
e.points = check[MOVE_POINTS_IDX];
|
|
||||||
e.evaluation = _evalFormula (check[MOVE_TILE_IDX], e.steps, e.points, e.round, initEval, e.game);
|
|
||||||
if (e.evaluation > evalData[check[MOVE_TILE_IDX]].evaluation) {
|
|
||||||
evalData[check[MOVE_TILE_IDX]].copy(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// find route back of the optimal path
|
|
||||||
e = evalData[board.getN() * board.getM()];
|
|
||||||
EvalData last = e;
|
|
||||||
while (e.from != tile) {
|
|
||||||
last = e;
|
|
||||||
e = evalData[e.from];
|
|
||||||
}
|
|
||||||
|
|
||||||
return last.roll; // return the first choice
|
|
||||||
}
|
|
||||||
|
|
||||||
double evaluate (int tile, int roll) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main evaluation function
|
* The main evaluation function
|
||||||
@@ -173,53 +126,15 @@ public class HeuristicPlayer
|
|||||||
* @param roll the roll to check
|
* @param roll the roll to check
|
||||||
* @return The evaluation of the roll
|
* @return The evaluation of the roll
|
||||||
*/
|
*/
|
||||||
private double _evalFormula (int tile, int steps, int points, int round, double initEval, boolean game) {
|
private double evaluate (int tile, int roll) {
|
||||||
initEval = (initEval == Double.NEGATIVE_INFINITY) ? 0 : initEval;
|
int[] check = new int[MOVE_DATA_SIZE];
|
||||||
return tile * FACTOR_TILE +
|
check = move(tile, roll, false);
|
||||||
steps * ((steps>0) ? FACTOR_FWD_STEP : FACTOR_BACK_STEP) +
|
|
||||||
points * ((points>0) ? FACTOR_UP_POINTS : FACTOR_DWN_POINTS) +
|
|
||||||
initEval * FACTOR_INIT_EVAL +
|
|
||||||
round * FACTOR_ROUND +
|
|
||||||
((game) ? 1:0) * FACTOR_GAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean _saturate (int[] check) {
|
return 0.65*check[MOVE_STEPS_IDX] + 0.35*check[MOVE_POINTS_IDX];
|
||||||
// make adjustments if game is finished
|
|
||||||
int tiles = board.getM() * board.getN();
|
|
||||||
boolean game = (check[MOVE_TILE_IDX] >= tiles) ? true : false;
|
|
||||||
|
|
||||||
if (check[MOVE_TILE_IDX]> tiles) {
|
|
||||||
check[MOVE_STEPS_IDX] -= check[MOVE_TILE_IDX] - tiles;
|
|
||||||
check[MOVE_TILE_IDX] = tiles;
|
|
||||||
}
|
|
||||||
return game;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @name Data members package access only */
|
/** @name Data members package access only */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
private ArrayList<Integer[]> path; /**< Players history as required */
|
private ArrayList<Integer[]> path; /**< Players history as required */
|
||||||
private EvalData[] evalData;
|
|
||||||
/** @} */
|
/** @} */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class EvalData {
|
|
||||||
int round;
|
|
||||||
int from;
|
|
||||||
int roll;
|
|
||||||
int steps;
|
|
||||||
int points;
|
|
||||||
boolean game;
|
|
||||||
double evaluation;
|
|
||||||
EvalData () { }
|
|
||||||
|
|
||||||
void copy (EvalData e) {
|
|
||||||
round = e.round;
|
|
||||||
from = e.from;
|
|
||||||
roll = e.roll;
|
|
||||||
steps = e.steps;
|
|
||||||
points = e.points;
|
|
||||||
game = e.game;
|
|
||||||
evaluation = e.evaluation;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -82,10 +82,18 @@ public class Player {
|
|||||||
this.tile = tile;
|
this.tile = tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get lastMove */
|
||||||
int[] getLastMove () { return lastMove; }
|
int[] getLastMove () { return lastMove; }
|
||||||
|
/** Set lastMove */
|
||||||
void setLastMove (int[] lastMove) {
|
void setLastMove (int[] lastMove) {
|
||||||
this.lastMove = lastMove;
|
this.lastMove = lastMove;
|
||||||
}
|
}
|
||||||
|
/** Get dryMove */
|
||||||
|
int[] getDryMove () { return dryMove; }
|
||||||
|
/** Set dryMove */
|
||||||
|
void setDryMove (int[] dryMove) {
|
||||||
|
this.dryMove = dryMove;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @name Exposed API members */
|
/** @name Exposed API members */
|
||||||
|
|||||||
Reference in New Issue
Block a user