All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fathzer.chess.utils.evaluators.quiesce.AbstractBasicQuiesceEvaluator Maven / Gradle / Ivy

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