From 21e5d894475b726b3f63410fbde6c2fc996ab88d Mon Sep 17 00:00:00 2001 From: Woody Folsom Date: Sun, 29 Apr 2012 14:59:25 -0400 Subject: [PATCH] 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. --- src/model/SearchResult.java | 11 +++-- src/model/comPlayer/MonteCarloComPlayer.java | 42 +++---------------- .../generator/AlphaBetaMoveGenerator.java | 24 +++-------- .../generator/ValidMoveGenerator.java | 7 +++- src/view/ParsedArgs.java | 4 ++ 5 files changed, 29 insertions(+), 59 deletions(-) diff --git a/src/model/SearchResult.java b/src/model/SearchResult.java index 57fbd82..c749469 100644 --- a/src/model/SearchResult.java +++ b/src/model/SearchResult.java @@ -1,16 +1,21 @@ package model; -public class SearchResult { +public class SearchResult implements Comparable { public final Move move; public final int score; - + public SearchResult(Move move, int score) { this.move = move; this.score = score; } - + @Override public String toString() { return move + ", score: " + score; } + + @Override + public int compareTo(SearchResult o) { + return Integer.compare(score, o.score); + } } diff --git a/src/model/comPlayer/MonteCarloComPlayer.java b/src/model/comPlayer/MonteCarloComPlayer.java index 013f150..44f310b 100644 --- a/src/model/comPlayer/MonteCarloComPlayer.java +++ b/src/model/comPlayer/MonteCarloComPlayer.java @@ -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 @@ -59,4 +27,4 @@ public class MonteCarloComPlayer implements Player { public String toString() { return "Monte Carlo ComPlayer"; } -} +} \ No newline at end of file diff --git a/src/model/comPlayer/generator/AlphaBetaMoveGenerator.java b/src/model/comPlayer/generator/AlphaBetaMoveGenerator.java index 9774317..1eb36db 100644 --- a/src/model/comPlayer/generator/AlphaBetaMoveGenerator.java +++ b/src/model/comPlayer/generator/AlphaBetaMoveGenerator.java @@ -29,22 +29,6 @@ public class AlphaBetaMoveGenerator implements MoveGenerator { Integer.MAX_VALUE).move; } } - - 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) { @@ -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; diff --git a/src/model/comPlayer/generator/ValidMoveGenerator.java b/src/model/comPlayer/generator/ValidMoveGenerator.java index eb97649..c9a7da2 100644 --- a/src/model/comPlayer/generator/ValidMoveGenerator.java +++ b/src/model/comPlayer/generator/ValidMoveGenerator.java @@ -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)); + } } } diff --git a/src/view/ParsedArgs.java b/src/view/ParsedArgs.java index ead0c9b..17c547d 100644 --- a/src/view/ParsedArgs.java +++ b/src/view/ParsedArgs.java @@ -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();