Belofte version 2.1.9
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 , m_variation{}
46 , m_previousmoves{}
47{
48 calcMinorPieces(true);
50}
51
52#if defined(__GNUC__)
53#pragma GCC diagnostic pop
54#endif
55
56//-----------------------------------------------------------------------
57
58#if defined(__GNUC__)
59#pragma GCC diagnostic push
60#pragma GCC diagnostic ignored "-Wswitch-enum"
61#endif
62
63/**
64 * Recalculate minor pieces, used for evaluation and end of game
65 * condition in case of less than 5 pieces
66 * @param bForceRecalc force to recalculate
67 */
68void bBoard::calcMinorPieces(bool const bForceRecalc)
69{
70 if (!bForceRecalc && noNeedCalcMinorPieces()) return; // no extra calculation cost
71
72 for (auto& v : m_whitePieces) v.clear();
73 for (auto& v : m_blackPieces) v.clear();
74
75 for (case_t iCase = 0; iCase < 64; ++iCase) {
76 piece_t piece = getPiece(iCase);
77 if (piece) {
78 switch (piece) {
79 case tPiece::W_ROOK:
80 m_whitePieces[tStatPiece::STAT_ROOK].push_back(iCase);
81 break;
83 m_whitePieces[tStatPiece::STAT_KNIGHT].push_back(iCase);
84 break;
86 m_whitePieces[tStatPiece::STAT_BISHOP].push_back(iCase);
87 break;
88 case tPiece::W_QUEEN:
89 m_whitePieces[tStatPiece::STAT_QUEEN].push_back(iCase);
90 break;
91 case tPiece::B_ROOK:
92 m_blackPieces[tStatPiece::STAT_ROOK].push_back(iCase);
93 break;
95 m_blackPieces[tStatPiece::STAT_KNIGHT].push_back(iCase);
96 break;
98 m_blackPieces[tStatPiece::STAT_BISHOP].push_back(iCase);
99 break;
100 case tPiece::B_QUEEN:
101 m_blackPieces[tStatPiece::STAT_QUEEN].push_back(iCase);
102 break;
103 //case tPiece::W_PAWN:
104 //case tPiece::B_PAWN:
105 // break;
106 //case tPiece::W_KING:
107 //case tPiece::B_KING:
108 // break;
109 //case tPiece::P_EMPTY:
110 //case tPiece::P_SIZE:
111 // break;
112 default:
113 break;
114 }
115 }
116 }
117
118 m_boardData.s_boardData.whiteminor
119 = static_cast<uint8_t>(m_whitePieces[tStatPiece::STAT_ROOK].size()
120 + m_whitePieces[tStatPiece::STAT_KNIGHT].size()
121 + m_whitePieces[tStatPiece::STAT_BISHOP].size()
122 + m_whitePieces[tStatPiece::STAT_QUEEN].size());
123 m_boardData.s_boardData.blackminor
124 = static_cast<uint8_t>(m_blackPieces[tStatPiece::STAT_ROOK].size()
125 + m_blackPieces[tStatPiece::STAT_KNIGHT].size()
126 + m_blackPieces[tStatPiece::STAT_BISHOP].size()
127 + m_blackPieces[tStatPiece::STAT_QUEEN].size());
128
130}
131
132#if defined(__GNUC__)
133#pragma GCC diagnostic pop
134#endif
135
136/**
137 * calculate stage of game to assist in evaluation
138 */
140{
141 // pre-calculate stage
142 if (pieceCount() > 28) {
143 /// @todo take into account actual moves
144 setGameStage(bGameStage::ST_OPENING);
145 } else if (pieceCount() < 14) {
146 if (noNeedCalcMinorPieces()) {
147 if (m_boardData.s_boardData.whiteminor && m_boardData.s_boardData.blackminor) {
148 // both have at least a minor piece
149 if ((m_boardData.s_boardData.whiteminor + m_boardData.s_boardData.blackminor) < 4)
150 setGameStage(bGameStage::ST_PAWNENDING);
151 else
152 setGameStage(bGameStage::ST_ENDGAME);
153 } else if (m_boardData.s_boardData.whiteminor || m_boardData.s_boardData.blackminor) {
154 // one has minor piece
155 setGameStage(bGameStage::ST_MATING);
156 } else {
157 setGameStage(bGameStage::ST_PAWNENDING);
158 }
159 } else {
160 setGameStage(bGameStage::ST_ENDGAME);
161 }
162 } else {
163 setGameStage(bGameStage::ST_UNSPECIFIED);
164 }
165}
166
167std::string bBoard::getGameStageName() const
168{
169 std::string sStage = "";
170 if (getGameStage() == bGameStage::ST_OPENING) sStage = "Opening";
171 else if (getGameStage() == bGameStage::ST_ENDGAME) sStage = "Endgame";
172 else if (getGameStage() == bGameStage::ST_MATING) sStage = "Mating";
173 else if (getGameStage() == bGameStage::ST_PAWNENDING) sStage = "Pawnending";
174 return sStage;
175}
176
177/**
178 * invert colours
179 * update kingpos, update colour to move, castle rights, ...
180 * @todo castledone, capturedcase, capturedpiece, bmove, eval
181 * @todo epcase
182 */
184{
185 // invert pieces
186 for (column_t iCol = 0; iCol < 8; ++iCol) {
187 for (rank_t iRank = 0; iRank < 4; ++iRank) {
188 piece_t c0 = getPiece(iCol, iRank);
189 piece_t c1 = getPiece(iCol, 7 - iRank);
190 if (c0) { c0 = static_cast<piece_t>((c0 > W_QUEEN) ? c0 - W_QUEEN : c0 + W_QUEEN); }
191 if (c1) { c1 = static_cast<piece_t>((c1 > W_QUEEN) ? c1 - W_QUEEN : c1 + W_QUEEN); }
192 setPieceKU(bCase::coordToCase(iCol, iRank), c1);
193 setPieceKU(bCase::coordToCase(iCol, 7 - iRank), c0);
194 }
195 }
196 // invert castle rights
203 // invert column
204 if (whiteToMove()) incPly();
205 else decPly();
206 // recalculate board data
207 calcHash();
208 calcMinorPieces(true);
209}
210
211/**
212 * modification of board
213 * move is kept on previous board
214 * newboard does not have move stored and has flag to recalculate minor pieces
215 * @todo check usage in case of failure, why not return exception?
216 */
218{
219 setMove(m.getFromTo());
220 boardInfo_t oldBoardInfo = bBasicBoard::applyMove(m);
222 return oldBoardInfo;
223}
224
225//-----------------------------------------------------------------------
226
227void bBoard::setVariation(bBoard const& chldbrd)
228{
229 m_variation = chldbrd.getVariation();
230 if (chldbrd.getPreviousMoves().back() != "")
231 m_variation.insert(m_variation.begin(), chldbrd.getPreviousMoves().back());
232}
233
234//-----------------------------------------------------------------------
235
236/**
237 * print board
238 * @todo add mate condition
239 */
240bBoard::operator std::string() const
241{
242 std::stringstream ss;
243
244 for (rank_t iRank = 0; iRank < 8; ++iRank) {
245 ss << "+---+---+---+---+---+---+---+---+\n";
246 for (column_t iCol = 0; iCol < 8; ++iCol) {
247 ss << "| "
248 << static_cast<char>(bPiece::getPieceChar(getPiece(iCol, 7 - iRank)))
249 << " ";
250 }
251 ss << "|\n";
252 }
253 ss << "+---+---+---+---+---+---+---+---+\n";
254
255 ss << "Move " << getMoveNumber() << " - "
256 << (whiteToMove() ? "White" : "Black") << " to move"
257 << "\n";
258
259 ss << "Castling : ";
260 for (uint8_t i = 0; i < 4; ++i) ss << (hasCastleRights(static_cast<uint8_t>(1 << i)) ? "1" : "-");
261 if (isEpSet()) ss << " E.p. " << bCase(getEp());
262 if (isNonSilent() || isInCheck())
263 ss << " QS:" << (isInCheck() ? " Check" : "")
264 << (getCapturedPiece() ? " Capture" : "");
265
266 if (getGameStageName() != "") ss << " - " << getGameStageName();
267
268 return ss.str();
269}
270
271/**
272 * print board
273 */
274std::ostream& operator<<(std::ostream& os, bBoard const& bd)
275{
276 os << bd.operator std::string();
277 os << std::endl;
278 return os;
279}
280
281// 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:94
int8_t column_t
Definition belofte.h:95
uint8_t case_t
Definition belofte.h:96
std::ostream & operator<<(std::ostream &os, bBoard const &bd)
print board
Definition board.cpp:274
@ 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:172
constexpr bool isNonSilent() const
Definition basicboard.h:139
constexpr bool whiteToMove() const
Definition basicboard.h:156
void incPly()
Definition basicboard.h:80
constexpr int16_t getMoveNumber() const
Definition basicboard.h:160
constexpr bool hasCastleRights(uint8_t const f) const
Definition basicboard.h:113
virtual boardInfo_t applyMove(bMove const &m)
play game move on board
constexpr case_t getEp() const
Definition basicboard.h:91
void decPly()
Definition basicboard.h:82
constexpr bool isEpSet() const
Definition basicboard.h:89
constexpr int8_t pieceCount() const
Definition basicboard.h:221
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:132
void setCastleRights(uint8_t const f)
void setPieceKU(case_t const cf, piece_t const piece)
Definition basicboard.h:253
constexpr piece_t getCapturedPiece() const
Definition basicboard.h:146
constexpr fromto_t getFromTo() const
Definition basicmove.h:70
void setNeedCalcMinorPieces()
Definition board.h:71
void invertColours()
invert colours update kingpos, update colour to move, castle rights, ...
Definition board.cpp:183
void setVariation(bBoard const &chldbrd)
Definition board.cpp:227
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:217
void calcMinorPieces(bool const bForceRecalc=false)
Recalculate minor pieces, used for evaluation and end of game condition in case of less than 5 pieces...
Definition board.cpp:68
void clearNeedCalcMinorPieces()
Definition board.h:73
constexpr bool noNeedCalcMinorPieces() const
Definition board.h:69
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:82
movesequence_t const & getPreviousMoves() const
Definition board.h:85
movesequence_t const & getVariation() const
Definition board.h:89
std::string getGameStageName() const
Definition board.cpp:167
void calcGameStage()
calculate stage of game to assist in evaluation
Definition board.cpp:139
constexpr bGameStage getGameStage() const
Definition board.h:59
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