src/game.c

changeset 16
a298c6637c30
parent 15
7ffd66591afe
child 17
2aed5418e142
equal deleted inserted replaced
15:7ffd66591afe 16:a298c6637c30
145 case PAWN: 145 case PAWN:
146 result = result && pawn_chkrules(board, move); 146 result = result && pawn_chkrules(board, move);
147 result = result && !pawn_isblocked(board, move); 147 result = result && !pawn_isblocked(board, move);
148 break; 148 break;
149 case ROOK: 149 case ROOK:
150 result = result && rook_chkrules(board, move); 150 result = result && rook_chkrules(move);
151 result = result && !rook_isblocked(board, move); 151 result = result && !rook_isblocked(board, move);
152 break; 152 break;
153 case KNIGHT: 153 case KNIGHT:
154 result = result && knight_chkrules(board, move); 154 result = result && knight_chkrules(move);
155 result = result && !knight_isblocked(board, move); 155 result = result && !knight_isblocked(board, move);
156 break; 156 break;
157 case BISHOP: 157 case BISHOP:
158 result = result && bishop_chkrules(board, move); 158 result = result && bishop_chkrules(move);
159 result = result && !bishop_isblocked(board, move); 159 result = result && !bishop_isblocked(board, move);
160 break; 160 break;
161 case QUEEN: 161 case QUEEN:
162 result = result && queen_chkrules(board, move); 162 result = result && queen_chkrules(move);
163 result = result && !queen_isblocked(board, move); 163 result = result && !queen_isblocked(board, move);
164 break; 164 break;
165 case KING: 165 case KING:
166 result = result && king_chkrules(board, move); 166 result = result && king_chkrules(board, move);
167 result = result && !king_isblocked(board, move); 167 result = result && !king_isblocked(board, move);
201 /** 201 /**
202 * Guesses the location of a piece for short algebraic notation. 202 * Guesses the location of a piece for short algebraic notation.
203 * 203 *
204 * @param board the current state of the board 204 * @param board the current state of the board
205 * @param move the move date to operate on 205 * @param move the move date to operate on
206 * @return TRUE if the location could be retrieved, FALSE if the location is 206 * @return status code (see rules/rules.h for the codes)
207 * ambiguous
208 */ 207 */
209 static _Bool getlocation(Board board, Move *move) { 208 static int getlocation(Board board, Move *move) {
210 uint8_t piece = move->piece & PIECE_MASK; 209 uint8_t piece = move->piece & PIECE_MASK;
211 switch (piece) { 210 switch (piece) {
212 case PAWN: return pawn_getlocation(board, move); 211 case PAWN: return pawn_getlocation(board, move);
213 case ROOK: return rook_getlocation(board, move); 212 case ROOK: return rook_getlocation(board, move);
214 case KNIGHT: return knight_getlocation(board, move); 213 case KNIGHT: return knight_getlocation(board, move);
215 case BISHOP: return bishop_getlocation(board, move); 214 case BISHOP: return bishop_getlocation(board, move);
216 case QUEEN: return queen_getlocation(board, move); 215 case QUEEN: return queen_getlocation(board, move);
217 case KING: return king_getlocation(board, move); 216 case KING: return king_getlocation(board, move);
218 default: return FALSE; 217 default: return INVALID_MOVE_SYNTAX;
219 } 218 }
220 } 219 }
221 220
222 /** 221 /**
223 * Evaluates a move syntactically and stores the move data in the specified 222 * Evaluates a move syntactically and stores the move data in the specified
225 * 224 *
226 * @param board the current state of the board 225 * @param board the current state of the board
227 * @param mycolor the color of the current player 226 * @param mycolor the color of the current player
228 * @param mstr the input string to parse 227 * @param mstr the input string to parse
229 * @param move a pointer to object where the move data shall be stored 228 * @param move a pointer to object where the move data shall be stored
230 * @return TRUE, if the move is syntactically valid, FALSE otherwise 229 * @return status code (see rules/rules.h for the list of codes)
231 */ 230 */
232 static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { 231 static int eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) {
233 memset(move, 0, sizeof(Move)); 232 memset(move, 0, sizeof(Move));
234 move->fromfile = POS_UNSPECIFIED; 233 move->fromfile = POS_UNSPECIFIED;
235 move->fromrow = POS_UNSPECIFIED; 234 move->fromrow = POS_UNSPECIFIED;
236 235
237 size_t len = strlen(mstr); 236 size_t len = strlen(mstr);
329 328
330 if (move->piece) { 329 if (move->piece) {
331 move->piece |= mycolor; 330 move->piece |= mycolor;
332 if (move->fromfile == POS_UNSPECIFIED 331 if (move->fromfile == POS_UNSPECIFIED
333 || move->fromrow == POS_UNSPECIFIED) { 332 || move->fromrow == POS_UNSPECIFIED) {
334 return getlocation(board, move) && chkidx(move); 333 return getlocation(board, move);
335 } else { 334 } else {
336 return chkidx(move); 335 return chkidx(move) ? VALID_MOVE_SYNTAX : INVALID_POSITION;
337 } 336 }
338 } else { 337 } else {
339 return FALSE; 338 return INVALID_MOVE_SYNTAX;
340 } 339 }
341 // TODO: return status code to indicate the error type
342 } 340 }
343 341
344 static int sendmove(Board board, uint8_t mycolor, int opponent) { 342 static int sendmove(Board board, uint8_t mycolor, int opponent) {
345 const size_t buflen = 8; 343 const size_t buflen = 8;
346 char movestr[buflen]; 344 char movestr[buflen];
364 refresh(); 362 refresh();
365 getnstr(movestr, buflen); 363 getnstr(movestr, buflen);
366 364
367 if (strncmp(movestr, "surr", buflen) == 0) { 365 if (strncmp(movestr, "surr", buflen) == 0) {
368 printw("You surrendered!"); 366 printw("You surrendered!");
367 clrtoeol();
369 refresh(); 368 refresh();
370 net_send_code(opponent, NETCODE_SURRENDER); 369 net_send_code(opponent, NETCODE_SURRENDER);
371 return 1; 370 return 1;
372 } else if (strncmp(movestr, "remis", buflen) == 0) { 371 } else if (strncmp(movestr, "remis", buflen) == 0) {
373 if (!remisrejected) { 372 if (!remisrejected) {
383 remisrejected = TRUE; 382 remisrejected = TRUE;
384 } 383 }
385 } 384 }
386 } else { 385 } else {
387 Move move; 386 Move move;
388 if (eval_move(board, mycolor, movestr, &move)) { 387 int eval_result = eval_move(board, mycolor, movestr, &move);
389 net_send_code(opponent, NETCODE_MOVE); 388 switch (eval_result) {
390 net_send_data(opponent, &move, sizeof(Move)); 389 case VALID_MOVE_SYNTAX:
391 code = net_recieve_code(opponent); 390 net_send_code(opponent, NETCODE_MOVE);
392 move.check = code == NETCODE_CHECK; 391 net_send_data(opponent, &move, sizeof(Move));
393 move.checkmate = code == NETCODE_CHECKMATE; 392 code = net_recieve_code(opponent);
394 // TODO: record move 393 move.check = code == NETCODE_CHECK;
395 if (code == NETCODE_DECLINE) { 394 move.checkmate = code == NETCODE_CHECKMATE;
396 printw("Invalid move."); 395 // TODO: record move
397 clrtoeol(); 396 if (code == NETCODE_DECLINE) {
398 } else { 397 printw("Invalid move.");
399 apply_move(board, &move);
400 if (move.checkmate) {
401 printw("Checkmate!");
402 return 1;
403 } else { 398 } else {
404 return 0; 399 apply_move(board, &move);
400 if (move.checkmate) {
401 printw("Checkmate!");
402 clrtoeol();
403 return 1;
404 } else {
405 return 0;
406 }
405 } 407 }
406 } 408 break;
407 } else { 409 case AMBIGUOUS_MOVE:
408 printw("Can't interpret move - please use algebraic notation."); 410 printw("Ambiguous move - "
411 "please specify the piece to move.");
412 break;
413 case INVALID_POSITION:
414 printw("Cannot find the piece that shall be moved.");
415 break;
416 default:
417 printw("Can't interpret move - "
418 "please use algebraic notation.");
409 } 419 }
420 clrtoeol();
410 } 421 }
411 } 422 }
412 } 423 }
413 424
414 static int recvmove(Board board, int opponent) { 425 static int recvmove(Board board, int opponent) {

mercurial