diff --git a/.github/workflows/try_compile.yml b/.github/workflows/try_compile.yml
index a1759f3..be6f456 100644
--- a/.github/workflows/try_compile.yml
+++ b/.github/workflows/try_compile.yml
@@ -49,15 +49,10 @@ jobs:
- name: Configure CMake
shell: bash
run: |
- CXX_FLAGS=""
- LINK_FLAGS=""
-
cmake -B "${{ steps.vars.outputs.dir }}" \
-DCMAKE_C_COMPILER=${{ matrix.c_compiler }} \
-DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} \
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }} \
- -DCMAKE_CXX_FLAGS_DEBUG="$CXX_FLAGS" \
- -DCMAKE_EXE_LINKER_FLAGS="$LINK_FLAGS" \
-S "${{ github.workspace }}"
- name: Build
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6f34095..1f9eebb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,21 @@
-cmake_minimum_required(VERSION 3.16)
+# a chess library (bonus: you can integrate more piece types!) which
+# supports Chess960 and is decently fast enough
+# Copyright (C) 2025-2026 winapiadmin
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+cmake_minimum_required(VERSION 3.14)
project(chesslib LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
@@ -51,7 +68,7 @@ if(BUILD_TESTING)
FetchContent_Declare(
doctest
GIT_REPOSITORY https://github.com/doctest/doctest.git
- GIT_TAG v2.4.12
+ GIT_TAG v2.5.2
)
FetchContent_MakeAvailable(doctest)
@@ -76,4 +93,4 @@ if(BUILD_TESTING)
endif()
endif()
-endif()
\ No newline at end of file
+endif()
diff --git a/attacks.cpp b/attacks.cpp
index 69d0efc..733a42f 100644
--- a/attacks.cpp
+++ b/attacks.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#include "attacks.h"
namespace chess::_chess {
diff --git a/attacks.h b/attacks.h
index 5027d84..fb90680 100644
--- a/attacks.h
+++ b/attacks.h
@@ -1,3 +1,22 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
#pragma once
#include "bitboard.h"
#include "fwd_decl.h"
@@ -126,7 +145,7 @@ struct Magic {
struct Magic {
Bitboard mask;
Bitboard magic;
- int index;
+ size_t index;
Bitboard shift;
constexpr Bitboard operator()(Bitboard b) const { return (((b & mask)) * magic) >> shift; }
};
@@ -162,6 +181,39 @@ extern const std::array BishopAttacks;
return (b & ~MASK_FILE[7]) << 1;
case Direction::SOUTH_EAST:
return (b & ~MASK_FILE[7]) >> 7;
+ case DOUBLE_NORTH:
+ return b << 16;
+
+ case DOUBLE_SOUTH:
+ return b >> 16;
+
+ case DOUBLE_EAST:
+ return (b & ~MASK_FILE[7] & ~(MASK_FILE[7] >> 1)) << 2;
+
+ case DOUBLE_WEST:
+ return (b & ~MASK_FILE[0] & ~(MASK_FILE[0] << 1)) >> 2;
+
+ case DOUBLE_NORTH_EAST: {
+ Bitboard t = (b & ~MASK_FILE[7]) << 9;
+ return (t & ~MASK_FILE[7]) << 9;
+ }
+
+ case DOUBLE_NORTH_WEST: {
+ Bitboard t = (b & ~MASK_FILE[0]) << 7;
+ return (t & ~MASK_FILE[0]) << 7;
+ }
+
+ case DOUBLE_SOUTH_EAST: {
+ Bitboard t = (b & ~MASK_FILE[7]) >> 7;
+ return (t & ~MASK_FILE[7]) >> 7;
+ }
+
+ case DOUBLE_SOUTH_WEST: {
+ Bitboard t = (b & ~MASK_FILE[0]) >> 9;
+ return (t & ~MASK_FILE[0]) >> 9;
+ }
+ case DIR_NONE:
+ return b;
default:
UNREACHABLE();
return 0;
diff --git a/bitboard.h b/bitboard.h
index cc635cb..0aa7eae 100644
--- a/bitboard.h
+++ b/bitboard.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include "types.h"
diff --git a/chess960_tests.cpp b/chess960_tests.cpp
index a5c5666..aa7915a 100644
--- a/chess960_tests.cpp
+++ b/chess960_tests.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#define DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
#include "moves_io.h"
diff --git a/fwd_decl.h b/fwd_decl.h
index 87e64e2..9f822ca 100644
--- a/fwd_decl.h
+++ b/fwd_decl.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include
#include
diff --git a/movegen.cpp b/movegen.cpp
index d92e78a..60f5155 100644
--- a/movegen.cpp
+++ b/movegen.cpp
@@ -1,3 +1,27 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+// AVX512 and scalar bb-movegens
+
+// License: https://github.com/official-stockfish/Stockfish/blob/master/COPYING.txt
+// movegen references
+
+// License: https://github.com/Disservin/chess-library/blob/master/LICENSE
#include "movegen.h"
#include "position.h"
diff --git a/movegen.h b/movegen.h
index df2eb41..bb6aea0 100644
--- a/movegen.h
+++ b/movegen.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include "fwd_decl.h"
#include
diff --git a/moves_io.cpp b/moves_io.cpp
index 06a89fe..f794881 100644
--- a/moves_io.cpp
+++ b/moves_io.cpp
@@ -1,9 +1,28 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+// UCI moves parsing
+
+// License: https://github.com/Disservin/chess-library/blob/master/LICENSE
#include "moves_io.h"
#include "position.h"
#include "types.h"
#include
-#include
-#include
#include
#if defined(__EXCEPTIONS)
#define THROW_IF_EXCEPTIONS_ON(stuff) throw stuff
@@ -237,13 +256,14 @@ template Move parseSan(const _Position &pos, std:
// consume it
std::string src_sq_str = prefix.substr(prefix.size() - 2, 2);
src_square = parse_square(src_sq_str);
- if (src_square == SQ_NONE)
+ if (src_square == SQ_NONE) {
THROW_IF_EXCEPTIONS_ON(IllegalMoveException("illegal san: '" + _san + "' in " + pos.fen()));
+ return Move::none();
+ }
prefix.resize(prefix.size() - 2);
- has_src_square = true;
}
}
-
+ has_src_square = src_square != SQ_NONE;
// 7) Detect piece letter at front if present
PieceType piece_type = NO_PIECE_TYPE;
if (!prefix.empty()) {
diff --git a/moves_io.h b/moves_io.h
index 5dccb74..2a00591 100644
--- a/moves_io.h
+++ b/moves_io.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include "fwd_decl.h"
#include
diff --git a/non_core_tests.cpp b/non_core_tests.cpp
index c6f6f51..d1786cd 100644
--- a/non_core_tests.cpp
+++ b/non_core_tests.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#define DOCTEST_CONFIG_IMPLEMENT
#ifndef __EXCEPTIONS
#define DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
@@ -418,11 +436,11 @@ TEST_SUITE("SAN Parser") {
auto b = Position{ "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK2R w KQkq - 0 17" };
Move m = Move::make(Square::SQ_E1, Square::SQ_H1);
-#if defined(_DEBUG) && !defined(NDEBUG)
- REQUIRE_THROWS_WITH_AS(uci::parseSan(b, "0-0+?!"),
+ Move m2 = Move::none();
+ REQUIRE_THROWS_WITH_AS(m2 = uci::parseSan(b, "0-0+?!"),
"illegal san: '0-0+?!' in rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQK2R w KQkq - 0 17",
chess::uci::IllegalMoveException);
-#endif
+ REQUIRE(m2 == Move::none());
REQUIRE(uci::parseSan(b, "0-0+?!", true) == m);
}
@@ -431,11 +449,12 @@ TEST_SUITE("SAN Parser") {
Move m = Move::make(Square::SQ_E1, Square::SQ_A1);
-#if defined(_DEBUG) && !defined(NDEBUG)
- REQUIRE_THROWS_WITH_AS(uci::parseSan(b, "0-0-0+?!"),
+ Move m2 = Move::none();
+ REQUIRE_THROWS_WITH_AS(m2 = uci::parseSan(b, "0-0-0+?!"),
"illegal san: '0-0-0+?!' in rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/R3K2R w KQkq - 0 1",
chess::uci::IllegalMoveException);
-#endif
+ REQUIRE(m2 == Move::none());
+
REQUIRE(uci::parseSan(b, "0-0-0+?!", true) == m);
}
diff --git a/position.cpp b/position.cpp
index fb0b5b7..c1636a5 100644
--- a/position.cpp
+++ b/position.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#include "position.h"
#include "movegen.h"
#include "moves_io.h"
@@ -13,17 +31,8 @@
#define _POSSIBLY_CONSTEXPR const
#endif
-#if defined(__EXCEPTIONS)
-#define THROW_IF_EXCEPTIONS_ON(stuff) throw stuff
-#else
-#define THROW_IF_EXCEPTIONS_ON(stuff) ((void)0)
-#endif
#if defined(_DEBUG) || !defined(NDEBUG)
#define INVALID_ARG_IF(c, s) assert(!(c) && s)
-#elif defined(__EXCEPTIONS)
-#define INVALID_ARG_IF(c, s) \
- if (c) \
- THROW_IF_EXCEPTIONS_ON(std::invalid_argument(s))
#else
#define INVALID_ARG_IF(c, s)
#endif
diff --git a/position.h b/position.h
index 1ca73d6..c879391 100644
--- a/position.h
+++ b/position.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include "attacks.h"
#include "bitboard.h"
@@ -63,9 +81,11 @@ template constexpr MoveGenType operator&(MoveGenType a, M
using U = std::underlying_type_t;
return static_cast(static_cast(a) & static_cast(b));
}
+
template constexpr MoveGenType operator|(MoveGenType a, MoveGenType b) {
using U = std::underlying_type_t;
- return static_cast(static_cast(a) | static_cast(b));
+ return static_cast(static_cast(a) |
+ static_cast(b)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
}
template ::value>> class _Position {
private:
@@ -173,9 +193,11 @@ template state_ = state();
history.pop_back();
+ refresh_attacks();
return state_;
} else {
history.pop_back();
+ refresh_attacks();
return;
}
}
@@ -188,10 +210,6 @@ template (state().castlingRights & (state().turn == WHITE ? BLACK_CASTLING : WHITE_CASTLING));
- state().hash ^= zobrist::RandomCastle[state().castlingRights];
state().hash ^= zobrist::RandomTurn;
state().fullMoveNumber += (state().turn == WHITE);
state().pliesFromNull = state().repetition = 0;
@@ -370,7 +388,7 @@ template = ply; }
inline int repetition_count() const { return state().repetition; }
- // Test if it's draw of 75 move rule (that forces everyone to draw). It doesn't consider checkmates.
+ // Test if it's draw of 50 move rule (that forces everyone to draw). It doesn't consider checkmates.
inline bool is_draw(int ply) const { return rule50_count() > 99 || is_repetition(ply); }
// Tests whether there has been at least one repetition
// of positions since the last capture or pawn move.
@@ -487,8 +502,8 @@ template = n; }
inline bool chess960() const { return _chess960; }
- inline bool is_seventyfive_moves(int n) const { return _is_halfmoves(150); }
- inline bool is_fifty_moves(int n) const { return _is_halfmoves(150); }
+ inline bool is_seventyfive_moves() const { return _is_halfmoves(150); }
+ inline bool is_fifty_moves() const { return _is_halfmoves(100); }
inline bool is_fivefold_repetition() const { return is_repetition(5); }
inline bool is_attacked_by(Color color, Square sq, Bitboard occupied = 0) const {
Bitboard occ_bb = occupied ? occupied : this->occ();
diff --git a/printers.cpp b/printers.cpp
index 74e69cc..75f920d 100644
--- a/printers.cpp
+++ b/printers.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#include "printers.h"
#include "moves_io.h"
#include "position.h"
diff --git a/printers.h b/printers.h
index 42581c0..1028bb4 100644
--- a/printers.h
+++ b/printers.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include "fwd_decl.h"
#include
diff --git a/tests.cpp b/tests.cpp
index 4b9ee33..318e24b 100644
--- a/tests.cpp
+++ b/tests.cpp
@@ -1,11 +1,27 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#define DOCTEST_CONFIG_IMPLEMENT
#define DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS
-#include "moves_io.h"
#include "position.h"
#include "printers.h"
#include
#include
-#include
using namespace chess;
// --------- Color assertions ----------
static_assert(color_of(PolyglotPiece::BPAWN) == BLACK, "BPAWN should be BLACK");
@@ -197,7 +213,37 @@ template uint64_t perft(_Po
uint64_t total = 0;
for (const Move &m : moves) {
pos.template doMove(m);
+#if !IS_RELEASE
+ {
+ const auto pre_nm_hash_1 = pos.hash();
+ const auto pre_nm_fen_1 = pos.fen();
+ if (pos.zobrist() != pos.hash())
+ REQUIRE(pos.zobrist() == pos.hash());
+ pos.doNullMove();
+ pos.undoMove();
+ if (!(pos.hash() == pre_nm_hash_1 && pos.fen() == pre_nm_fen_1 && pos.zobrist() == pre_nm_hash_1)) {
+ REQUIRE(pos.hash() == pre_nm_hash_1);
+ REQUIRE(pos.fen() == pre_nm_fen_1);
+ REQUIRE(pos.zobrist() == pre_nm_hash_1);
+ }
+ }
+#endif
const uint64_t nodes = perft(pos, depth - 1);
+#if !IS_RELEASE
+ {
+ const auto pre_nm_hash_1 = pos.hash();
+ const auto pre_nm_fen_1 = pos.fen();
+ if (pos.zobrist() != pos.hash())
+ REQUIRE(pos.zobrist() == pos.hash());
+ pos.doNullMove();
+ pos.undoMove();
+ if (!(pos.hash() == pre_nm_hash_1 && pos.fen() == pre_nm_fen_1 && pos.zobrist() == pre_nm_hash_1)) {
+ REQUIRE(pos.hash() == pre_nm_hash_1);
+ REQUIRE(pos.fen() == pre_nm_fen_1);
+ REQUIRE(pos.zobrist() == pre_nm_hash_1);
+ }
+ }
+#endif
pos.undoMove();
if constexpr (EnableDiv)
std::cout << m << ": " << nodes << '\n';
diff --git a/types.h b/types.h
index f6177f8..f88af18 100644
--- a/types.h
+++ b/types.h
@@ -1,3 +1,26 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
+
+// enums, structures, Move class taken from Stockfish
+
+// License: https://github.com/official-stockfish/Stockfish/blob/master/COPYING.txt
+
#pragma once
#include "fwd_decl.h"
@@ -111,6 +134,15 @@ enum Direction : int8_t {
SOUTH_EAST = SOUTH + EAST,
SOUTH_WEST = SOUTH + WEST,
NORTH_WEST = NORTH + WEST,
+ DOUBLE_NORTH = 2*NORTH,
+ DOUBLE_EAST = 2*EAST,
+ DOUBLE_SOUTH = 2*SOUTH,
+ DOUBLE_WEST = 2*WEST,
+ DOUBLE_NORTH_EAST = 2*NORTH_EAST,
+ DOUBLE_SOUTH_EAST = 2*SOUTH_EAST,
+ DOUBLE_SOUTH_WEST = 2*SOUTH_WEST,
+ DOUBLE_NORTH_WEST = 2*NORTH_WEST,
+
DIR_NONE = 0
};
// clang-format on
@@ -266,23 +298,23 @@ enum CastlingRights : int8_t {
constexpr CastlingRights operator&(Color c, CastlingRights cr) {
return CastlingRights((c == WHITE ? WHITE_CASTLING : BLACK_CASTLING) & cr);
}
-// Bitwise OR assignment operator
+
inline CastlingRights &operator|=(CastlingRights &a, CastlingRights b) {
- a = static_cast(static_cast(a) | static_cast(b));
- return a;
+ return a = static_cast(static_cast(a) |
+ static_cast(b)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
}
-// Bitwise OR assignment operator
inline CastlingRights operator|(CastlingRights a, CastlingRights b) {
- return static_cast(static_cast(a) | static_cast(b));
+ return static_cast(static_cast(a) |
+ static_cast(b)); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
}
-// Bitwise OR assignment operator
inline CastlingRights &operator&=(CastlingRights &a, CastlingRights b) {
a = static_cast(static_cast(a) & static_cast(b));
return a;
}
inline CastlingRights operator~(CastlingRights a) {
- return static_cast(static_cast(a) ^ ANY_CASTLING);
+ return static_cast(static_cast(a) ^
+ ANY_CASTLING); // NOLINT(clang-analyzer-optin.core.EnumCastOutOfRange)
}
enum MoveType : uint16_t { NORMAL, PROMOTION = 1 << 14, EN_PASSANT = 2 << 14, CASTLING = 3 << 14 };
diff --git a/zobrist.cpp b/zobrist.cpp
index 0d82cf5..f1f6811 100644
--- a/zobrist.cpp
+++ b/zobrist.cpp
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#include "zobrist.h"
#include "types.h"
namespace chess::zobrist {
diff --git a/zobrist.h b/zobrist.h
index 020a8e3..3a43a5f 100644
--- a/zobrist.h
+++ b/zobrist.h
@@ -1,3 +1,21 @@
+/*
+ a chess library (bonus: you can integrate more piece types!) which
+ supports Chess960 and is decently fast enough
+ Copyright (C) 2025-2026 winapiadmin
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+*/
#pragma once
#include
#include