133 // TODO: make it so |
133 // TODO: make it so |
134 |
134 |
135 return result; |
135 return result; |
136 } |
136 } |
137 |
137 |
|
138 /** |
|
139 * Maps a character to a piece. |
|
140 * |
|
141 * Does not work for pawns, since they don't have a character. |
|
142 * |
|
143 * @param c one of R,N,B,Q,K |
|
144 * @return numeric value for the specified piece |
|
145 */ |
|
146 static uint8_t getpiece(char c) { |
|
147 switch (c) { |
|
148 case 'R': return ROOK; |
|
149 case 'N': return KNIGHT; |
|
150 case 'B': return BISHOP; |
|
151 case 'Q': return QUEEN; |
|
152 case 'K': return KING; |
|
153 default: return 0; |
|
154 } |
|
155 } |
|
156 |
|
157 /** |
|
158 * Guesses the location of a piece for short algebraic notation. |
|
159 * |
|
160 * @param board the current state of the board |
|
161 * @param move the move date to operate on |
|
162 * @return TRUE if the location could be retrieved, FALSE if the location is |
|
163 * ambiguous |
|
164 */ |
|
165 static _Bool getlocation(Board board, Move *move) { |
|
166 uint8_t piece = move->piece & PIECE_MASK; |
|
167 switch (piece) { |
|
168 case PAWN: return pawn_getlocation(board, move); |
|
169 case ROOK: return rook_getlocation(board, move); |
|
170 case KNIGHT: return knight_getlocation(board, move); |
|
171 case BISHOP: return bishop_getlocation(board, move); |
|
172 case QUEEN: return queen_getlocation(board, move); |
|
173 case KING: return king_getlocation(board, move); |
|
174 default: return FALSE; |
|
175 } |
|
176 } |
|
177 |
|
178 /** |
|
179 * Evaluates a move syntactically and stores the move data in the specified |
|
180 * object. |
|
181 * |
|
182 * @param board the current state of the board |
|
183 * @param mycolor the color of the current player |
|
184 * @param mstr the input string to parse |
|
185 * @param move a pointer to object where the move data shall be stored |
|
186 * @return TRUE, if the move is syntactically valid, FALSE otherwise |
|
187 */ |
138 static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { |
188 static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { |
139 memset(move, 0, sizeof(Move)); |
189 memset(move, 0, sizeof(Move)); |
|
190 move->fromfile = POS_UNSPECIFIED; |
|
191 move->fromrow = POS_UNSPECIFIED; |
140 |
192 |
141 size_t len = strlen(mstr); |
193 size_t len = strlen(mstr); |
142 |
194 |
143 /* evaluate check/checkmate flags */ |
195 /* evaluate check/checkmate flags */ |
144 if (mstr[len-1] == '+') { |
196 if (mstr[len-1] == '+') { |
150 } |
202 } |
151 |
203 |
152 if (len == 2) { |
204 if (len == 2) { |
153 /* pawn move (e.g. "e4") */ |
205 /* pawn move (e.g. "e4") */ |
154 if (isfile(mstr[0]) && isrow(mstr[1])) { |
206 if (isfile(mstr[0]) && isrow(mstr[1])) { |
155 move->piece = PAWN|mycolor; |
207 move->piece = PAWN; |
156 move->tofile = fileidx(mstr[0]); |
208 move->tofile = fileidx(mstr[0]); |
157 move->torow = rowidx(mstr[1]); |
209 move->torow = rowidx(mstr[1]); |
158 if (!pawn_getlocation(board, move)) { |
|
159 move->piece = 0; |
|
160 } |
|
161 } |
210 } |
162 } else if (len == 3) { |
211 } else if (len == 3) { |
163 if (strcmp(mstr, "O-O") == 0) { |
212 if (strcmp(mstr, "O-O") == 0) { |
164 /* king side castling */ |
213 /* king side castling */ |
165 move->piece = KING|mycolor; |
214 move->piece = KING; |
166 move->fromfile = fileidx('e'); |
215 move->fromfile = fileidx('e'); |
167 move->tofile = fileidx('g'); |
216 move->tofile = fileidx('g'); |
168 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
217 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
169 } else { |
218 } else { |
170 /* unambiguous move (e.g. "Nf3") */ |
219 /* unambiguous move (e.g. "Nf3") */ |
|
220 move->piece = getpiece(mstr[0]); |
|
221 move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; |
|
222 move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; |
171 } |
223 } |
172 |
224 |
173 } else if (len == 4) { |
225 } else if (len == 4) { |
174 /* ambiguous move (e.g. "Ndf3") */ |
226 /* ambiguous move (e.g. "Ndf3") */ |
175 |
227 |
176 /* unambiguous capture (e.g. "Nxf3", "dxe5") */ |
228 /* unambiguous capture (e.g. "Nxf3", "dxe5") */ |
177 |
229 |
178 } else if (len == 5) { |
230 } else if (len == 5) { |
179 if (strcmp(mstr, "O-O-O") == 0) { |
231 if (strcmp(mstr, "O-O-O") == 0) { |
180 /* queen side castling "O-O-O" */ |
232 /* queen side castling "O-O-O" */ |
181 move->piece = KING|mycolor; |
233 move->piece = KING; |
182 move->fromfile = fileidx('e'); |
234 move->fromfile = fileidx('e'); |
183 move->tofile = fileidx('c'); |
235 move->tofile = fileidx('c'); |
184 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
236 move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; |
185 } else { |
237 } else { |
186 /* ambiguous capture (e.g. "Ndxf3") */ |
238 /* ambiguous capture (e.g. "Ndxf3") */ |
189 |
241 |
190 /* long notation capture (e.g. "e5xf6") */ |
242 /* long notation capture (e.g. "e5xf6") */ |
191 } |
243 } |
192 } else if (len == 6) { |
244 } else if (len == 6) { |
193 /* long notation capture (e.g. "Nc5xf3") */ |
245 /* long notation capture (e.g. "Nc5xf3") */ |
|
246 } |
|
247 |
|
248 if (move->piece) { |
|
249 move->piece |= mycolor; |
|
250 } |
|
251 |
|
252 if (!getlocation(board, move)) { |
|
253 // TODO: return status code to indicate the error type |
|
254 move->piece = 0; |
194 } |
255 } |
195 |
256 |
196 return move->piece != 0; |
257 return move->piece != 0; |
197 } |
258 } |
198 |
259 |