Belofte version 2.2.0
A promising chess program using the UCI or Winboard interface
board.cpp
Go to the documentation of this file.
1/*---------------------------------------------------------------------+
2 * File: board.cpp
3 * Project: part of belofte - A Promising Chess Program
4 * Author: yves
5 * SPDX-License-Identifier: GPL-2.0-only
6+----------------------------------------------------------------------*/
7
8#include "belofte.h"
9
10//-----------------------------------------------------------------------
11
12#if defined(__GNUC__)
13#pragma GCC diagnostic push
14#pragma GCC diagnostic ignored "-Weffc++"
15#endif
16
17/**
18 * Copy board with limited board data, no board history
19 */
21 : bBasicBoard(b)
22 , m_boardData{b.m_boardData.u_boardData}
23{
24}
25
26/**
27 * Create copy of board with limited board data and history
28 * @param b existing board
29 * @param m move to be added to history
30 */
32 : bBasicBoard{b}
33 , m_boardData{b.m_boardData.u_boardData}
34 , m_previousmoves{b.getPreviousMoves()}
35{
36 m_previousmoves.emplace_back(m);
37}
38
39/**
40 * used by setFENInitialPos
41 */
43 : bBasicBoard(fen)
44 , m_boardData{0ULL}
45{
46 calcMinorPieces(true);
48}
49
50#if defined(__GNUC__)
51#pragma GCC diagnostic pop
52#endif
53
54//-----------------------------------------------------------------------
55
56#if defined(__GNUC__)
57#pragma GCC diagnostic push
58#pragma GCC diagnostic ignored "-Wswitch-enum"
59#endif
60
61/**
62 * Recalculate minor pieces, used for evaluation and end of game
63 * condition in case of less than 5 pieces
64 * @param bForceRecalc force to recalculate
65 */
66void bBoard::calcMinorPieces(bool const bForceRecalc)
67{
68 if (!bForceRecalc && noNeedCalcMinorPieces()) return; // no extra calculation cost
69
70 for (auto& v : m_whitePieces) v.clear();
71 for (auto& v : m_blackPieces) v.clear();
72
73 for (case_t iCase = 0; iCase < 64; ++iCase) {
74 piece_t piece = getPiece(iCase);
75 if (piece) {
76 switch (piece) {
77 case tPiece::W_ROOK:
78 m_whitePieces[tStatPiece::STAT_ROOK].push_back(iCase);
79 break;
81 m_whitePieces[tStatPiece::STAT_KNIGHT].push_back(iCase);
82 break;
84 m_whitePieces[tStatPiece::STAT_BISHOP].push_back(iCase);
85 break;
86 case tPiece::W_QUEEN:
87 m_whitePieces[tStatPiece::STAT_QUEEN].push_back(iCase);
88 break;
89 case tPiece::B_ROOK:
90 m_blackPieces[tStatPiece::STAT_ROOK].push_back(iCase);
91 break;
93 m_blackPieces[tStatPiece::STAT_KNIGHT].push_back(iCase);
94 break;
96 m_blackPieces[tStatPiece::STAT_BISHOP].push_back(iCase);
97 break;
98 case tPiece::B_QUEEN:
99 m_blackPieces[tStatPiece::STAT_QUEEN].push_back(iCase);
100 break;
101 //case tPiece::W_PAWN:
102 //case tPiece::B_PAWN:
103 // break;
104 //case tPiece::W_KING:
105 //case tPiece::B_KING:
106 // break;
107 //case tPiece::P_EMPTY:
108 //case tPiece::P_SIZE:
109 // break;
110 default:
111 break;
112 }
113 }
114 }
115
116 m_boardData.s_boardData.whiteminor
117 = static_cast<uint8_t>(m_whitePieces[tStatPiece::STAT_ROOK].size()
118 + m_whitePieces[tStatPiece::STAT_KNIGHT].size()
119 + m_whitePieces[tStatPiece::STAT_BISHOP].size()
120 + m_whitePieces[tStatPiece::STAT_QUEEN].size());
121 m_boardData.s_boardData.blackminor
122 = static_cast<uint8_t>(m_blackPieces[tStatPiece::STAT_ROOK].size()
123 + m_blackPieces[tStatPiece::STAT_KNIGHT].size()
124 + m_blackPieces[tStatPiece::STAT_BISHOP].size()
125 + m_blackPieces[tStatPiece::STAT_QUEEN].size());
126
128}
129
130#if defined(__GNUC__)
131#pragma GCC diagnostic pop
132#endif
133
134/**
135 * calculate stage of game to assist in evaluation
136 */
138{
139 // pre-calculate stage
140 if (pieceCount() > 28) {
141 /// @todo take into account actual moves
142 setGameStage(bGameStage::ST_OPENING);
143 } else if (pieceCount() < 14) {
144 if (noNeedCalcMinorPieces()) {
145 if (m_boardData.s_boardData.whiteminor && m_boardData.s_boardData.blackminor) {
146 // both have at least a minor piece
147 if ((m_boardData.s_boardData.whiteminor + m_boardData.s_boardData.blackminor) < 4)
148 setGameStage(bGameStage::ST_PAWNENDING);
149 else
150 setGameStage(bGameStage::ST_ENDGAME);
151 } else if (m_boardData.s_boardData.whiteminor || m_boardData.s_boardData.blackminor) {
152 // one has minor piece
153 setGameStage(bGameStage::ST_MATING);
154 } else {
155 setGameStage(bGameStage::ST_PAWNENDING);
156 }
157 } else {
158 setGameStage(bGameStage::ST_ENDGAME);
159 }
160 } else {
161 setGameStage(bGameStage::ST_UNSPECIFIED);
162 }
163}
164
165std::string bBoard::getGameStageName() const
166{
167 std::string sStage;
168 if (getGameStage() == bGameStage::ST_OPENING) sStage = "Opening";
169 else if (getGameStage() == bGameStage::ST_ENDGAME) sStage = "Endgame";
170 else if (getGameStage() == bGameStage::ST_MATING) sStage = "Mating";
171 else if (getGameStage() == bGameStage::ST_PAWNENDING) sStage = "Pawnending";
172 return sStage;
173}
174
175/**
176 * invert colours
177 * update kingpos, update colour to move, castle rights, ...
178 * @todo castledone, capturedcase, capturedpiece, bmove, eval
179 * @todo epcase
180 */
182{
183 // invert pieces
184 for (column_t iCol = 0; iCol < 8; ++iCol) {
185 for (rank_t iRank = 0; iRank < 4; ++iRank) {
186 piece_t c0 = getPiece(iCol, iRank);
187 piece_t c1 = getPiece(iCol, 7 - iRank);
188 if (c0) { c0 = static_cast<piece_t>((c0 > W_QUEEN) ? c0 - W_QUEEN : c0 + W_QUEEN); }
189 if (c1) { c1 = static_cast<piece_t>((c1 > W_QUEEN) ? c1 - W_QUEEN : c1 + W_QUEEN); }
190 setPieceKU(bCase::coordToCase(iCol, iRank), c1);
191 setPieceKU(bCase::coordToCase(iCol, 7 - iRank), c0);
192 }
193 }
194 // invert castle rights
201 // invert column
202 if (whiteToMove()) incPly();
203 else decPly();
204 // recalculate board data
205 calcHash();
206 calcMinorPieces(true);
207}
208
209/**
210 * modification of board
211 * move is kept on previous board
212 * newboard does not have move stored and has flag to recalculate minor pieces
213 * @todo check usage in case of failure, why not return exception?
214 */
216{
217 setMove(m.getFromTo());
218 boardInfo_t oldBoardInfo = bBasicBoard::applyMove(m);
220 return oldBoardInfo;
221}
222
223//-----------------------------------------------------------------------
224
225void bBoard::setVariation(bBoard const& chldbrd)
226{
227 m_variation = chldbrd.getVariation();
228 if (chldbrd.getPreviousMoves().back() != "")
229 m_variation.insert(m_variation.begin(), chldbrd.getPreviousMoves().back());
230}
231
232//-----------------------------------------------------------------------
233
234/**
235 * print board
236 * @todo add mate condition
237 */
238bBoard::operator std::string() const
239{
240 std::stringstream ss;
241
242 for (rank_t iRank = 0; iRank < 8; ++iRank) {
243 ss << "+---+---+---+---+---+---+---+---+\n";
244 for (column_t iCol = 0; iCol < 8; ++iCol) {
245 ss << "| "
246 << static_cast<char>(bPiece::getPieceChar(getPiece(iCol, 7 - iRank)))
247 << " ";
248 }
249 ss << "|\n";
250 }
251 ss << "+---+---+---+---+---+---+---+---+\n";
252
253 ss << "Move " << getMoveNumber() << " - "
254 << (whiteToMove() ? "White" : "Black") << " to move"
255 << "\n";
256
257 ss << "Castling : ";
258 for (uint8_t i = 0; i < 4; ++i) ss << (hasCastleRights(static_cast<uint8_t>(1 << i)) ? "1" : "-");
259 if (isEpSet()) ss << " E.p. " << bCase(getEp());
260 if (isNonSilent() || isInCheck())
261 ss << " QS:" << (isInCheck() ? " Check" : "")
262 << (getCapturedPiece() ? " Capture" : "");
263
264 if (getGameStageName() != "") ss << " - " << getGameStageName();
265
266 return ss.str();
267}
268
269/**
270 * print board
271 */
272std::ostream& operator<<(std::ostream& os, bBoard const& bd)
273{
274 os << bd.operator std::string() << "\n";
275 return os;
276}
277
278// eof
union boardInfo boardInfo_t
@ BCASTLE_L
Definition basicboard.h:14
@ BCASTLE_S
Definition basicboard.h:14
@ WCASTLE_S
Definition basicboard.h:14
@ WCASTLE_L
Definition basicboard.h:14
This is the main include file, needs to be included before any other include.
int8_t rank_t
Definition belofte.h:97
int8_t column_t
Definition belofte.h:98
uint8_t case_t
Definition belofte.h:99
std::ostream & operator<<(std::ostream &os, bBoard const &bd)
print board
Definition board.cpp:272
@ ST_MATING
Definition board.h:15
@ ST_PAWNENDING
Definition board.h:15
@ ST_UNSPECIFIED
Definition board.h:14
@ ST_OPENING
Definition board.h:15
@ ST_ENDGAME
Definition board.h:15
constexpr piece_t getPiece(case_t const cf) const
Definition basicboard.h:178
constexpr bool isNonSilent() const
Definition basicboard.h:145
constexpr bool whiteToMove() const
Definition basicboard.h:162
void incPly()
Definition basicboard.h:86
constexpr int16_t getMoveNumber() const
Definition basicboard.h:166
constexpr bool hasCastleRights(uint8_t const f) const
Definition basicboard.h:119
virtual boardInfo_t applyMove(bMove const &m)
play game move on board
constexpr case_t getEp() const
Definition basicboard.h:97
void decPly()
Definition basicboard.h:88
constexpr bool isEpSet() const
Definition basicboard.h:95
constexpr int8_t pieceCount() const
Definition basicboard.h:227
void calcHash()
Set hash based on board position, also calc pieces Byte 0: bits 4-6 capture count (masked) bit 7 play...
constexpr bool isInCheck() const
Definition basicboard.h:138
void setCastleRights(uint8_t const f)
void setPieceKU(case_t const cf, piece_t const piece)
Definition basicboard.h:259
constexpr piece_t getCapturedPiece() const
Definition basicboard.h:152
constexpr fromto_t getFromTo() const
Definition basicmove.h:70
void setNeedCalcMinorPieces()
Definition board.h:80
void invertColours()
invert colours update kingpos, update colour to move, castle rights, ...
Definition board.cpp:181
void calcMinorPieces(bool const bForceRecalc)
Recalculate minor pieces, used for evaluation and end of game condition in case of less than 5 pieces...
Definition board.cpp:66
void setVariation(bBoard const &chldbrd)
Definition board.cpp:225
boardInfo_t applyMove(bMove const &m) override
modification of board move is kept on previous board newboard does not have move stored and has flag ...
Definition board.cpp:215
void clearNeedCalcMinorPieces()
Definition board.h:82
constexpr bool noNeedCalcMinorPieces() const
Definition board.h:78
bBoard(bBoard const &b)
Copy board with limited board data, no board history.
Definition board.cpp:20
void setMove(bmove_t const bmt)
Definition board.h:91
movesequence_t const & getPreviousMoves() const
Definition board.h:94
movesequence_t const & getVariation() const
Definition board.h:98
std::string getGameStageName() const
Definition board.cpp:165
void calcGameStage()
calculate stage of game to assist in evaluation
Definition board.cpp:137
constexpr bGameStage getGameStage() const
Definition board.h:68
position on board, defined as 255 if invalid used primarily to compose a move or a source or destinat...
Definition case.h:18
static constexpr case_t coordToCase(column_t const c, rank_t const r)
Definition case.h:51
FEN string.
Definition fen.h:14
Definition move.h:13
static cpiece_t getPieceChar(piece_t const piece)
static class member function
Definition piece.cpp:219
@ W_KNIGHT
Definition piece.h:39
@ B_BISHOP
Definition piece.h:40
@ W_ROOK
Definition piece.h:39
@ B_ROOK
Definition piece.h:40
@ W_QUEEN
Definition piece.h:39
@ B_KNIGHT
Definition piece.h:40
@ B_QUEEN
Definition piece.h:40
@ W_BISHOP
Definition piece.h:39
enum tPiece piece_t
Definition piece.h:44
@ STAT_KNIGHT
Definition piece.h:55
@ STAT_BISHOP
Definition piece.h:55
@ STAT_ROOK
Definition piece.h:55
@ STAT_QUEEN
Definition piece.h:55