<commit_before>package mitzi;

import static mitzi.MateScores.NEG_INF;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * 
 * This class computes the value of a board in a proper way, see
 * http://philemon.cycovery.com/site/part2.html for more details.
 * 
 */
public class BoardAnalyzer implements IPositionAnalyzer {

	// the square to array index from Position.java
	protected static int[] square_to_array_index = { 64, 64, 64, 64, 64, 64,
			64, 64, 64, 64, 64, 56, 48, 40, 32, 24, 16, 8, 0, 64, 64, 57, 49,
			41, 33, 25, 17, 9, 1, 64, 64, 58, 50, 42, 34, 26, 18, 10, 2, 64,
			64, 59, 51, 43, 35, 27, 19, 11, 3, 64, 64, 60, 52, 44, 36, 28, 20,
			12, 4, 64, 64, 61, 53, 45, 37, 29, 21, 13, 5, 64, 64, 62, 54, 46,
			38, 30, 22, 14, 6, 64, 64, 63, 55, 47, 39, 31, 23, 15, 7, 64, 64,
			64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
			64, 64, 64 };

	static private int[] piece_values = { 100, 500, 325, 325, 975, 000 };

	// The following arrays contains the value of a piece on a specific square,
	// always in favor of white. Since the arrays are symmetric w.r.t. the
	// columns, BLACK uses 63-i entry with opposite sign.
	static private int[] piece_activity_b_k = { -16, -16, -8, -8, -8, -8, -16,
			-16, -16, -16, -4, -4, -4, -4, -16, -16, -8, 2, 6, 6, 6, 6, 2, -8,
			-8, 2, 6, 6, 6, 6, 2, -8, -8, 2, 4, 4, 4, 4, 2, -8, -8, 2, 2, 2, 2,
			2, 2, -8, -8, -8, 0, 0, 0, 0, -8, -8, -16, -8, -8, -8, -8, -8, -8,
			-16 };

	static private int[] piece_activity_r = { 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4,
			6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0,
			0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0,
			0, 0, 0, 4, 6, 6, 4, 0, 0, };

