Chess Engine
C++ chess engine with movegen, bitboards, and Arduino-friendly docs
Loading...
Searching...
No Matches
interactive_helpers.cpp
Go to the documentation of this file.
2#include <cstdio>
3#include <cstring>
4#include <cctype>
7#include "../move/make_move.h"
8#include "notation.h"
9
10int ParseSquare2(const char* s) {
11 if (!s) return -1;
12 while (*s == ' ') ++s;
13 if (s[0] < 'a' || s[0] > 'h' || s[1] < '1' || s[1] > '8') return -1;
14 const int file = s[0] - 'a';
15 const int rank = s[1] - '1';
16 return FR2SQ(file, rank);
17}
18
19int ParsePromotionPiece(char c, int side) {
20 if (!c) return EMPTY;
21 c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
22 switch (c) {
23 case 'q': return side == WHITE ? wQ : bQ;
24 case 'r': return side == WHITE ? wR : bR;
25 case 'b': return side == WHITE ? wB : bB;
26 case 'n': return side == WHITE ? wN : bN;
27 default: return EMPTY;
28 }
29}
30
31int LegalMovesFrom(S_BOARD* pos, int from,
32 int outMoves[], char labels[][8], int maxOut) {
33 S_MOVELIST list[1];
34 generateAllMoves(pos, list);
35
36 int count = 0;
37 for (int i = 0; i < list->count && count < maxOut; ++i) {
38 const int m = list->moves[i].move;
39 if (FROMSQ(m) != from) continue;
40
41 if (makeMove(pos, m) == TRUE) {
42 takeMove(pos);
43
44 const int to = TOSQ(m);
45 const int prom = PROMOTED(m);
46 if (prom == EMPTY) {
47 std::snprintf(labels[count], 8, "%s", squareToString(to));
48 } else {
49 char pc = 'Q';
50 switch (prom) {
51 case wQ: case bQ: pc = 'Q'; break;
52 case wR: case bR: pc = 'R'; break;
53 case wB: case bB: pc = 'B'; break;
54 case wN: case bN: pc = 'N'; break;
55 }
56 std::snprintf(labels[count], 8, "%s=%c", squareToString(to), pc);
57 }
58 outMoves[count++] = m;
59 }
60 }
61 return count;
62}
63
64int MatchDestinationMove(S_BOARD* pos, int from,
65 const char* destStr, const int legalMoves[], int nMoves) {
66 if (!destStr) return NOMOVE;
67
68 char dst[8] = {0};
69 int di = 0;
70 while (destStr[di] && destStr[di] != '\n' && di < 7) { dst[di] = destStr[di]; ++di; }
71 dst[di] = 0;
72
73 char* eq = std::strchr(dst, '=');
74 char promChar = 0;
75 if (eq) {
76 if (eq[1]) promChar = eq[1];
77 *eq = '\0';
78 } else if (di >= 3) {
79 const char tail = dst[2];
80 if (tail=='Q'||tail=='q'||tail=='R'||tail=='r'||tail=='B'||tail=='b'||tail=='N'||tail=='n') {
81 promChar = tail;
82 dst[2] = '\0';
83 }
84 }
85
86 const int to = ParseSquare2(dst);
87 if (to == -1) return NOMOVE;
88
89 int cand[8];
90 int candN = 0;
91 for (int i = 0; i < nMoves && candN < 8; ++i) {
92 const int m = legalMoves[i];
93 if (FROMSQ(m) == from && TOSQ(m) == to) {
94 cand[candN++] = m;
95 }
96 }
97 if (candN == 0) return NOMOVE;
98 if (candN == 1) {
99 const int m = cand[0];
100 if (PROMOTED(m) != EMPTY && promChar == 0) {
101 for (int i = 0; i < candN; ++i) {
102 const int pm = cand[i];
103 const int pr = PROMOTED(pm);
104 if (pr == (pos->side == WHITE ? wQ : bQ)) return pm;
105 }
106 }
107 return m;
108 }
109
110 if (promChar) {
111 const int want = ParsePromotionPiece(promChar, pos->side);
112 if (want != EMPTY) {
113 for (int i = 0; i < candN; ++i) {
114 if (PROMOTED(cand[i]) == want) return cand[i];
115 }
116 }
117 }
118
119 for (int i = 0; i < candN; ++i) {
120 const int pr = PROMOTED(cand[i]);
121 if (pr == (pos->side == WHITE ? wQ : bQ)) return cand[i];
122 }
123 return cand[0];
124}
#define FR2SQ(f, r)
Definition defs.h:181
#define TOSQ(m)
Definition defs.h:165
@ bQ
Definition defs.h:40
@ wN
Definition defs.h:40
@ EMPTY
Definition defs.h:40
@ bN
Definition defs.h:40
@ wR
Definition defs.h:40
@ bR
Definition defs.h:40
@ bB
Definition defs.h:40
@ wB
Definition defs.h:40
@ wQ
Definition defs.h:40
@ WHITE
Definition defs.h:44
#define NOMOVE
Definition defs.h:176
#define FROMSQ(m)
Definition defs.h:164
#define PROMOTED(m)
Definition defs.h:167
@ TRUE
Definition defs.h:57
int ParseSquare2(const char *s)
Parse "e2" style coordinate into a 120-based square index.
int LegalMovesFrom(S_BOARD *pos, int from, int outMoves[], char labels[][8], int maxOut)
Build list of legal moves that originate from from.
int ParsePromotionPiece(char c, int side)
Map promotion char ('q','r','b','n') to a piece code for the given side. Case-insensitive....
int MatchDestinationMove(S_BOARD *pos, int from, const char *destStr, const int legalMoves[], int nMoves)
Resolve a destination string ("e4", "e8=Q", "e8q") to a move.
int makeMove(S_BOARD *board, int move)
Make a move; returns non-zero if legal (king not left in check).
void takeMove(S_BOARD *board)
Undo the last made move.
void generateAllMoves(const S_BOARD *board, S_MOVELIST *moveList)
Generate all pseudo-legal moves for the side to move.
char * squareToString(const int square)
Convert a board square index to algebraic notation.
Definition notation.cpp:7
int side
Definition defs.h:107
int move
Definition defs.h:62
int count
Definition defs.h:68
S_MOVE moves[MAXPOSITIONMOVES]
Definition defs.h:67