stellar

Stellar - UCI Chess engine written in C++20
git clone git://git.dimitrijedobrota.com/stellar.git
Log | Files | Refs | README | LICENSE

commit 72c1d1c1ce13660c03891584709d5dda8a8ec2af
parent ac4acc635c69b6c2189acbbdf7521dea23fb2f0b
Author: Dimitrije Dobrota <mail@dimitrijedobrota.com>
Date:   Fri,  1 Sep 2023 15:50:14 +0200

Rooks and king on open and semi-open file eval

Diffstat:
MCMakeLists.txt | 2+-
Msrc/engine/evaluate.cpp | 99++++++++++++++++++++++++++++++++++++++++---------------------------------------
2 files changed, 51 insertions(+), 50 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) project( Stellar - VERSION 0.0.30 + VERSION 0.0.31 DESCRIPTION "Chess engine written in C" HOMEPAGE_URL https://git.dimitrijedobrota.com/stellar.git LANGUAGES C CXX diff --git a/src/engine/evaluate.cpp b/src/engine/evaluate.cpp @@ -39,29 +39,27 @@ inline constexpr const mask_fr_array mask_isolated = []() constexpr -> mask_fr_a return mask_isolated; }(); -typedef std::array<U64, 64> mask_passed_array; -inline constexpr const mask_passed_array mask_passed_white = []() constexpr -> mask_passed_array { - mask_passed_array mask_passed_white; +typedef std::array<std::array<U64, 64>, 2> mask_passed_array; +inline constexpr const mask_passed_array mask_passed = []() constexpr -> mask_passed_array { + mask_passed_array mask_passed; + for (uint8_t file = 0; file < 8; file++) { U64 mask = mask_file[file] | mask_isolated[file]; for (uint8_t rank = 0; rank < 8; rank++) { mask = nortOne(mask); - mask_passed_white[rank * 8 + file] = mask; + mask_passed[0][rank * 8 + file] = mask; } } - return mask_passed_white; -}(); -inline constexpr const mask_passed_array mask_passed_black = []() constexpr -> mask_passed_array { - mask_passed_array mask_passed_black; for (uint8_t file = 0; file < 8; file++) { U64 mask = mask_file[file] | mask_isolated[file]; for (int8_t rank = 7; rank >= 0; rank--) { mask = soutOne(mask); - mask_passed_black[rank * 8 + file] = mask; + mask_passed[1][rank * 8 + file] = mask; } } - return mask_passed_black; + + return mask_passed; }(); inline constexpr uint8_t get_file(uint8_t square) { return square & 0x07; } @@ -70,70 +68,73 @@ inline constexpr uint8_t get_rank(uint8_t square) { return square >> 3; } inline constexpr const int8_t penalty_pawn_double = -10; inline constexpr const int8_t penalty_pawn_isolated = -10; -inline constexpr const std::array<int16_t, 8> bonus_pawn_passed = {0, 10, 30, 50, 75, 100, 150, 200}; +inline constexpr const int8_t score_open_semi = 10; +inline constexpr const int8_t score_open = 15; +inline constexpr const std::array<std::array<int16_t, 8>, 2> bonus_pawn_passed = { + {{0, 10, 30, 50, 75, 100, 150, 200}, {200, 150, 100, 75, 50, 30, 10, 0}}}; + +using piece::Type::KING; using piece::Type::PAWN; +using piece::Type::ROOK; -int16_t score_position(const Board &board) { +int16_t score_position_side(const Board &board, Color side) { + static U64 bitboard; uint8_t square_i; int16_t score = 0; - // Score all White pieces except pawns + // Score all pieces except pawns for (const piece::Type type : ++piece::TypeIter()) { - U64 bitboard = board.get_bitboard_piece(type, Color::WHITE); + bitboard = board.get_bitboard_piece(type, side); bitboard_for_each_bit(square_i, bitboard) { Square square = static_cast<Square>(square_i); score += piece::score(type); - score += piece::score(type, Color::WHITE, square); - } - } - - // Score all Black pieces except pawns - for (const piece::Type type : ++piece::TypeIter()) { - U64 bitboard = board.get_bitboard_piece(type, Color::BLACK); - bitboard_for_each_bit(square_i, bitboard) { - Square square = static_cast<Square>(square_i); - score -= piece::score(type); - score -= piece::score(type, Color::BLACK, square); + score += piece::score(type, side, square); } } - U64 pawns = board.get_bitboard_piece(PAWN); - U64 pawnsW = board.get_bitboard_piece(PAWN, Color::WHITE); - U64 pawnsB = board.get_bitboard_piece(PAWN, Color::BLACK); + const U64 pawns = board.get_bitboard_piece(PAWN); + const U64 pawnsS = board.get_bitboard_piece(PAWN, side); + const U64 rookS = board.get_bitboard_piece(ROOK, side); + const U64 kingS = board.get_bitboard_piece(KING, side); for (uint8_t file = 0; file < 8; file++) { // check doubled and isolated pawns - U64 pawns_file = pawns & mask_file[file]; - uint8_t pawnsW_count = bit_count(pawns_file & pawnsW); - if (pawnsW_count > 1) score += (pawnsW_count - 1) * penalty_pawn_double; - if (!(mask_isolated[file] & pawnsW)) score += pawnsW_count * penalty_pawn_isolated; + uint8_t pawnsS_count = bit_count(pawnsS & mask_file[file]); + uint8_t pawns_count = bit_count(pawns & mask_file[file]); + + if (pawnsS_count > 1) score += (pawnsS_count - 1) * penalty_pawn_double; + if (!(mask_isolated[file] & pawnsS)) score += pawnsS_count * penalty_pawn_isolated; - uint8_t pawnsB_count = bit_count(pawns_file & pawnsB); - if (pawnsB_count > 1) score -= (pawnsB_count - 1) * penalty_pawn_double; - if (!(mask_isolated[file] & pawnsB)) score -= pawnsB_count * penalty_pawn_isolated; + // rooks on open and semi-open files + if (rookS & mask_file[file]) { + if (!pawns_count) score += score_open; + if (!pawnsS_count) score += score_open_semi; + } + + // king on open and semi-open files + if (kingS & mask_file[file]) { + if (!pawns_count) score -= score_open; + if (!pawnsS_count) score -= score_open_semi; + } } - // Score White pawns, bonus for passed - bitboard_for_each_bit(square_i, pawnsW) { + // Score pawns, bonus for passed + bitboard = pawnsS; + bitboard_for_each_bit(square_i, bitboard) { Square square = static_cast<Square>(square_i); score += piece::score(PAWN); - score += piece::score(PAWN, Color::WHITE, square); - if (!(pawnsB & mask_passed_white[square_i])) score += bonus_pawn_passed[get_rank(square_i)]; + score += piece::score(PAWN, side, square); + if (!(pawns & ~pawnsS & mask_passed[to_underlying(side)][square_i])) + score += bonus_pawn_passed[to_underlying(side)][get_rank(square_i)]; } - // previous bitboard_for_each_bit consumed this mask - pawnsW = board.get_bitboard_piece(PAWN, Color::WHITE); - - // Score White pawns, bonus for passed - bitboard_for_each_bit(square_i, pawnsB) { - Square square = static_cast<Square>(square_i); - score -= piece::score(PAWN); - score -= piece::score(PAWN, Color::BLACK, square); - if (!(pawnsW & mask_passed_black[square_i])) score -= bonus_pawn_passed[7 - get_rank(square_i)]; - } + return score; +} +int16_t score_position(const Board &board) { + const int16_t score = score_position_side(board, Color::WHITE) - score_position_side(board, Color::BLACK); return board.get_side() == Color::WHITE ? score : -score; }