Belofte version 2.1.9
A promising chess program using the UCI or Winboard interface
pgnmove.cpp
Go to the documentation of this file.
1/*---------------------------------------------------------------------+
2 * File: pgnmove.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/**
13 * create PGN move based on bMove
14 */
15bPgnMove::bPgnMove(bBoard const& b, bmove_t const bmt)
16 : m_move{}
17 , m_evalstr{}
18{
19 bMoveList ml;
20 ml.generateMoves(b);
21 movenum_t n_moves = ml.getNumberOfMoves();
22 for (movenum_t moveid = 1; moveid <= n_moves; ++moveid) {
23 bMove m = ml[moveid];
24 if (m == bmt) {
25 ctor(b, m);
26 break;
27 }
28 }
29}
30
31void bPgnMove::ctor(bBoard const& b, bMove const& m)
32{
33 std::string piece = bPiece::getPieceStrUpper(b.getPiece(m.from()));
34 movelist_t alternatives;
35
36 if (piece == S_P_KING) {
37 if (m.isCastleMove()) {
38 m_move = "O-O";
39 if (m.isLongCastleMove()) {
40 m_move += "-O";
41 }
42 } else {
43 m_move = piece;
44 }
45 } else if (piece != S_P_PAWN) {
46 m_move = piece;
47
48 /// @todo check why can't we capture alternatives, b ?
49 auto getSiblings = [m](bBoard const& bs) -> movelist_t {
50 movelist_t siblings;
51 bMoveList ml;
52 movenum_t n_moves = ml.generateMoves(bs);
53 for (movenum_t moveid = 1; moveid <= n_moves; ++moveid) {
54 bMove bm(ml[moveid]);
55 if (bm.to() == m.to()) {
56 if (!(bm.from() == m.from())
57 && (bs.getPiece(bm.from()) == bs.getPiece(m.from()))) {
58 // same destination sq, same major piece, not same move
59 siblings.push_back(bm);
60 }
61 }
62 }
63 return siblings;
64 };
65 alternatives = getSiblings(b);
66 }
67
68 if (m.isCapture()) {
69 if (piece == S_P_PAWN) {
70 m_move = (bCase(m.from()).operator std::string()).substr(0,1);
71 }
72 m_move += "x";
73 }
74
75 if (!m.isCastleMove()) {
76 m_move += bCase(m.to()).operator std::string();
77 }
78
79 if (m.isPromotion()) {
80 m_move += getPromotionDecorationStr(m.getPromotion());
81 }
82
83 if (alternatives.size() > 0) {
84 // add column or row or both if multiple moves are possible
85 // with same destination
86 if (std::none_of(alternatives.begin(), alternatives.end(),
87 [m](bMove const& bm)
88 { return bm.fromcolumn() == m.fromcolumn(); })) {
89 // add column descriptor
90 m_move.insert(1, (bCase(m.from()).operator std::string()).substr(0, 1));
91 } else if (std::none_of(alternatives.begin(), alternatives.end(),
92 [m](bMove const& bm)
93 { return bm.fromrank() == m.fromrank(); })) {
94 // add row descriptor
95 m_move.insert(1, (bCase(m.from()).operator std::string()).substr(1, 1));
96 } else {
97 // add from case, both row and column are not unique
98 m_move.insert(1, (bCase(m.from()).operator std::string()));
99 }
100 }
101
102 if (m.isCheck()) {
103 if ((!m.isDrawScore()) && m.isMateMove()) {
104 m_move += "#";
105 } else {
106 m_move += "+";
107 }
108 }
109
110 if (!m_move.size()) throw std::logic_error("empty bPgnMove");
111 m_evalstr = m.getMoveEvalStr();
112}
113
114//-----------------------------------------------------------------------
115
116std::string const bPgnMove::getPromotionDecorationStr(ppiece_t const piece)
117 const
118{
119 if (piece == tPPiece::N_P_QUEEN) {
120 return "=Q";
121 } else if (piece == tPPiece::N_P_KNIGHT) {
122 return "=N";
123 } else if (piece == tPPiece::N_P_ROOK) {
124 return "=R";
125 } else if (piece == tPPiece::N_P_BISHOP) {
126 return "=B";
127 }
128 throw std::logic_error("superfluous call to bPgnMove::getPromotionDecorationStr");
129}
130
131//-----------------------------------------------------------------------
132
134 : m_pmoves{}
135{
136 bMoveList ml;
137 movenum_t n_moves = ml.generateMoves(b);
138 for (movenum_t moveid = 1; moveid <= n_moves; ++moveid) {
139 bPgnMove pm(b, ml[moveid].getBMoveT());
140 m_pmoves.push_back(pm);
141 }
142}
143
144std::ostream& operator<<(std::ostream& os, bPgnMoveList const& mpl)
145{
146 os << "#" << belofte::to_string(static_cast<int64_t>(mpl.m_pmoves.size())) << " ";
147 for (bPgnMove const& m: mpl.m_pmoves) {
148 os << m << m.getMoveEvalStr() << " ";
149 }
150 return os;
151}
152
153// eof
This is the main include file, needs to be included before any other include.
uint32_t bmove_t
Definition belofte.h:98
uint_fast8_t movenum_t
Definition belofte.h:100
constexpr piece_t getPiece(case_t const cf) const
Definition basicboard.h:172
constexpr bool isLongCastleMove() const
Definition basicmove.h:107
constexpr bool isCastleMove() const
Definition basicmove.h:101
constexpr bool isCapture() const
Definition basicmove.h:93
constexpr ppiece_t getPromotion() const
Definition basicmove.h:74
constexpr case_t to() const
Definition basicmove.h:58
constexpr bool isPromotion() const
Definition basicmove.h:82
constexpr bool isCheck() const
Definition basicmove.h:109
constexpr case_t from() const
Definition basicmove.h:56
board
Definition board.h:45
Definition move.h:13
constexpr bool isDrawScore() const
Definition move.h:59
std::string getMoveEvalStr() const
Definition move.cpp:17
bool isMateMove() const
Check if end of game flag is set, and not forced draw.
Definition move.cpp:41
movenum_t generateMoves(bBasicBoard const &b)
generate moves if not yet generated
Definition movelist.cpp:340
constexpr movenum_t getNumberOfMoves() const
Definition movelist.h:34
PgnMove is for user-interface only.
Definition pgnmove.h:14
std::string const & getMoveEvalStr() const
Definition pgnmove.h:35
bPgnMove(bPgnMove const &pm) noexcept
Definition pgnmove.h:16
static const std::string getPieceStrUpper(piece_t const piece)
static class member function
Definition piece.cpp:173
std::vector< bMove > movelist_t
Definition movelist.h:11
std::string to_string(int16_t value)
std::to_string not compatible on Mac OS (Apple LLVM version 5.0) provide generic utility function
Definition util.cpp:171
std::ostream & operator<<(std::ostream &os, bPgnMoveList const &mpl)
Definition pgnmove.cpp:144
enum tPPiece ppiece_t
Definition piece.h:52
#define S_P_PAWN
Definition piece.h:14
#define S_P_KING
Definition piece.h:12
@ N_P_KNIGHT
Definition piece.h:48
@ N_P_QUEEN
Definition piece.h:48
@ N_P_ROOK
Definition piece.h:48
@ N_P_BISHOP
Definition piece.h:48