All MoveGenerators default to 1 move lookahead.
Made MoveGenerators protected for unit testing. Added unit test for some analysis of MoveGenerator speeds. Fixed MDP to consider all states where #turns = maxTurns terminal.
This commit is contained in:
@@ -33,7 +33,11 @@ public class MDPFactory {
|
||||
public static ActionsFunction<GridCell<Double>, GridWorldAction> createActionsFunctionForTileGame(
|
||||
final GridWorld<Double> cw, int maxTiles, int maxScore) {
|
||||
final Set<GridCell<Double>> terminals = new HashSet<GridCell<Double>>();
|
||||
terminals.add(cw.getCellAt(maxTiles,maxScore));
|
||||
|
||||
for (int score = 1; score <= maxScore; score++) {
|
||||
terminals.add(cw.getCellAt(maxTiles,score));
|
||||
}
|
||||
//terminals.add(cw.getCellAt(maxTiles,maxScore));
|
||||
|
||||
ActionsFunction<GridCell<Double>, GridWorldAction> af = new ActionsFunction<GridCell<Double>, GridWorldAction>() {
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class AlphaBetaComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new AlphaBetaMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new AlphaBetaMoveGenerator();
|
||||
|
||||
@Override
|
||||
public void denyMove() {
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class MinimaxComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new MinimaxMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new MinimaxMoveGenerator();
|
||||
|
||||
public MinimaxComPlayer() {
|
||||
super();
|
||||
|
||||
@@ -8,7 +8,7 @@ import model.playerModel.GameGoal;
|
||||
import model.playerModel.PlayerModel;
|
||||
|
||||
public class MonteCarloComPlayer implements Player {
|
||||
private final MoveGenerator moveGenerator = new MonteCarloMoveGenerator();
|
||||
final MoveGenerator moveGenerator = new MonteCarloMoveGenerator();
|
||||
|
||||
@Override
|
||||
public void denyMove() {
|
||||
|
||||
@@ -10,7 +10,7 @@ import model.SearchResult;
|
||||
|
||||
public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||
|
||||
@@ -18,10 +18,10 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
public Move genMove(Board board, boolean asHuman) {
|
||||
|
||||
if (!asHuman) {
|
||||
return getMaxValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2,
|
||||
return getMaxValue(board, asHuman, lookahead * 2,
|
||||
Integer.MIN_VALUE, Integer.MAX_VALUE).move;
|
||||
} else {
|
||||
return getMinValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2,
|
||||
return getMinValue(board, asHuman, lookahead * 2,
|
||||
Integer.MIN_VALUE, Integer.MAX_VALUE).move;
|
||||
}
|
||||
}
|
||||
@@ -114,4 +114,9 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
|
||||
|
||||
return bestResult;
|
||||
}
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,8 @@ import model.Move;
|
||||
import model.SearchResult;
|
||||
|
||||
public class MinimaxMoveGenerator implements MoveGenerator {
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 2;
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
|
||||
@@ -20,12 +21,12 @@ public class MinimaxMoveGenerator implements MoveGenerator {
|
||||
//have different types of moves.
|
||||
SearchResult searchResult;
|
||||
if (!asHuman) {
|
||||
searchResult = getMaxValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
searchResult = getMaxValue(board, Move.NONE, asHuman, lookahead * 2);
|
||||
} else {
|
||||
searchResult = getMinValue(board, Move.NONE, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
searchResult = getMinValue(board, Move.NONE, asHuman, lookahead * 2);
|
||||
}
|
||||
|
||||
System.out.println(searchResult);
|
||||
//System.out.println(searchResult);
|
||||
return searchResult.move;
|
||||
}
|
||||
|
||||
@@ -94,4 +95,10 @@ public class MinimaxMoveGenerator implements MoveGenerator {
|
||||
Move[] doNothing = new Move[] { Move.NONE };
|
||||
return Arrays.asList(doNothing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import model.Move;
|
||||
import model.SearchResult;
|
||||
|
||||
public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 3;
|
||||
private static final int DEFAULT_RECURSIVE_PLAYS = 1;
|
||||
private int lookahead = DEFAULT_RECURSIVE_PLAYS;
|
||||
private static final int MOVES_PER_LEVEL = 12;
|
||||
|
||||
private final BoardScorer scorer = new BoardScorer();
|
||||
@@ -18,7 +19,7 @@ public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
@Override
|
||||
public Move genMove(Board board, boolean asHuman) {
|
||||
|
||||
SearchResult bestResult = genMove(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2);
|
||||
SearchResult bestResult = genMove(board, asHuman, lookahead * 2);
|
||||
|
||||
return bestResult.move;
|
||||
}
|
||||
@@ -74,4 +75,10 @@ public class MonteCarloMoveGenerator implements MoveGenerator {
|
||||
Move[] doNothing = new Move[] { Move.NONE };
|
||||
return Arrays.asList(doNothing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
this.lookahead = lookahead;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -10,4 +10,5 @@ public interface MoveGenerator {
|
||||
|
||||
public Move genMove(Board board, boolean asHuman);
|
||||
public List<Move> genMoves(Board board, boolean asHuman, int nMoves);
|
||||
public boolean setLookahead(int lookahead);
|
||||
}
|
||||
@@ -94,5 +94,8 @@ public class NeuralNetworkMoveGenerator implements MoveGenerator {
|
||||
// Do nothing.
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,9 @@ public class ValidMoveGenerator implements MoveGenerator {
|
||||
return validMoves.subList(0, Math.min(validMoves.size(), nMoves));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setLookahead(int lookahead) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
114
test/model/comPlayer/SpeedTest.java
Normal file
114
test/model/comPlayer/SpeedTest.java
Normal file
@@ -0,0 +1,114 @@
|
||||
package model.comPlayer;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import model.Board;
|
||||
import model.Board.TileColor;
|
||||
import model.playerModel.PlayerModel;
|
||||
import model.CellPointer;
|
||||
|
||||
public class SpeedTest {
|
||||
private static final Board board = new Board();
|
||||
private static final int nTestRounds = 10;
|
||||
private static final int lookahead = 3;
|
||||
|
||||
static {
|
||||
board.playTile(new CellPointer(2,2), TileColor.BLUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRandom() {
|
||||
long testTime = 0L;
|
||||
|
||||
RandomComPlayer player = new RandomComPlayer();
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for RandomMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMonteCarlo() {
|
||||
long testTime = 0L;
|
||||
|
||||
MonteCarloComPlayer player = new MonteCarloComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for MonteCarloGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Ignore
|
||||
public void testMinimax() {
|
||||
long testTime = 0L;
|
||||
|
||||
MinimaxComPlayer player = new MinimaxComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for MinimaxMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAlphaBeta() {
|
||||
long testTime = 0L;
|
||||
|
||||
AlphaBetaComPlayer player = new AlphaBetaComPlayer();
|
||||
player.moveGenerator.setLookahead(lookahead);
|
||||
|
||||
PlayerModel model = new PlayerModel("test");
|
||||
|
||||
for (int testRound = 0; testRound < nTestRounds; testRound++) {
|
||||
Board newBoard = new Board(board);
|
||||
|
||||
long testStart = System.currentTimeMillis();
|
||||
player.getMove(newBoard, model);
|
||||
long testEnd = System.currentTimeMillis();
|
||||
|
||||
testTime += testEnd - testStart;
|
||||
}
|
||||
|
||||
double avgTime = testTime / (nTestRounds * 1000.0);
|
||||
|
||||
System.out.println("Average time for AlphaBetaMoveGenerator.genMove() over " + nTestRounds + " tests: " + avgTime);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user