Implemented naive Monte Carlo move generator (simulates 10 random moves for 3 turns by each player).

Consequently, it performs strictly worse than Alpha-Beta, but usually avoids setting players up for an easy capture,
unlike Alpha-Beta.
This commit is contained in:
Woody Folsom
2012-04-29 14:59:25 -04:00
parent 744ceb02f7
commit 21e5d89447
5 changed files with 29 additions and 59 deletions

View File

@@ -1,6 +1,6 @@
package model;
public class SearchResult {
public class SearchResult implements Comparable<SearchResult> {
public final Move move;
public final int score;
@@ -13,4 +13,9 @@ public class SearchResult {
public String toString() {
return move + ", score: " + score;
}
@Override
public int compareTo(SearchResult o) {
return Integer.compare(score, o.score);
}
}

View File

@@ -1,48 +1,16 @@
package model.comPlayer;
import java.util.Random;
import model.Board;
import model.CellPointer;
import model.Move;
import model.Board.TileColor;
import model.comPlayer.generator.MonteCarloMoveGenerator;
import model.comPlayer.generator.MoveGenerator;
public class MonteCarloComPlayer implements Player {
private final Random rand = new Random();
private MoveGenerator moveGenerator = new MonteCarloMoveGenerator();
@Override
public Move getMove(Board board) {
return getRandomMove(board,true);
}
public Move getRandomMove(Board board, boolean isCompTurn) {
TileColor tile = TileColor.BLUE;
int r = -1;
int c = -1;
while (tile != TileColor.NONE) {
r = rand.nextInt(Board.NUM_ROWS);
c = rand.nextInt(Board.NUM_COLS);
tile = board.getTile(r, c);
}
switch (rand.nextInt(4)) {
case 0:
tile = TileColor.BLUE;
break;
case 1:
tile = TileColor.GREEN;
break;
case 2:
tile = TileColor.RED;
break;
case 3:
tile = TileColor.YELLOW;
}
return new Move(new CellPointer(r, c), tile);
return moveGenerator.genMove(board, false);
}
@Override

View File

@@ -30,22 +30,6 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
}
}
private SearchResult getMax(SearchResult sr1, SearchResult sr2) {
if (sr1.score >= sr2.score) {
return sr1;
} else {
return sr2;
}
}
private SearchResult getMin(SearchResult sr1, SearchResult sr2) {
if (sr1.score <= sr2.score) {
return sr1;
} else {
return sr2;
}
}
private SearchResult getMaxValue(Board board, boolean asHuman, int recursionLevel,
int alpha, int beta) {
if (recursionLevel < 1) {
@@ -72,7 +56,9 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
SearchResult searchResult = new SearchResult(nextMove,getMinValue(nextBoard, !asHuman, recursionLevel - 1,
alpha, beta).score);
bestResult = getMax(bestResult,searchResult);
if (searchResult.compareTo(bestResult) > 0) {
bestResult = searchResult;
}
if (bestResult.score >= beta) {
return bestResult;
@@ -110,7 +96,9 @@ public class AlphaBetaMoveGenerator implements MoveGenerator {
SearchResult searchResult = new SearchResult(nextMove,getMaxValue(nextBoard, !asHuman, recursionLevel - 1,
alpha, beta).score);
bestResult = getMin(bestResult,searchResult);
if (searchResult.compareTo(bestResult) < 0) {
bestResult = searchResult;
}
if (bestResult.score <= alpha) {
return bestResult;

View File

@@ -39,6 +39,11 @@ public class ValidMoveGenerator implements MoveGenerator {
}
Collections.shuffle(validMoves);
return validMoves;
if (nMoves == MoveGenerator.ALL_MOVES) {
return validMoves;
} else {
return validMoves.subList(0, Math.min(validMoves.size(),nMoves));
}
}
}

View File

@@ -2,6 +2,7 @@ package view;
import model.comPlayer.AlphaBetaComPlayer;
import model.comPlayer.MinimaxComPlayer;
import model.comPlayer.MonteCarloComPlayer;
import model.comPlayer.Player;
import model.comPlayer.RandomComPlayer;
@@ -9,6 +10,7 @@ public class ParsedArgs {
public static final String COM_RANDOM = "RANDOM";
public static final String COM_MINIMAX = "MINIMAX";
public static final String COM_ALPHABETA = "ALPHABETA";
public static final String COM_MONTECARLO = "MONTECARLO";
public static final String COM_DEFAULT = COM_ALPHABETA;
private String comPlayer = COM_DEFAULT;
@@ -20,6 +22,8 @@ public class ParsedArgs {
return new MinimaxComPlayer();
} else if (COM_ALPHABETA.equalsIgnoreCase(comPlayer)) {
return new AlphaBetaComPlayer();
} else if (COM_MONTECARLO.equalsIgnoreCase(comPlayer)) {
return new MonteCarloComPlayer();
} else {
System.out.println("Unrecognized comPlayer '" + comPlayer +"', using default: " + COM_DEFAULT);
return new AlphaBetaComPlayer();