Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ option(BUILD_TESTS "Build tests" OFF)
set(CMAKE_CXX_STANDARD 26)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_EXTENSIONS ON)

add_compile_options(-Wall -Wextra -Wpedantic)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
Expand Down
4 changes: 2 additions & 2 deletions Chess/Attacks.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Attacks.h"

#include <utility>

#include "BitBoard.h"
Expand Down Expand Up @@ -29,8 +30,7 @@ Bitboard SimpleChessEngine::GenerateAttackMask(const BitIndex square,

for (auto direction : GetStepDelta<sliding_piece>()) {
Bitboard step;
for (BitIndex temp = square;
(occupancy & SingleSquare(temp)).None();) {
for (BitIndex temp = square; (occupancy & SingleSquare(temp)).None();) {
step = DoShiftIfValid(temp, direction).value_or(kEmptyBoard);
result |= step;
if (step.None()) break;
Expand Down
6 changes: 6 additions & 0 deletions Chess/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ struct DebugInfo {
std::size_t nmp_cuts{};

std::size_t tt_hits{};
std::size_t tt_pv_misses{};
std::size_t tt_other_misses{};
std::size_t tt_wrong_moves{};
std::size_t tt_cuts{};

DebugInfo &operator+=(const DebugInfo &other) {
Expand All @@ -23,6 +26,9 @@ struct DebugInfo {
nmp_tries += other.nmp_tries;
nmp_cuts += other.nmp_cuts;
tt_hits += other.tt_hits;
tt_pv_misses += other.tt_pv_misses;
tt_other_misses += other.tt_other_misses;
tt_wrong_moves += other.tt_wrong_moves;
tt_cuts += other.tt_cuts;
return *this;
}
Expand Down
79 changes: 79 additions & 0 deletions Chess/Eval.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#pragma once

#include <cstdint>
#include <ostream>
#include <limits>

namespace SimpleChessEngine {

struct Eval {
std::int16_t value{0};

constexpr Eval() = default;
constexpr Eval(std::int16_t v) : value(v) {}
constexpr Eval(int v) : value(static_cast<std::int16_t>(v)) {}
constexpr Eval(std::size_t v) : value(static_cast<std::int16_t>(v)) {}

constexpr auto operator<=>(const Eval&) const = default;
constexpr bool operator==(const Eval&) const = default;

constexpr Eval operator-() const { return Eval(-value); }
constexpr Eval operator+() const { return *this; }

constexpr Eval operator+(const Eval& other) const {
return Eval(value + other.value);
}
constexpr Eval operator-(const Eval& other) const {
return Eval(value - other.value);
}
constexpr Eval operator*(const std::integral auto scale) const {
return Eval(value * scale);
}
constexpr Eval operator/(const std::integral auto scale) const {
return Eval(value / scale);
}

constexpr Eval& operator+=(const Eval& other) {
value += other.value;
return *this;
}
constexpr Eval& operator-=(const Eval& other) {
value -= other.value;
return *this;
}
constexpr Eval& operator*=(const std::integral auto scale) {
value *= scale;
return *this;
}
constexpr Eval& operator/=(const std::integral auto scale) {
value /= scale;
return *this;
}
};

inline Eval operator*(const std::integral auto scale, const Eval& eval) {
return eval * scale;
}

inline std::ostream& operator<<(std::ostream& os, const Eval& eval) {
return os << eval.value;
}

inline constexpr Eval operator""_ev(unsigned long long value) {
return Eval(static_cast<std::int16_t>(value));
}
} // namespace SimpleChessEngine

namespace std {
template<>
constexpr SimpleChessEngine::Eval numeric_limits<SimpleChessEngine::Eval>::min() noexcept {
return SimpleChessEngine::Eval(numeric_limits<std::int16_t>::min());
}
template<>
constexpr SimpleChessEngine::Eval numeric_limits<SimpleChessEngine::Eval>::max() noexcept{
return SimpleChessEngine::Eval(numeric_limits<std::int16_t>::max());
}
constexpr SimpleChessEngine::Eval abs(const SimpleChessEngine::Eval eval) noexcept {
return SimpleChessEngine::Eval(std::abs(eval.value));
}
}
8 changes: 4 additions & 4 deletions Chess/Evaluation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ namespace SimpleChessEngine {
kPhaseValueLimits[static_cast<size_t>(GamePhase::kMiddleGame)];
const auto eg_limit =
kPhaseValueLimits[static_cast<size_t>(GamePhase::kEndGame)];
pv = std::clamp(pv, eg_limit, mg_limit);
return (eval[static_cast<size_t>(GamePhase::kMiddleGame)] * (pv - eg_limit) +
eval[static_cast<size_t>(GamePhase::kEndGame)] * (mg_limit - pv)) /
kLimitsDifference;
pv = std::clamp<Eval>(pv, eg_limit, mg_limit);
return (eval[static_cast<size_t>(GamePhase::kMiddleGame)].value * (pv - eg_limit).value +
eval[static_cast<size_t>(GamePhase::kEndGame)].value * (mg_limit - pv).value) /
kLimitsDifference.value;
}

[[nodiscard]] Eval Position::Evaluate() const {
Expand Down
10 changes: 5 additions & 5 deletions Chess/Evaluation.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
#include <array>
#include <cstdint>

#include "Eval.h"
#include "Utility.h"

namespace SimpleChessEngine {
using Eval = int;
using SearchResult = std::optional<Eval>;

enum class GamePhase : std::uint8_t { kMiddleGame, kEndGame };

constexpr size_t kGamePhases = 2;

using PhaseValue = int;
using PhaseValue = Eval;

struct TaperedEval {
std::array<Eval, kGamePhases> eval{};
Expand Down Expand Up @@ -68,19 +68,19 @@ constexpr Eval kFullNonPawnMaterial =
.eval[static_cast<size_t>(GamePhase::kMiddleGame)] *
2;

constexpr std::array kPhaseValueLimits = {kFullNonPawnMaterial, 0};
constexpr std::array kPhaseValueLimits = {kFullNonPawnMaterial, Eval{0}};

constexpr PhaseValue kLimitsDifference =
kPhaseValueLimits[0] - kPhaseValueLimits[1];

constexpr Eval kTempoBonus = 20;

constexpr Eval kMateValue = -100'000;
constexpr Eval kMateValue = -10'000;
constexpr Eval kDrawValue = 0;

// returns zero if the score is not mate value
// otherwise returns 1 if it is winning (positive), -1 if losing (negative)
inline int IsMateScore(const int score) {
inline int IsMateScore(const Eval score) {
if (-std::abs(score) > kMateValue + static_cast<Eval>(kMaxSearchPly) + 1) {
return 0;
}
Expand Down
6 changes: 3 additions & 3 deletions Chess/KillerTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ template <size_t MaxKillerCount>
class KillerTable {
public:
void Clear() { killer_total_count_.fill(0); }
void TryAdd(const Depth ply, const Move& move) {
void TryAdd(const Depth ply, Move move) {
if (!Contains(ply, move)) {
table_[ply][killer_total_count_[ply]++ % MaxKillerCount] = move;
}
}
size_t AvailableKillerCount(const Depth ply) const {
return std::min(killer_total_count_[ply], MaxKillerCount);
}
const Move& Get(const Depth ply, const size_t index) const {
Move Get(const Depth ply, const size_t index) const {
assert(index < killer_total_count_[ply] && index < MaxKillerCount);
return table_[ply][index];
}

private:
bool Contains(const Depth ply, const Move& move) {
bool Contains(const Depth ply, Move move) {
for (size_t i = 0; i < std::min(killer_total_count_[ply], MaxKillerCount);
++i) {
if (move == table_[ply][i]) return true;
Expand Down
Loading