Browse Source

A dynamic programming test

dynamic
Christos Houtouridis 5 years ago
parent
commit
43c591bf4a
2 changed files with 109 additions and 24 deletions
  1. +6
    -6
      src/net/hoo2/auth/dsproject/snake/Game.java
  2. +103
    -18
      src/net/hoo2/auth/dsproject/snake/HeuristicPlayer.java

+ 6
- 6
src/net/hoo2/auth/dsproject/snake/Game.java View File

@@ -269,13 +269,13 @@ public class Game {
*/
public static void main(String[] args) {
// Current project requirements
int lines = 20;
int columns = 10;
int numOfSnakes = 3;
int numOfLadders = 3;
int numOfApples = 6;
int lines = 6; //20;
int columns = 6; //10;
int numOfSnakes = 1; //3;
int numOfLadders = 1; //3;
int numOfApples = 2; //6;
int numOfPlayers = 2;
boolean verbose = false;
boolean verbose = true;
// Print caption
System.out.println("================== Snake Game ==================");


+ 103
- 18
src/net/hoo2/auth/dsproject/snake/HeuristicPlayer.java View File

@@ -15,13 +15,23 @@ import java.util.*;
*/
public class HeuristicPlayer
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 */
/** @{ */
/** Default doing nothing constructor */
public HeuristicPlayer() {
super ();
path = new ArrayList<Integer[]>();
path = new ArrayList<Integer[]>();
evalData = new EvalData[board.getN() * board.getM() +1];
}
/**
* @brief The main constructor
@@ -33,7 +43,8 @@ public class HeuristicPlayer
*/
HeuristicPlayer (int playerId, String name, Board board) {
super (playerId, name, board);
path = new ArrayList<Integer[]>();
path = new ArrayList<Integer[]>();
evalData = new EvalData[board.getN() * board.getM() +1];
}
/* @} */
@@ -62,19 +73,10 @@ public class HeuristicPlayer
*/
@Override
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;
// Evaluate each possible dice result and find the better one
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;
}
}
roll = evalProcess(tile);
// Do the move and get the move data
Integer[] move_data = Arrays.stream(move (tile, roll, true))
.boxed()
@@ -119,22 +121,105 @@ public class HeuristicPlayer
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
* @param tile The current tile of the player
* @param roll the roll to check
* @return The evaluation of the roll
*/
private double evaluate (int tile, int roll) {
int[] check = new int[MOVE_DATA_SIZE];
check = move(tile, roll, false);
return 0.65*check[MOVE_STEPS_IDX] + 0.35*check[MOVE_POINTS_IDX];
private double _evalFormula (int tile, int steps, int points, int round, double initEval, boolean game) {
initEval = (initEval == Double.NEGATIVE_INFINITY) ? 0 : initEval;
return tile * FACTOR_TILE +
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) {
// 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 */
/** @{ */
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;
}
}

Loading…
Cancel
Save