Files
cs8803p4/src/model/comPlayer/generator/AlphaBetaMoveGenerator.java
Woody Folsom 744ceb02f7 Fixed index out of bounds.
Implemented CellPointer equals, hashcode.
2012-04-29 13:40:27 -04:00

134 lines
3.4 KiB
Java

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);
if (validMoves.size() == 0) {
return bestResult;
}
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);
if (validMoves.size() == 0) {
return bestResult;
}
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);
}
}