- 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:
126
src/model/comPlayer/generator/AlphaBetaMoveGenerator.java
Normal file
126
src/model/comPlayer/generator/AlphaBetaMoveGenerator.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user