- Reorganized packages so that the computer agents are inside the model package.

- Added support for the player model inside Referee.java; high scores should now persist over a single execution of the program.
- Refactored PlayerModel.java to support game logging. All games are now logged so that we can track overall progress.
- Added scaffolding to allow saving and importing of PlayerModel.java. It is not yet functional, but it will be with two function implementations and then the appropriate calls.
This commit is contained in:
Marshall
2012-04-28 19:18:28 -04:00
parent 1a4c6d865b
commit a6af6df132
18 changed files with 123 additions and 52 deletions

View File

@@ -0,0 +1,126 @@
package model.comPlayer.generator;
import java.util.Arrays;
import java.util.List;
import model.Board;
import model.BoardScorer;
import model.Move;
import model.SearchResult;
import org.apache.log4j.Logger;
public class AlphaBetaMoveGenerator implements MoveGenerator {
private static final Logger LOGGER = Logger
.getLogger(AlphaBetaMoveGenerator.class.getName());
private static final int DEFAULT_RECURSIVE_PLAYS = 2;
private final BoardScorer scorer = new BoardScorer();
private final ValidMoveGenerator validMoveGenerator = new ValidMoveGenerator();
@Override
public Move genMove(Board board, boolean asHuman) {
if (!asHuman) {
return getMaxValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, Integer.MIN_VALUE,
Integer.MAX_VALUE).move;
} else {
return getMinValue(board, asHuman, DEFAULT_RECURSIVE_PLAYS * 2, Integer.MIN_VALUE,
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) {
if (recursionLevel < 1) {
return new SearchResult(Move.NONE,scorer.getScore(board));
}
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
MoveGenerator.ALL_MOVES);
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MIN_VALUE);
for (Move nextMove : validMoves) {
Board nextBoard = new Board(board);
if (!nextBoard.playTile(nextMove.getCell(), nextMove.getColor())) {
throw new RuntimeException(
"Illegal move attempted during search!");
}
SearchResult searchResult = new SearchResult(nextMove,getMinValue(nextBoard, !asHuman, recursionLevel - 1,
alpha, beta).score);
bestResult = getMax(bestResult,searchResult);
if (bestResult.score >= beta) {
return bestResult;
}
alpha = Math.max(alpha, bestResult.score);
}
return bestResult;
}
private SearchResult getMinValue(Board board, boolean asHuman, int recursionLevel,
int alpha, int beta) {
if (recursionLevel < 1) {
return new SearchResult(Move.NONE,scorer.getScore(board));
}
List<Move> validMoves = validMoveGenerator.genMoves(board, asHuman,
MoveGenerator.ALL_MOVES);
SearchResult bestResult = new SearchResult(Move.NONE,Integer.MAX_VALUE);
for (Move nextMove : validMoves) {
Board nextBoard = new Board(board);
if (!nextBoard.playTile(nextMove.getCell(), nextMove.getColor())) {
throw new RuntimeException(
"Illegal move attempted during search!");
}
SearchResult searchResult = new SearchResult(nextMove,getMaxValue(nextBoard, !asHuman, recursionLevel - 1,
alpha, beta).score);
bestResult = getMin(bestResult,searchResult);
if (bestResult.score <= alpha) {
return bestResult;
}
beta = Math.min(beta, bestResult.score);
}
return bestResult;
}
/**
* AlphaBetaMoveGenerator2 does not support this method.
*/
@Override
public List<Move> genMoves(Board board, boolean asHuman, int nMoves) {
Move[] doNothing = new Move[] { Move.NONE };
LOGGER.info("Minimax genMoves() stub returning []");
return Arrays.asList(doNothing);
}
}