BenBot 1.7.5
A chess engine
Loading...
Searching...
No Matches
Score.hpp
Go to the documentation of this file.
1/*
2 * ======================================================================================
3 *
4 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7 * ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9 * ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10 * ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11 *
12 * ======================================================================================
13 */
14
19
20#pragma once
21
22#include <cassert>
23#include <cmath> // IWYU pragma: keep - for std::abs()
24#include <cstddef> // IWYU pragma: keep - for size_t
25#include <cstdint> // IWYU pragma: keep - for std::int16_t
26#include <format>
28#include <limits>
29#include <utility>
30
31namespace ben_bot::eval {
32
33using std::size_t;
34
38using Value = std::int16_t;
39
46inline constexpr Value MAX { std::numeric_limits<Value>::max() - UINT16_C(5) };
47
54inline constexpr Value MATE { MAX / UINT16_C(2) };
55
59inline constexpr Value DRAW { UINT16_C(0) };
60
67struct Score final {
69 Value value { UINT16_C(0) };
70
75 constexpr operator Value() const noexcept { return value; }
76
78 [[nodiscard]] constexpr auto operator-() const noexcept -> Score { return { static_cast<Value>(-value) }; }
79
82
84 [[nodiscard]] auto is_mate() const noexcept -> bool { return std::cmp_greater_equal(std::abs(value), MATE); }
85
87 [[nodiscard]] constexpr auto is_winning_mate() const noexcept -> bool { return std::cmp_greater_equal(value, MATE); }
88
90 [[nodiscard]] constexpr auto is_losing_mate() const noexcept -> bool { return std::cmp_less_equal(value, -MATE); }
91
95 [[nodiscard]] auto ply_to_mate() const noexcept -> size_t
96 {
97 assert(is_mate());
98
99 return static_cast<size_t>(MAX - std::abs(value));
100 }
101
103
108 [[nodiscard]] constexpr auto to_tt() const noexcept -> Value;
109
111 using LibchessScore = chess::uci::printing::SearchInfo::Score;
112
114 [[nodiscard]] auto to_libchess() const noexcept -> LibchessScore;
115
120 [[nodiscard, gnu::const]] static constexpr auto mate(const size_t plyFromRoot) noexcept -> Score
121 {
122 // multiply by -1 here because this score is relative to the player who got mated
123 return { static_cast<Value>(
124 (MAX - static_cast<Value>(plyFromRoot)) * -1) };
125 }
126
130 [[nodiscard, gnu::const]] static constexpr auto from_tt(
131 Value eval, size_t plyFromRoot) noexcept
132 -> Score;
133};
134
135/*
136 ___ ,--,
137 ,---, ,--.'|_ ,--, ,--.'|
138 ,---.'| | | :,' ,--.'| | | :
139 | | : : : ' : | |, : : ' .--.--.
140 | | | ,---. .;__,' / ,--.--. `--'_ | ' | / / '
141 ,--.__| | / \ | | | / \ ,' ,'| ' | | | : /`./
142 / ,' | / / |:__,'| : .--. .-. | ' | | | | : | : ;_
143. ' / |. ' / | ' : |__ \__\/: . . | | : ' : |__ \ \ `.
144' ; |: |' ; /| | | '.'| ," .--.; | ' : |__ | | '.'| `----. \
145| | '/ '' | / | ; : ;/ / ,. | | | '.'|; : ;/ /`--' /__ ___ ___
146| : :|| : | | , /; : .' \; : ;| , /'--'. / .\/ .\/ .\
147 \ \ / \ \ / ---`-' | , .-./| , / ---`-' `--'---'\ ; \ ; \ ; |
148 `----' `----' `--`---' ---`-' `--" `--" `--"
149
150 */
151
152constexpr auto Score::to_tt() const noexcept -> Value
153{
154 if (is_losing_mate())
155 return -MATE;
156
157 if (is_winning_mate())
158 return MATE;
159
160 return value;
161}
162
163constexpr auto Score::from_tt(
164 const Value eval, const size_t plyFromRoot) noexcept
165 -> Score
166{
167 if (std::cmp_less_equal(eval, -MATE))
168 return mate(plyFromRoot);
169
170 if (std::cmp_greater_equal(eval, MATE))
171 return -mate(plyFromRoot);
172
173 return { eval };
174}
175
176inline auto Score::to_libchess() const noexcept -> LibchessScore
177{
178 LibchessScore res;
179
180 if (is_mate()) {
181 auto ply = static_cast<int>(ply_to_mate());
182
183 if (is_losing_mate())
184 ply *= -1;
185
186 res.value = LibchessScore::MateIn { .plies = ply };
187 } else {
188 res.value = LibchessScore::Centipawns { .value = value };
189 }
190
191 return res;
192}
193
194} // namespace ben_bot::eval
195
203template <>
204struct std::formatter<ben_bot::eval::Score> final {
205 template <typename ParseContext>
206 constexpr auto parse(ParseContext& ctx) -> typename ParseContext::iterator
207 {
208 return ctx.begin();
209 }
210
211 template <typename FormatContext>
212 auto format(
213 const ben_bot::eval::Score& score, FormatContext& ctx) const
214 -> typename FormatContext::iterator
215 {
216 return std::format_to(ctx.out(), "{}", score.value);
217 }
218};
std::int16_t Value
Definition Score.hpp:38
constexpr Value DRAW
Definition Score.hpp:59
constexpr Value MAX
Definition Score.hpp:46
constexpr Value MATE
Definition Score.hpp:54
auto is_mate() const noexcept -> bool
Definition Score.hpp:84
constexpr auto is_losing_mate() const noexcept -> bool
Definition Score.hpp:90
static constexpr auto from_tt(Value eval, size_t plyFromRoot) noexcept -> Score
Definition Score.hpp:163
chess::uci::printing::SearchInfo::Score LibchessScore
Definition Score.hpp:111
constexpr auto operator-() const noexcept -> Score
Definition Score.hpp:78
auto to_libchess() const noexcept -> LibchessScore
Definition Score.hpp:176
constexpr auto to_tt() const noexcept -> Value
Definition Score.hpp:152
constexpr auto is_winning_mate() const noexcept -> bool
Definition Score.hpp:87
static constexpr auto mate(const size_t plyFromRoot) noexcept -> Score
Definition Score.hpp:120
auto ply_to_mate() const noexcept -> size_t
Definition Score.hpp:95
std::variant< Centipawns, MateIn > value
Definition Printing.hpp:90
auto format(const ben_bot::eval::Score &score, FormatContext &ctx) const -> typename FormatContext::iterator
Definition Score.hpp:212
constexpr auto parse(ParseContext &ctx) -> typename ParseContext::iterator
Definition Score.hpp:206