| 47 #define MISSING_CHECKMATE 9 |
47 #define MISSING_CHECKMATE 9 |
| 48 #define INVALID_CHECK 10 |
48 #define INVALID_CHECK 10 |
| 49 #define INVALID_CHECKMATE 11 |
49 #define INVALID_CHECKMATE 11 |
| 50 #define RULES_VIOLATED 32 |
50 #define RULES_VIOLATED 32 |
| 51 |
51 |
| |
52 #if __STDC_VERSION__ < 202310L |
| |
53 /* since #warning is also a C23 feature, the only hope is this: */ |
| |
54 #pragma GCC warning "Type safety for enums is only available since C23" |
| |
55 #define enum_uint8_t(name) enum e##name |
| |
56 #define typedef_enum_uint8_t(name) typedef uint8_t name |
| |
57 #else |
| |
58 #define enum_uint8_t(name) enum e##name : uint8_t |
| |
59 #define typedef_enum_uint8_t(name) typedef enum e##name name |
| |
60 #endif |
| |
61 |
| 52 #define ENPASSANT_THREAT 0x40u |
62 #define ENPASSANT_THREAT 0x40u |
| 53 |
63 |
| 54 #define WHITE 0x10u |
64 enum_uint8_t(Color) { |
| 55 #define BLACK 0x20u |
65 WHITE = 0x10u, |
| 56 #define opponent_color(color) ((color)==WHITE?BLACK:WHITE) |
66 BLACK = 0x20u, |
| |
67 }; |
| |
68 typedef_enum_uint8_t(Color); |
| |
69 |
| |
70 static inline Color opponent_color(Color color) { |
| |
71 return color == WHITE ? BLACK : WHITE; |
| |
72 } |
| 57 |
73 |
| 58 #define PIECE_MASK 0x0Fu |
74 #define PIECE_MASK 0x0Fu |
| 59 #define COLOR_MASK 0x30u |
75 #define COLOR_MASK 0x30u |
| 60 |
76 |
| 61 #define PAWN 0x01u |
77 #define PAWN 0x01u |
| 63 #define KNIGHT 0x03u |
79 #define KNIGHT 0x03u |
| 64 #define BISHOP 0x04u |
80 #define BISHOP 0x04u |
| 65 #define QUEEN 0x05u |
81 #define QUEEN 0x05u |
| 66 #define KING 0x06u |
82 #define KING 0x06u |
| 67 |
83 |
| 68 #define WPAWN (WHITE|PAWN) |
84 enum_uint8_t(Piece) { |
| 69 #define WROOK (WHITE|ROOK) |
85 WPAWN = WHITE|PAWN, |
| 70 #define WKNIGHT (WHITE|KNIGHT) |
86 WROOK = WHITE|ROOK, |
| 71 #define WBISHOP (WHITE|BISHOP) |
87 WKNIGHT = WHITE|KNIGHT, |
| 72 #define WQUEEN (WHITE|QUEEN) |
88 WBISHOP = WHITE|BISHOP, |
| 73 #define WKING (WHITE|KING) |
89 WQUEEN = WHITE|QUEEN, |
| 74 #define BPAWN (BLACK|PAWN) |
90 WKING = WHITE|KING, |
| 75 #define BROOK (BLACK|ROOK) |
91 BPAWN = BLACK|PAWN, |
| 76 #define BKNIGHT (BLACK|KNIGHT) |
92 BROOK = BLACK|ROOK, |
| 77 #define BBISHOP (BLACK|BISHOP) |
93 BKNIGHT = BLACK|KNIGHT, |
| 78 #define BQUEEN (BLACK|QUEEN) |
94 BBISHOP = BLACK|BISHOP, |
| 79 #define BKING (BLACK|KING) |
95 BQUEEN = BLACK|QUEEN, |
| |
96 BKING = BLACK|KING, |
| |
97 }; |
| |
98 typedef_enum_uint8_t(Piece); |
| |
99 |
| |
100 #define POS_UNSPECIFIED 255u |
| |
101 enum_uint8_t(Row) { |
| |
102 RANK_1 = 0, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, |
| |
103 RANK_UNSPECIFIED = POS_UNSPECIFIED |
| |
104 }; |
| |
105 typedef_enum_uint8_t(Row); |
| |
106 |
| |
107 enum_uint8_t(File) { |
| |
108 FILE_A = 0, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H, |
| |
109 FILE_UNSPECIFIED = POS_UNSPECIFIED |
| |
110 }; |
| |
111 typedef_enum_uint8_t(File); |
| 80 |
112 |
| 81 typedef uint8_t Board[8][8]; |
113 typedef uint8_t Board[8][8]; |
| 82 typedef uint8_t BoardIndex; |
|
| 83 typedef BoardIndex Row; |
|
| 84 typedef BoardIndex File; |
|
| 85 typedef uint8_t Piece; |
|
| 86 typedef uint8_t Color; |
|
| 87 |
114 |
| 88 struct movetimeval { |
115 struct movetimeval { |
| 89 uint64_t sec; |
116 uint64_t sec; |
| 90 int32_t usec; /* important that this is signed b/c potential carry */ |
117 int32_t usec; /* important that this is signed b/c potential carry */ |
| 91 }; |
118 }; |
| 152 /** this flag is only supposed to be set when the opponent disconnects */ |
179 /** this flag is only supposed to be set when the opponent disconnects */ |
| 153 bool ragequit; |
180 bool ragequit; |
| 154 bool review; |
181 bool review; |
| 155 } GameState; |
182 } GameState; |
| 156 |
183 |
| 157 #define piece_type(piece) ((piece)&PIECE_MASK) |
184 #define piece_type(piece) ((uint8_t)(piece)&PIECE_MASK) |
| 158 #define piece_color(piece) ((piece)&COLOR_MASK) |
185 #define piece_color(piece) ((uint8_t)(piece)&COLOR_MASK) |
| 159 #define mkpiece(type,color) ((type)|(color)) |
186 #define mkpiece(type,color) (Piece)((type)|(color)) |
| 160 |
187 |
| 161 #define POS_UNSPECIFIED UINT8_MAX |
|
| 162 #define mdst(m) (m)->torow, (m)->tofile |
188 #define mdst(m) (m)->torow, (m)->tofile |
| 163 #define msrc(m) (m)->fromrow, (m)->fromfile |
189 #define msrc(m) (m)->fromrow, (m)->fromfile |
| 164 |
190 |
| 165 /** Checks if the index is specified and valid. */ |
191 /** Checks if the index is specified and valid. */ |
| 166 #define isidx(idx) ((BoardIndex)(idx) < 8) |
192 static inline bool isidx(uint8_t idx) {return idx < 8;} |
| 167 /** Checks if the index is unspecified or valid. */ |
193 /** Checks if the index is unspecified or valid. */ |
| 168 #define isidxr(idx) ((idx) == POS_UNSPECIFIED || (BoardIndex)(idx) < 8) |
194 static inline bool isidxr(uint8_t idx) {return idx==POS_UNSPECIFIED || idx<8;} |
| 169 |
195 |
| 170 #define isfile(file) (file >= 'a' && file <= 'h') |
196 static inline bool isfile(char file) {return file >= 'a' && file <= 'h';} |
| 171 #define isrow(row) (row >= '1' && row <= '8') |
197 static inline bool isrow(char row) {return row >= '1' && row <= '8';} |
| 172 |
198 |
| 173 #define rowidx(row) (row-'1') |
199 static inline Row rowidx(char row) {return row-'1';} |
| 174 #define fileidx(file) (file-'a') |
200 static inline File fileidx(char file) {return file-'a';} |
| 175 |
201 |
| 176 #define rowchr(row) (row+'1') |
202 static inline char rowchr(Row row) {return (char)row+'1';} |
| 177 #define filechr(file) (file+'a') |
203 static inline char filechr(File file) {return (char)file+'a';} |
| 178 |
|
| 179 /* secure versions - use, if index is not checked with isidx() */ |
|
| 180 #define fileidx_s(c) (isfile(c)?fileidx(c):POS_UNSPECIFIED) |
|
| 181 #define rowidx_s(c) (isrow(c)?rowidx(c):POS_UNSPECIFIED) |
|
| 182 |
204 |
| 183 |
205 |
| 184 static inline void enpassant_threat_add(GameState *gamestate, |
206 static inline void enpassant_threat_add(GameState *gamestate, |
| 185 Row row, File file) { |
207 Row row, File file) { |
| 186 gamestate->board[row][file] |= ENPASSANT_THREAT; |
208 gamestate->board[row][file] |= ENPASSANT_THREAT; |