1 /***************************************************************************
2 move_notation.h - Convert move from and to string
4 begin : Mon Oct 08 2007
5 copyright : (C) 2007 by Maurizio Monge
6 email : monge@linuz.sns.it
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
22 static int char_to_piece(char c
)
26 case 'K': case 'k': return KING
;
27 case 'Q': case 'q': return QUEEN
;
28 case 'R': case 'r': return ROOK
;
29 case 'B': case 'b': return BISHOP
;
30 case 'N': case 'n': return KNIGHT
;
31 case 'P': case 'p': return PAWN
;
38 /* reads a string and if possible understands a move */
39 Move
Board::move_from_string(const char* s
)
48 int comment_2
= strlen(s
);
50 Move retv
= Move::None();
53 if(!strncmp(s
, "0-0-0", 5) || !strncmp(s
, "O-O-O", 5) || !strncmp(s
, "o-o-o", 5) )
58 int num_moves
= find_moves(moves
);
60 for(int i
=0;i
<num_moves
;i
++)
61 if(moves
[i
].flags
== CASTLEQUEENSIDE
)
67 return Move::Illegal();
70 /* parse O-O. Note that O-O-O matches the expr for O-O, so it must be tested after */
71 if(!strncmp(s
, "0-0", 3) || !strncmp(s
, "O-O", 3) || !strncmp(s
, "o-o", 3) )
76 int num_moves
= find_moves(moves
);
78 for(int i
=0;i
<num_moves
;i
++)
79 if(moves
[i
].flags
== CASTLEKINGSIDE
)
85 return Move::Illegal();
89 if(s
[pos
]>='A' && s
[pos
]<='Z' && (piece
=char_to_piece(s
[pos
])) != -1)
91 if(s
[pos
]>='a' && s
[pos
]<='h')
92 to_x
= s
[pos
++] - 'a';
93 if(s
[pos
]>='1' && s
[pos
]<='8')
94 to_y
= s
[pos
++] - '1';
95 if(s
[pos
]=='-' || s
[pos
]=='x')
97 if(s
[pos
]>='A' && s
[pos
]<='Z' && char_to_piece(s
[pos
]) != -1)
99 if(s
[pos
]>='a' && s
[pos
]<='h')
102 to_x
= s
[pos
++] - 'a';
104 if(s
[pos
]>='1' && s
[pos
]<='8')
107 to_y
= s
[pos
++] - '1';
111 if((promote
=char_to_piece(s
[pos
])) != -1)
114 if(to_x
!= -1 && to_y
!= -1)
116 if(piece
==-1 && (from_x
==-1 || from_y
==-1))
121 /* find a unique matching move */
123 int num_moves
= find_moves(moves
);
126 // printf("piece=%d from_x=%d from_y=%d to_x=%d to_y=%d promote=%d\n",
127 // piece, from_x, from_y, to_x, to_y, promote);
129 for(int i
=0;i
<num_moves
;i
++)
132 // move_to_alg(buf, &moves[i]);
133 // printf("%s piece=%d from_x=%d from_y=%d to_x=%d to_y=%d promote=%d\n", buf,
134 // PIECE_OF(data[moves[i].from]), X(moves[i].from), Y(moves[i].from),
135 // X(moves[i].to), Y(moves[i].to), moves[i].flags);
136 if( (piece
== -1 || piece
== PIECE_OF(data
[moves
[i
].from
])) &&
137 (from_x
== -1 || from_x
== X(moves
[i
].from
)) &&
138 (from_y
== -1 || from_y
== Y(moves
[i
].from
)) &&
139 (to_x
== X(moves
[i
].to
)) &&
140 (to_y
== Y(moves
[i
].to
)) &&
141 (moves
[i
].flags
<PROMOTE_FIRST
|| moves
[i
].flags
>PROMOTE_LAST
|| moves
[i
].flags
-PROMOTE0
== promote
) )
143 if(retv
!= Move::None())
144 return Move::Ambiguous();
150 if(retv
== Move::None())
151 return Move::Illegal();
160 for(int i
=comment_1
; i
<comment_2
; i
++)
169 //converts a move to the dummy notation (e2e4,g7h8q,...)
170 char* Board::move_to_coord(char* string
, const Move
& mv
)
173 *(str
++) = 'a' + X(mv
.from
);
174 *(str
++) = '1' + Y(mv
.from
);
175 *(str
++) = 'a' + X(mv
.to
);
176 *(str
++) = '1' + Y(mv
.to
);
179 if(mv
.flags
> PROMOTE0
)
180 *(str
++) = piecename
[ mv
.flags
-PROMOTE0
]^0x20;
185 /* converts a move into the standard algebraic notation
186 the current board must be the board before the move is done.
187 mv must be a valid move in the current position! */
188 char* Board::move_to_alg(char* string
, const Move
& mv
)
192 if(mv
.flags
==CASTLEKINGSIDE
)
198 else if(mv
.flags
==CASTLEQUEENSIDE
)
209 int num_moves
= find_moves(moves
);
210 unsigned char piece
=data
[mv
.from
];
212 if(PIECE_OF(piece
)!=PAWN
)
214 /* mark here how the move could be ambiguous */
219 *(str
++)=Board::piecename
[PIECE_OF(piece
)];
221 for(int i
=0;i
<num_moves
;i
++)
223 //check for ambiguity
224 if(piece
== data
[moves
[i
].from
] //same piece?
225 && moves
[i
].to
== mv
.to
//same target?
226 && moves
[i
].from
!= mv
.from
) //but not same move?
229 if(X(moves
[i
].from
)==X(mv
.from
))
231 if(Y(moves
[i
].from
)==Y(mv
.from
))
238 if(!samecol
|| samerow
)
239 *(str
++)='a' + X(mv
.from
);
241 *(str
++)='1' + Y(mv
.from
);
244 if((mv
.capture
) || mv
.flags
==ENPASSANT
)
246 if(PIECE_OF(piece
)==PAWN
)
247 *(str
++)='a' + X(mv
.from
);
251 *(str
++)='a' + X(mv
.to
);
252 *(str
++)='1' + Y(mv
.to
);
254 if(mv
.flags
> PROMOTE0
)
257 *(str
++) = Board::piecename
[ mv
.flags
-PROMOTE0
];
260 /* is this move a check(mate)? */
263 if(under_attack( king_pos
[IS_WHITE(color_to_move
)],
267 int n
= find_moves(mv_tmp
);