HooverChessUtils_PgnReader 0.9.0
Loading...
Searching...
No Matches
chessboard-test-playmove-helper.h
Go to the documentation of this file.
1// Hoover Chess Utilities / PGN reader
2// Copyright (C) 2022-2025 Sami Kiminki
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <https://www.gnu.org/licenses/>.
16
17#ifndef HOOVER_CHESS_UTILS__PGN_READER__CHESSBOARD_TEST_PLAYMOVE_HELPER_H_INCLUDED
18#define HOOVER_CHESS_UTILS__PGN_READER__CHESSBOARD_TEST_PLAYMOVE_HELPER_H_INCLUDED
19
20#include "chessboard.h"
22
23#include "gtest/gtest.h"
24
25
27{
28
29
30template <typename ... Args>
32 ChessBoard &board,
33 std::size_t expectNumMoves,
34 std::size_t (ChessBoard::*generateMovesFn)(ShortMoveList &moves, SquareSet, Square, Args ...) const noexcept,
35 Move (ChessBoard::*generateSingleMoveFn)(SquareSet, Square, Args ...) const noexcept,
36 SquareSet srcSqMask, Square dstSq, Args && ... args)
37{
38 ShortMoveList moves;
39
40 std::size_t numMoves { (board.*generateMovesFn)(moves, srcSqMask, dstSq, std::forward<Args>(args) ...) };
41 EXPECT_EQ(expectNumMoves, numMoves);
42
43 Move singleMove { (board.*generateSingleMoveFn)(srcSqMask, dstSq, std::forward<Args>(args) ...) };
44
45 if (expectNumMoves == 0U)
46 {
47 EXPECT_TRUE(singleMove.isIllegal());
48 EXPECT_EQ(singleMove, Move::illegalNoMove());
49 }
50 else if (expectNumMoves == 1U)
51 {
52 EXPECT_FALSE(singleMove.isIllegal());
53 }
54 else
55 {
56 EXPECT_TRUE(singleMove.isIllegal());
57 EXPECT_EQ(singleMove, Move::illegalAmbiguousMove());
58 }
59
60 if (numMoves == expectNumMoves)
61 {
62 if (numMoves == 1U)
63 {
64 EXPECT_EQ(singleMove, moves[0U]);
65
66 // Single move found and it is expected
67
68 // Verify that the source square is within the srcSqMask
69 EXPECT_TRUE(srcSqMask.isMember(singleMove.getSrc()));
70
71 // Verify that the destination square is as expected
72 EXPECT_EQ(dstSq, singleMove.getDst());
73
74 // Additional check: verify that allowing all other sources except
75 // move source returns no moves
76 playMove<Args ...>(
77 board,
78 0U,
79 generateMovesFn,
80 generateSingleMoveFn,
81 ~SquareSet { singleMove.getSrc() },
82 dstSq,
83 std::forward<Args>(args) ...);
84
85 board.doMove(singleMove);
86 }
87 }
88 else
89 {
90 board.printBoard();
91 }
92}
93
95 ChessBoard &board,
96 std::size_t expectNumMoves,
97 std::size_t (ChessBoard::*generateMovesFn)(ShortMoveList &moves) const noexcept,
98 Move (ChessBoard::*generateSingleMoveFn)() const noexcept)
99{
100 ShortMoveList moves;
101
102 std::size_t numMoves { (board.*generateMovesFn)(moves) };
103 EXPECT_EQ(expectNumMoves, numMoves);
104
105 Move singleMove { (board.*generateSingleMoveFn)() };
106
107 if (expectNumMoves == 0U)
108 {
109 EXPECT_TRUE(singleMove.isIllegal());
110 EXPECT_EQ(singleMove, Move::illegalNoMove());
111 }
112 else if (expectNumMoves == 1U)
113 {
114 EXPECT_FALSE(singleMove.isIllegal());
115 }
116 else
117 {
118 EXPECT_TRUE(singleMove.isIllegal());
119 EXPECT_EQ(singleMove, Move::illegalAmbiguousMove());
120 }
121
122 if (numMoves == expectNumMoves)
123 {
124 if (numMoves == 1U)
125 {
126 EXPECT_EQ(singleMove, moves[0U]);
127 board.doMove(singleMove);
128 }
129 }
130 else
131 {
132 board.printBoard();
133 }
134}
135
136}
137
138#define PLAY_MOVE(board, MoveFunction, ...) \
139 hoover_chess_utils::pgn_reader::unit_test::playMove( \
140 board, \
141 1U, \
142 &hoover_chess_utils::pgn_reader::ChessBoard::generateMovesFor ## MoveFunction, \
143 &hoover_chess_utils::pgn_reader::ChessBoard::generateSingleMoveFor ## MoveFunction \
144 __VA_OPT__(,) __VA_ARGS__)
145
146#define PLAY_MOVE_EXPECT_NO_MOVES(board, MoveFunction, ...) \
147 hoover_chess_utils::pgn_reader::unit_test::playMove( \
148 board, \
149 0U, \
150 &hoover_chess_utils::pgn_reader::ChessBoard::generateMovesFor ## MoveFunction, \
151 &hoover_chess_utils::pgn_reader::ChessBoard::generateSingleMoveFor ## MoveFunction \
152 __VA_OPT__(,) __VA_ARGS__)
153
154#endif
The chessboard.
Definition chessboard.h:589
void printBoard() const
Prints the current board to stdout. This is intended only for debugging purposes.
void doMove(Move m) noexcept
Applies a move on the current position. The move is assumed to be legal, and it must be from one of t...
A legal move. Important: see the note!
Definition chessboard.h:198
static constexpr Move illegalNoMove() noexcept
Token for illegal move: no moves generated.
Definition chessboard.h:429
static constexpr Move illegalAmbiguousMove() noexcept
Token for illegal move: ambiguous move generation.
Definition chessboard.h:437
Set of squares. Implemented using a bit-mask.
Definition chessboard-types-squareset.h:35
std::array< CompactMove, 8U > ShortMoveList
Short move list returned by move generators for writing a SAN move. That is, when the piece type and ...
Definition chessboard.h:514
Square
Named square.
Definition chessboard-types.h:122
Definition chessboard-test-playmove-helper.h:27
void playMove(ChessBoard &board, std::size_t expectNumMoves, std::size_t(ChessBoard::*generateMovesFn)(ShortMoveList &moves, SquareSet, Square, Args ...) const noexcept, Move(ChessBoard::*generateSingleMoveFn)(SquareSet, Square, Args ...) const noexcept, SquareSet srcSqMask, Square dstSq, Args &&... args)
Definition chessboard-test-playmove-helper.h:31