
com.fathzer.chess.utils.evaluators.quiesce.AbstractBasicQuiesceEvaluator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chess-utils Show documentation
Show all versions of chess-utils Show documentation
Some helpful piece of code to implement chess engines.
The newest version!
package com.fathzer.chess.utils.evaluators.quiesce;
import java.util.List;
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.MoveGenerator.MoveConfidence;
import com.fathzer.games.ai.SearchContext;
import com.fathzer.games.ai.SearchStatistics;
import com.fathzer.games.ai.evaluation.QuiesceEvaluator;
/** A basic quiescence search evaluator.
* @see #evaluate(SearchContext, int, int, int)
*/
public abstract class AbstractBasicQuiesceEvaluator> implements QuiesceEvaluator {
/** Constructor.
*/
protected AbstractBasicQuiesceEvaluator() {
super();
}
/**
* {@inheritDoc}
*
The quiesce search is recursive algorithm.
*
At each depth:
* - If there's no check:
* - if current position evaluation is >= beta it returns beta
* - if current position evaluation is > alpha alpha is replaced by the evaluation
*
* - The method calls {@link #getMoves(SearchContext, int)}:
* - If the move list is empty, it returns the evaluation of current position.
* - Otherwise, for each move, it plays the move and performs the same algorithm on this new position.
*
*
*
*/
@Override
public int evaluate(SearchContext context, int depth, int alpha, int beta) {
return quiesce(context, alpha, beta, depth, 0);
}
private int quiesce(SearchContext context, int alpha, int beta, int rootDepth, int quiesceDepth) {
final SearchStatistics statistics = context.getStatistics();
final boolean check = isCheck(context);
if (!check) {
final int standPat = context.getEvaluator().evaluate(context.getGamePosition());
statistics.evaluationDone();
if (standPat>=beta) {
return beta;
}
if (alpha < standPat) {
alpha = standPat;
}
}
final List moves = getMoves(context, quiesceDepth);
statistics.movesGenerated(moves.size());
boolean mate = check;
for (M move : moves) {
if (makeMove(context, move)) {
mate = false;
statistics.movePlayed();
final int score = -quiesce(context, -beta, -alpha, rootDepth, quiesceDepth+1);
context.unmakeMove();
if (score >= beta) {
return beta;
}
if (score > alpha) {
alpha = score;
}
}
}
return mate ? -context.getEvaluator().getWinScore(rootDepth+quiesceDepth) : alpha;
}
/** Tests whether the current position is a check.
* @param context The current context (you can find current position with {@link SearchContext#getGamePosition()})
* @return true if the position is a check
*/
protected abstract boolean isCheck(SearchContext context);
/** Gets the list of quiesce moves.
* @param context The search context (can be used to get the board)
* @param quiesceDepth The quiesce depth. 0 for the first level
* @return A list of moves to analyze deeper (usually, this list should contain moves to escape a check, captures and check moves), an empty list to stop deepening.
*/
protected abstract List getMoves(SearchContext context, int quiesceDepth);
/** Make a move.
*
The default implementation make the move with a {@link MoveConfidence#PSEUDO_LEGAL} confidence.
* @param context The context on which to apply the move
* @param move The move to play
* @return true if the move was successfully played, false if the move is illegal
*/
protected boolean makeMove(SearchContext context, M move) {
return context.makeMove(move, MoveConfidence.PSEUDO_LEGAL);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy