diff -r 08d7a6e3ec31 -r 84880c7e1ea6 src/game.c --- a/src/game.c Sat Mar 22 18:56:52 2014 +0100 +++ b/src/game.c Wed Mar 26 13:16:49 2014 +0100 @@ -135,8 +135,60 @@ return result; } +/** + * Maps a character to a piece. + * + * Does not work for pawns, since they don't have a character. + * + * @param c one of R,N,B,Q,K + * @return numeric value for the specified piece + */ +static uint8_t getpiece(char c) { + switch (c) { + case 'R': return ROOK; + case 'N': return KNIGHT; + case 'B': return BISHOP; + case 'Q': return QUEEN; + case 'K': return KING; + default: return 0; + } +} + +/** + * Guesses the location of a piece for short algebraic notation. + * + * @param board the current state of the board + * @param move the move date to operate on + * @return TRUE if the location could be retrieved, FALSE if the location is + * ambiguous + */ +static _Bool getlocation(Board board, Move *move) { + uint8_t piece = move->piece & PIECE_MASK; + switch (piece) { + case PAWN: return pawn_getlocation(board, move); + case ROOK: return rook_getlocation(board, move); + case KNIGHT: return knight_getlocation(board, move); + case BISHOP: return bishop_getlocation(board, move); + case QUEEN: return queen_getlocation(board, move); + case KING: return king_getlocation(board, move); + default: return FALSE; + } +} + +/** + * Evaluates a move syntactically and stores the move data in the specified + * object. + * + * @param board the current state of the board + * @param mycolor the color of the current player + * @param mstr the input string to parse + * @param move a pointer to object where the move data shall be stored + * @return TRUE, if the move is syntactically valid, FALSE otherwise + */ static _Bool eval_move(Board board, uint8_t mycolor, char *mstr, Move *move) { memset(move, 0, sizeof(Move)); + move->fromfile = POS_UNSPECIFIED; + move->fromrow = POS_UNSPECIFIED; size_t len = strlen(mstr); @@ -152,22 +204,22 @@ if (len == 2) { /* pawn move (e.g. "e4") */ if (isfile(mstr[0]) && isrow(mstr[1])) { - move->piece = PAWN|mycolor; + move->piece = PAWN; move->tofile = fileidx(mstr[0]); move->torow = rowidx(mstr[1]); - if (!pawn_getlocation(board, move)) { - move->piece = 0; - } } } else if (len == 3) { if (strcmp(mstr, "O-O") == 0) { /* king side castling */ - move->piece = KING|mycolor; + move->piece = KING; move->fromfile = fileidx('e'); move->tofile = fileidx('g'); move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; } else { /* unambiguous move (e.g. "Nf3") */ + move->piece = getpiece(mstr[0]); + move->tofile = isfile(mstr[1]) ? fileidx(mstr[1]) : POS_UNSPECIFIED; + move->torow = isrow(mstr[2]) ? fileidx(mstr[2]) : POS_UNSPECIFIED; } } else if (len == 4) { @@ -178,7 +230,7 @@ } else if (len == 5) { if (strcmp(mstr, "O-O-O") == 0) { /* queen side castling "O-O-O" */ - move->piece = KING|mycolor; + move->piece = KING; move->fromfile = fileidx('e'); move->tofile = fileidx('c'); move->fromrow = move->torow = mycolor == WHITE ? 0 : 7; @@ -192,6 +244,15 @@ } else if (len == 6) { /* long notation capture (e.g. "Nc5xf3") */ } + + if (move->piece) { + move->piece |= mycolor; + } + + if (!getlocation(board, move)) { + // TODO: return status code to indicate the error type + move->piece = 0; + } return move->piece != 0; }