3 Copyright (c) Scott Gasch
11 Routines to convert internal move structs into ICS (d2d4 style)
12 move strings and vice versa.
22 $Id: ics.c 345 2007-12-02 22:56:42Z scott $
35 Convert a MOVE into an ICS ("d2d4" style) string. Note: not
40 MOVE mv : the move to convert
48 static char szTextMove[10];
55 memset(szTextMove, 0, sizeof(szTextMove));
57 ASSERT(IS_ON_BOARD(mv.cFrom));
58 ASSERT(IS_ON_BOARD(mv.cTo));
59 *p++ = FILE(mv.cFrom) + 'a';
60 *p++ = RANK(mv.cFrom) + '0';
61 *p++ = FILE(mv.cTo) + 'a';
62 *p++ = RANK(mv.cTo) + '0';
66 if (IS_QUEEN(mv.pPromoted))
70 else if (IS_ROOK(mv.pPromoted))
74 else if (IS_BISHOP(mv.pPromoted))
78 else if (IS_KNIGHT(mv.pPromoted))
94 ParseMoveIcs(CHAR *szInput, POSITION *pos)
99 Parse a move in ICS format (i.e. "d2d4") and create a MOVE struct.
114 PIECE pMoved, pCaptured, pProm;
115 CHAR *szMoveText = StripMove(szInput);
116 static CHAR *szPieces = "nbrq";
120 if (InCheck(pos, pos->uToMove))
122 mv.bvFlags |= MOVE_FLAG_ESCAPING_CHECK;
125 cFrom = FILE_RANK_TO_COOR((tolower(szMoveText[0]) - 'a'),
126 (tolower(szMoveText[1]) - '0'));
127 cTo = FILE_RANK_TO_COOR((tolower(szMoveText[2]) - 'a'),
128 (tolower(szMoveText[3]) - '0'));
131 // check for castling moves in o-o style notation.
133 if ((!STRCMPI(szMoveText, "OO")) ||
134 (!STRCMPI(szMoveText, "00")) ||
135 (((E1 == cFrom) && (G1 == cTo)) &&
136 (pos->rgSquare[E1].pPiece == WHITE_KING)) ||
137 (((E8 == cFrom) && (G8 == cTo)) &&
138 (pos->rgSquare[E8].pPiece == BLACK_KING)))
140 if (pos->uToMove == WHITE)
142 if (pos->bvCastleInfo & CASTLE_WHITE_SHORT)
144 ASSERT(pos->rgSquare[E1].pPiece == WHITE_KING);
146 MAKE_MOVE(E1, G1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL);
149 else // black to move
151 if (pos->bvCastleInfo & CASTLE_BLACK_SHORT)
153 ASSERT(pos->rgSquare[E8].pPiece == BLACK_KING);
155 MAKE_MOVE(E8, G8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL);
160 else if ((!STRCMPI(szMoveText, "OOO")) ||
161 (!STRCMPI(szMoveText, "000")) ||
162 (((E1 == cFrom) && (C1 == cTo)) &&
163 (pos->rgSquare[E1].pPiece == WHITE_KING)) ||
164 (((E8 == cFrom) && (C8 == cTo)) &&
165 (pos->rgSquare[E8].pPiece == BLACK_KING)))
167 if (pos->uToMove == WHITE)
169 if (pos->bvCastleInfo & CASTLE_WHITE_LONG)
171 ASSERT(pos->rgSquare[E1].pPiece == WHITE_KING);
173 MAKE_MOVE(E1, C1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL);
176 else // black to move
178 if (pos->bvCastleInfo & CASTLE_BLACK_LONG)
180 ASSERT(pos->rgSquare[E8].pPiece == BLACK_KING);
182 MAKE_MOVE(E8, C8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL);
188 if ((!IS_ON_BOARD(cFrom)) ||
194 pMoved = pos->rgSquare[cFrom].pPiece;
195 if ((IS_EMPTY(pMoved)) || (GET_COLOR(pMoved) != pos->uToMove))
200 pCaptured = pos->rgSquare[cTo].pPiece;
201 if ((pCaptured != 0) && (GET_COLOR(pCaptured) == pos->uToMove))
209 mv.pCaptured = pCaptured;
216 if ((szMoveText[4] != 0) && (szMoveText[4] != '\n'))
218 if (IS_PAWN(mv.pMoved))
220 if (((BLACK == GET_COLOR(mv.pMoved)) && (RANK(cTo) != 1)) ||
221 ((WHITE == GET_COLOR(mv.pMoved)) && (RANK(cTo) != 8)))
226 p = strchr(szPieces, tolower(szMoveText[4]));
231 pProm = (PIECE)((BYTE *)p - (BYTE *)szPieces);
234 pProm |= pos->uToMove;
235 mv.pPromoted = pProm;
236 mv.bvFlags = MOVE_FLAG_SPECIAL;
240 // Handle en passant captures.
242 if (cTo == pos->cEpSquare)
244 mv.bvFlags = MOVE_FLAG_SPECIAL;
245 if (WHITE == pos->uToMove)
247 mv.pCaptured = pos->rgSquare[cTo + 0x10].pPiece;
248 ASSERT(mv.pCaptured == BLACK_PAWN);
252 mv.pCaptured = pos->rgSquare[cTo - 0x10].pPiece;
253 ASSERT(mv.pCaptured == WHITE_PAWN);
258 // Handle double jumps.
260 if (abs(RANK(cTo) - RANK(cFrom)) > 1)
262 mv.bvFlags = MOVE_FLAG_SPECIAL;