	static private int[] piece_activity_q = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
			5, 5, 4, 0, 0, 0, 2, 4, 10, 10, 4, 2, 0, 0, 2, 10, 12, 12, 10, 2,
			0, -10, 2, 10, 12, 12, 10, 2, -10, -10, -10, 4, 10, 10, 4, -10,
			-10, -10, 2, 8, 8, 8, 8, 2, -10, -10, -8, 0, 0, 0, 0, -8, -10, };

	static private int[] weak_positions = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 8, 12, 12, 8, 0, 0, 0, 2, 12, 16, 16, 12, 2, 0,
			0, 2, 12, 20, 20, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };

	static private int[] pawn_positions_w = { 0, 0, 0, 0, 0, 0, 0, 0, 28, 28,
			35, 42, 45, 35, 28, 28, -9, -3, 7, 12, 15, 7, -3, -9, -10, -10, 6,
			9, 10, 6, -11, -10, -11, -11, 4, 5, 6, 2, -11, -11, -11, -11, 0, 0,
			1, 0, -11, -11, -6, -6, 4, 5, 5, 4, -6, -6, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] pawn_positions_b = { 0, 0, 0, 0, 0, 0, 0, 0, -6, -6,
			4, 5, 5, 4, -6, -6, -11, -11, 0, 0, 1, 0, -11, -11, -11, -11, 4, 5,
			6, 2, -11, -11, -10, -10, 6, 9, 10, 6, -11, -10, -9, -3, 7, 12, 15,
			7, -3, -9, 28, 28, 35, 42, 45, 35, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] king_positions_w = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, -15,
			-10, 0, 0, 5, 10, 18, -8, -3, -8, 23, 10 };

	static private int[] king_positions_b = { 5, 10, 18, -8, -3, -8, 23, 10, 0,
			0, 0, -10, -15, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] twin_pawns = { 0, 0, 1, 2, 3, 4, 7, 0 };

	static private int[] covered_pawns = { 0, 0, 4, 6, 8, 12, 16, 0 };

	static private int[] passed_pawn = { 0, 2, 10, 20, 40, 60, 70, 0 };

	static private int[] passed_pawn_with_king = { 0, 0, 0, 0, 10, 50, 80, 0 };

	static private int[] blocked_passed_pawn = { 0, 0, -8, -16, -32, -45, -58,
			0 };

	// if not all Bishop and Knight has moved, moving the queen results in
	// negative score
	static private int PREMATURE_QUEEN = -17;

	// bonus, if the rook is on an open line (no other pawns)
	static private int ROOK_OPEN_LINE = 20;

	// bonus if the rook is on an halfopen line (only opponents pawns)
	static private int ROOK_HALFOPEN_LINE = 5;

	// bonus if the rook is in the 7th row and either opponents king is in the
	// 8th or pawn in the 7th
	static private int ROOK_7TH_2ND = 25;

	// bonus if the previous bonus holds and the 7th row is empty. (hopefully)
	static private int ROOK_7TH_2ND_ABSOLUTE = 15;

	// bonus if a rook covers the other rook, this replaces the
	// ROOK_7TH_2ND and counts for each rook (both on the 7th row)
	static private int REINFORCED_ROOK_7TH_2ND = 40;

	static private int PASSED_ROOK_SUPPORT = 10;
	static private int ENDGAME_BISHOP_BONUS = 10; // not yet implemented
	static private int BISHOP_BASELINE_CAGED = -12;

	// bonus if a queen is covered on the 7th row by a rook
	static private int REINFORCING_QUEEN_7TH_2ND = 20;

	// The player receives a bonus if the 2 bishops are alive.
	static private int bishop_pair_value = 25;

	static private int MULTI_PAWN = -10;

	static private int ISOLATED_PAWN = -20;

	static private int COVERED_PASSED_7TH_PAWN = 90;

	static private int CASTLING_LOSS = -40;

	static public long eval_counter_seldepth = 0;

	// the number of pieces, when the endgame starts (a first draft, needs to be
	// optimized)
	static public int ENDGAME_THRESHOLD = 8;

	@Override
	public AnalysisResult eval0(IPosition board) {
		int score = 0;
		board.cacheOccupiedSquares();
		// Evaluate Pawn Stucture
		score += evalPawns(board);

		// Evaluate Diagonals and lines
		score += evalLinesAndDiagonals(board);

		// Evaluate position - activity
		score += evalPieceActivity(board);

		// Evaluate weak/strong position
		score += evalWeakPosition(board);

		// Evaluate the pieces
		score += evalPieces(board);

		// Evaluate the King's position (not in endgame)
		score += evalKingPos(board);

		AnalysisResult result = new AnalysisResult(score, false, false, 0, 0,
				Flag.EXACT);
		return result;
	}

	@Override
	public AnalysisResult evalBoard(IPosition position, int alpha, int beta) {
		AnalysisResult result = quiesce(position, alpha, beta);

		// The analysis result should always contain the pure value (not
		// perturbed via side_sign)
		return result;
	}

	/**
	 * Implements Quiescence search to avoid the horizon effect. The function
	 * increase the search depth until no capture is possible, where only
	 * captures are analyzed. The optimal value is found using the negamax
	 * algorithm.
	 * 
	 * @see <a
	 *      href="http://chessprogramming.wikispaces.com/Quiescence+Search">http://chessprogramming.wikispaces.com/Quiescence+Search</a>
	 * 
	 * @param position
	 *            the position to be analyzed
	 * @param alpha
	 *            the alpha value of alpha-beta search
	 * @param beta
	 *            the beta value of alpha-beta search
	 * @return the value of the board
	 */
	private AnalysisResult quiesce(IPosition position, int alpha, int beta) {

		int side_sign = Side.getSideSign(position.getActiveColor());

		// Cache lookup
		AnalysisResult entry = ResultCache.getResult(position);
		if (entry != null) {
			// TODO table_counter++;
			if (entry.flag == Flag.EXACT) {
				AnalysisResult new_entry = entry.tinyCopy();
				new_entry.plys_to_seldepth += entry.plys_to_eval0;
				return new_entry;
			} else if (entry.flag == Flag.LOWERBOUND)
				alpha = Math.max(alpha, entry.score * side_sign);
			else if (entry.flag == Flag.UPPERBOUND)
				beta = Math.min(beta, entry.score * side_sign);

			if (alpha >= beta) {
				AnalysisResult new_entry = entry.tinyCopy();
				new_entry.plys_to_seldepth += entry.plys_to_eval0;
				return new_entry;
			}
		}<commit_msg>if a position in quiesce is found, dont use the depth and seldepth. <commit_after>package mitzi;

import static mitzi.MateScores.NEG_INF;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * 
 * This class computes the value of a board in a proper way, see
 * http://philemon.cycovery.com/site/part2.html for more details.
 * 
 */
public class BoardAnalyzer implements IPositionAnalyzer {

	// the square to array index from Position.java
	protected static int[] square_to_array_index = { 64, 64, 64, 64, 64, 64,
			64, 64, 64, 64, 64, 56, 48, 40, 32, 24, 16, 8, 0, 64, 64, 57, 49,
			41, 33, 25, 17, 9, 1, 64, 64, 58, 50, 42, 34, 26, 18, 10, 2, 64,
			64, 59, 51, 43, 35, 27, 19, 11, 3, 64, 64, 60, 52, 44, 36, 28, 20,
			12, 4, 64, 64, 61, 53, 45, 37, 29, 21, 13, 5, 64, 64, 62, 54, 46,
			38, 30, 22, 14, 6, 64, 64, 63, 55, 47, 39, 31, 23, 15, 7, 64, 64,
			64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
			64, 64, 64 };

	static private int[] piece_values = { 100, 500, 325, 325, 975, 000 };

	// The following arrays contains the value of a piece on a specific square,
	// always in favor of white. Since the arrays are symmetric w.r.t. the
	// columns, BLACK uses 63-i entry with opposite sign.
	static private int[] piece_activity_b_k = { -16, -16, -8, -8, -8, -8, -16,
			-16, -16, -16, -4, -4, -4, -4, -16, -16, -8, 2, 6, 6, 6, 6, 2, -8,
			-8, 2, 6, 6, 6, 6, 2, -8, -8, 2, 4, 4, 4, 4, 2, -8, -8, 2, 2, 2, 2,
			2, 2, -8, -8, -8, 0, 0, 0, 0, -8, -8, -16, -8, -8, -8, -8, -8, -8,
			-16 };

	static private int[] piece_activity_r = { 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4,
			6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0,
			0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0, 0, 0, 0, 4, 6, 6, 4, 0,
			0, 0, 0, 4, 6, 6, 4, 0, 0, };

	static private int[] piece_activity_q = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
			5, 5, 4, 0, 0, 0, 2, 4, 10, 10, 4, 2, 0, 0, 2, 10, 12, 12, 10, 2,
			0, -10, 2, 10, 12, 12, 10, 2, -10, -10, -10, 4, 10, 10, 4, -10,
			-10, -10, 2, 8, 8, 8, 8, 2, -10, -10, -8, 0, 0, 0, 0, -8, -10, };

	static private int[] weak_positions = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 8, 12, 12, 8, 0, 0, 0, 2, 12, 16, 16, 12, 2, 0,
			0, 2, 12, 20, 20, 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };

	static private int[] pawn_positions_w = { 0, 0, 0, 0, 0, 0, 0, 0, 28, 28,
			35, 42, 45, 35, 28, 28, -9, -3, 7, 12, 15, 7, -3, -9, -10, -10, 6,
			9, 10, 6, -11, -10, -11, -11, 4, 5, 6, 2, -11, -11, -11, -11, 0, 0,
			1, 0, -11, -11, -6, -6, 4, 5, 5, 4, -6, -6, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] pawn_positions_b = { 0, 0, 0, 0, 0, 0, 0, 0, -6, -6,
			4, 5, 5, 4, -6, -6, -11, -11, 0, 0, 1, 0, -11, -11, -11, -11, 4, 5,
			6, 2, -11, -11, -10, -10, 6, 9, 10, 6, -11, -10, -9, -3, 7, 12, 15,
			7, -3, -9, 28, 28, 35, 42, 45, 35, 28, 28, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] king_positions_w = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -10, -15,
			-10, 0, 0, 5, 10, 18, -8, -3, -8, 23, 10 };

	static private int[] king_positions_b = { 5, 10, 18, -8, -3, -8, 23, 10, 0,
			0, 0, -10, -15, -10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	static private int[] twin_pawns = { 0, 0, 1, 2, 3, 4, 7, 0 };

	static private int[] covered_pawns = { 0, 0, 4, 6, 8, 12, 16, 0 };

	static private int[] passed_pawn = { 0, 2, 10, 20, 40, 60, 70, 0 };

	static private int[] passed_pawn_with_king = { 0, 0, 0, 0, 10, 50, 80, 0 };

	static private int[] blocked_passed_pawn = { 0, 0, -8, -16, -32, -45, -58,
			0 };

	// if not all Bishop and Knight has moved, moving the queen results in
	// negative score
	static private int PREMATURE_QUEEN = -17;

	// bonus, if the rook is on an open line (no other pawns)
	static private int ROOK_OPEN_LINE = 20;

	// bonus if the rook is on an halfopen line (only opponents pawns)
	static private int ROOK_HALFOPEN_LINE = 5;

	// bonus if the rook is in the 7th row and either opponents king is in the
	// 8th or pawn in the 7th
	static private int ROOK_7TH_2ND = 25;

	// bonus if the previous bonus holds and the 7th row is empty. (hopefully)
	static private int ROOK_7TH_2ND_ABSOLUTE = 15;

	// bonus if a rook covers the other rook, this replaces the
	// ROOK_7TH_2ND and counts for each rook (both on the 7th row)
	static private int REINFORCED_ROOK_7TH_2ND = 40;

	static private int PASSED_ROOK_SUPPORT = 10;
	static private int ENDGAME_BISHOP_BONUS = 10; // not yet implemented
	static private int BISHOP_BASELINE_CAGED = -12;

	// bonus if a queen is covered on the 7th row by a rook
	static private int REINFORCING_QUEEN_7TH_2ND = 20;

	// The player receives a bonus if the 2 bishops are alive.
	static private int bishop_pair_value = 25;

	static private int MULTI_PAWN = -10;

	static private int ISOLATED_PAWN = -20;

	static private int COVERED_PASSED_7TH_PAWN = 90;

	static private int CASTLING_LOSS = -40;

	static public long eval_counter_seldepth = 0;

	// the number of pieces, when the endgame starts (a first draft, needs to be
	// optimized)
	static public int ENDGAME_THRESHOLD = 8;

	@Override
	public AnalysisResult eval0(IPosition board) {
		int score = 0;
		board.cacheOccupiedSquares();
		// Evaluate Pawn Stucture
		score += evalPawns(board);

		// Evaluate Diagonals and lines
		score += evalLinesAndDiagonals(board);

		// Evaluate position - activity
		score += evalPieceActivity(board);

		// Evaluate weak/strong position
		score += evalWeakPosition(board);

		// Evaluate the pieces
		score += evalPieces(board);

		// Evaluate the King's position (not in endgame)
		score += evalKingPos(board);

		AnalysisResult result = new AnalysisResult(score, false, false, 0, 0,
				Flag.EXACT);
		return result;
	}

	@Override
	public AnalysisResult evalBoard(IPosition position, int alpha, int beta) {
		AnalysisResult result = quiesce(position, alpha, beta);

		// The analysis result should always contain the pure value (not
		// perturbed via side_sign)
		return result;
	}

	/**
	 * Implements Quiescence search to avoid the horizon effect. The function
	 * increase the search depth until no capture is possible, where only
	 * captures are analyzed. The optimal value is found using the negamax
	 * algorithm.
	 * 
	 * @see <a
	 *      href="http://chessprogramming.wikispaces.com/Quiescence+Search">http://chessprogramming.wikispaces.com/Quiescence+Search</a>
	 * 
	 * @param position
	 *            the position to be analyzed
	 * @param alpha
	 *            the alpha value of alpha-beta search
	 * @param beta
	 *            the beta value of alpha-beta search
	 * @return the value of the board
	 */
	private AnalysisResult quiesce(IPosition position, int alpha, int beta) {

		int side_sign = Side.getSideSign(position.getActiveColor());

		// Cache lookup
		AnalysisResult entry = ResultCache.getResult(position);
		if (entry != null) {
			// TODO table_counter++;
			if (entry.flag == Flag.EXACT) {
				AnalysisResult new_entry = entry.tinyCopy();
				new_entry.plys_to_eval0=0;
				new_entry.plys_to_seldepth=0;
				//new_entry.plys_to_seldepth += entry.plys_to_eval0;
				return new_entry;
			} else if (entry.flag == Flag.LOWERBOUND)
				alpha = Math.max(alpha, entry.score * side_sign);
			else if (entry.flag == Flag.UPPERBOUND)
				beta = Math.min(beta, entry.score * side_sign);

			if (alpha >= beta) {
				AnalysisResult new_entry = entry.tinyCopy();
				new_entry.plys_to_eval0=0;
				new_entry.plys_to_seldepth=0;
				//new_entry.plys_to_seldepth += entry.plys_to_eval0;
				return new_entry;
			}
		}
{'fraction_non_alphanumeric': 0.16043543057085466, 'fraction_numerical': 0.12427914209810147, 'mean_word_length': 2.811805384045443, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 70, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1436623', 'n_tokens_mistral': 8336, 'n_tokens_neox': 6255, 'n_words': 2483}