libscid 0.1.0
Chess applications made easy.
Loading...
Searching...
No Matches
fullmove.h
Go to the documentation of this file.
1
4#pragma once
5
6#include "scid/core/board.h"
7
8#include <cassert>
9#include <cstdint>
10#include <string>
11
12namespace scid::core {
13
14class FullMove {
15 // ** Lower 16 bits are compatible with Stockfish's Move **
16 // bits 0- 5: destination square (from 0 to 63)
17 // bits 6-11: origin square (from 0 to 63)
18 // bits 12-13: promotion piece type -2 (from QUEEN-2 to KNIGHT-2)
19 // bits 14-15: special move flag: promotion (1), en passant (2), castling (3)
20
21 // ** Info for undoing the move **
22 // bits 16-17: castling flags - TODO
23 // bits 18-20: enpassant file - TODO
24 // bits 21-23: captured pieceT
25
26 // ** Info for direct SAN conversion **
27 // bits 24-26: moving pieceT
28 // bit 27: black to move
29 // bit 28: ambiguous move, insert from fyle
30 // bit 29: ambiguous move, insert from rank
31 // bit 30: check
32
33 // ** TODO: Use this flag to embed tags, variations, etc.. in a move stream
34 // bit 31: special flag
35 std::uint32_t m_;
36
37public:
38 constexpr FullMove(std::uint32_t m = 0) : m_(m){};
39
40 FullMove(colorT c, squareT kingSq, squareT rookSq)
41 // Castle: encoding as king to rook allows the undoing of chess360 moves
42 : FullMove(c, kingSq, rookSq, KING) {
43 m_ |= (3 << 14);
44 }
45
46 FullMove(colorT c, squareT from, squareT to, pieceT pt) {
47 m_ = to | (from << 6) | (pt << 24) | (c << 27);
48 }
49
50 bool operator==(FullMove const& f) const { return m_ == f.m_; }
51
52 // Special moves:
53 // NONE: encoded as 0 (from 0 to 0);
54 // NULL: encoded as 65 (from 1 to 1);
55 // PROMO: encoded setting the special move flag to 1
56 // ENPASSANT: encoded setting the special move flag to 2
57 // CASTLING: encoded setting the special move flag to 3, from is the square
58 // of the king and to is the square of the rook.
59 // If from < to it is castling king side.
60 explicit operator bool() const { return m_ != 0; }
61 bool isNull() const { return m_ == 0b01000001; }
62 bool isPromo() const { return (m_ & (3 << 14)) == (1 << 14); }
63 bool isEnpassant() const { return (m_ & (3 << 14)) == (2 << 14); }
64 bool isCastle() const { return (m_ & (3 << 14)) == (3 << 14); }
65
66 squareT getTo() const { return m_ & 0x3F; }
67 squareT getFrom() const { return (m_ >> 6) & 0x3F; }
68 pieceT getPiece() const { return (m_ >> 24) & 0x07; }
69 colorT getColor() const { return (m_ >> 27 & 1) ? BLACK : WHITE; }
70 pieceT getPromo() const { return ((m_ >> 12) & 0x03) +2; }
71 pieceT getCaptured() const { return (m_ >> 21) & 0x07; }
72 std::string getSAN() const {
73 std::string res;
74 const auto to = getTo();
75 const auto from = getFrom();
76 if (to == 0 && from == 0) return "--";
77 if (isCastle()) {
78 res = (to > from) ? "O-O" : "O-O-O";
79 bool check = (m_ >> 30) & 1;
80 if (check)
81 res += "+";
82 return res;
83 }
84 bool fromFyle = (m_ >> 28) & 1;
85 bool fromRank = (m_ >> 29) & 1;
86 bool check = (m_ >> 30) & 1;
87 bool capture = (getCaptured() != 0);
88
89 switch (getPiece()) {
90 case BISHOP: res += "B"; break;
91 case KNIGHT: res += "N"; break;
92 case ROOK: res += "R"; break;
93 case QUEEN: res += "Q"; break;
94 case KING: res += "K"; break;
95 default: //PAWN
96 if (capture) res += 'a' + (from % 8);
97 }
98 if (fromFyle) res += 'a' + (from % 8);
99 if (fromRank) res += '1' + (from / 8);
100 if (capture) res += "x";
101 res += 'a' + (to % 8);
102 res += '1' + (to / 8);
103 if (isPromo()) {
104 switch (getPromo()) {
105 case BISHOP: res += "=B"; break;
106 case KNIGHT: res += "=N"; break;
107 case ROOK: res += "=R"; break;
108 case QUEEN: res += "=Q"; break;
109 }
110 }
111 if (check) res += "+";
112 return res;
113 }
114
115 void setPromo(pieceT promo) {
116 assert(promo == QUEEN || promo == ROOK || promo == BISHOP ||
117 promo == KNIGHT);
118 m_ |= ((promo - 2) << 12) | (1 << 14);
119 }
120 void setCapture(pieceT piece, bool enPassant) {
121 m_ |= ((piece & 0x07) << 21);
122 if (enPassant) m_ |= (2 << 14);
123 }
124 void setAmbiguity(bool fyle, bool rank) {
125 m_ &= ~(3 << 28);
126 if (fyle)
127 m_ |= (1 << 28);
128 if (rank)
129 m_ |= (1 << 29);
130 }
131 void setCheck() { m_ |= (1 << 30); }
132};
133
134
135} // namespace scid::core
Chess board constants, piece helpers, square geometry, and directions.
Definition fullmove.h:14