-
Notifications
You must be signed in to change notification settings - Fork 1
/
chess_move.h
155 lines (112 loc) · 4.89 KB
/
chess_move.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#ifndef CHESS_MOVE_H
#define CHESS_MOVE_H
#include <string>
#include <vector>
#include <optional>
#include <iosfwd>
#include "castling_type.h"
#include "piece_type.h"
#include "square.h"
/// A chess move, e.g. 'e4'
// Call it 'chess_move' instead of 'move' to avoid conflicts with 'std::move'
class chess_move
{
public:
/// Need to now the player's color, e.g. for 'O-O-O' or '1-0'
explicit chess_move(std::string pgn_str, const chess_color color);
/// Get the castling type.
/// Will be empty if this move is not a promotion
const auto& get_castling_type() const noexcept { return m_castling_type; };
/// Get the color of the player that did this move
const auto& get_color() const noexcept { return m_color; };
/// Get the original PGN string back
const auto& get_pgn_str() const noexcept { return m_pgn_str; }
/// Get the promotion type.
/// Will be empty if this move is not a promotion
const auto& get_promotion_type() const noexcept { return m_promotion_type; };
/// Get the target square, e.g. 'e4' in 'Pxe4'.
/// Result will be empty when castling (e.g. 'O-O') or winning (e.g. '1-0')
/// @see use the free function \link{get_from} to determine the
/// square where the pieces comes from
const auto& get_to() const noexcept { return m_to; }
/// The type of chess piece.
/// Result will be empty when castling (e.g. 'O-O') or winning (e.g. '1-0')
const auto& get_type() const noexcept { return m_type; }
/// Get the winner.
/// * If this is empty, the game is still on-going.
/// * If this has 1 element, that color is the winner.
/// * If this has 2 elements, the game ended in a draw.
const auto& get_winner() const noexcept { return m_winner; }
/// Is this move a capture?
/// E.g. 'Qxf7' is a capture
bool is_capture() const noexcept { return m_is_capture; }
private:
/// The type of castling. Empty if move is not a castling
std::optional<castling_type> m_castling_type;
chess_color m_color;
bool m_is_capture;
/// The original PGN string
std::string m_pgn_str;
/// The type of piece a pawn promotes into.
/// Empty if move is not a promotion
std::optional<piece_type> m_promotion_type;
std::optional<square> m_to;
std::optional<piece_type> m_type;
/// Can be
/// * No winner yet: empty
/// * One winner: one element
/// * Draw: two elements
std::vector<chess_color> m_winner;
};
/// Get the square the piece doing the move came from.
/// Even with, e.g., castling, it is the king at e1 that
/// needed to be selected to do that move
square get_from(const game& g, const chess_move& m);
/// Get the square the bishop doing the move came from.
square get_from_for_bishop(const game& g, const chess_move& m);
/// Get the square the king doing the move came from.
/// Even with, e.g., castling for white, it is the king at e1 that
/// needed to be selected to do that move
square get_from_for_king(const game& g, const chess_move& m);
/// Get the square the knight doing the move came from.
square get_from_for_knight(const game& g, const chess_move& m);
/// Get the square the pawn doing the move came from.
square get_from_for_pawn(const game& g, const chess_move& m);
/// Get the square the queen doing the move came from.
square get_from_for_queen(const game& g, const chess_move& m);
/// Get the square the rook doing the move came from.
square get_from_for_rook(const game& g, const chess_move& m);
/// Get the square from a string
/// E.g. 'Nc3' will result in 'c3'
square get_square(const std::string& pgn_str);
/// Get a piece type for a string
/// E.g. 'Nc3' will result in a knight, 'e4' will result in a pawn
piece_type get_piece_type(const std::string& pgn_str);
/// Get the type the piece is promoted to.
/// Will be empty if this is no promotion
std::optional<piece_type> get_promotion_type(const std::string& pgn_str);
/// Get the winner from a notation.
/// Assumes a win ('1-0' or '0-1') or a draw ('1/2-1/2').
std::vector<chess_color> get_winner(const std::string& pgn_str);
/// Conclude if the move is a capture from a PGN string
/// E.g. 'Nxc3' will result in true
bool is_capture(const std::string& pgn_str);
/// Get if the move is a capture
bool is_capture(const chess_move& move) noexcept;
/// Get if the move is a castling
bool is_castling(const chess_move& move) noexcept;
/// Get if the move is a win
bool is_draw(const chess_move& move) noexcept;
/// Get if the move is a move,
/// i.e. if it moves one piece, without a capture,
/// no castling, no promotion, no win and no draw
bool is_simple_move(const chess_move& move) noexcept;
/// Get if the move is a promotion
bool is_promotion(const chess_move& move) noexcept;
/// Get if the move is a win
bool is_win(const chess_move& move) noexcept;
/// Test this class and its free functions
void test_chess_move();
bool operator==(const chess_move& lhs, const chess_move& rhs) noexcept;
std::ostream& operator<<(std::ostream& os, const chess_move& m) noexcept;
#endif // CHESS_MOVE_H