2
* Copyright (C) 1999,2001 Robert Wilhelm
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 3 of the License, or
7
* (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, see <http://www.gnu.org/licenses/>.
21
#include "chess_position.h"
22
#include "chess_notation.h"
24
static char piece_to_ascii_t[]= {' ','N','B','R','Q','K'};
26
static int norm_piece (Piece piece);
29
file_to_ascii (char **move, Square square)
31
*(*move)++ = square - square / 10 * 10 + 96; /* a - h */
35
rank_to_ascii (char **move, Square square)
37
*(*move)++ = square / 10 + 47 ; /* 1 - 8 */
41
square_to_ascii(char **move, Square square)
43
file_to_ascii (move, square);
44
rank_to_ascii (move, square);
49
same_rank (Square square, Square square2)
58
rank_to_ascii (&s1, square);
59
rank_to_ascii (&s2, square2);
68
same_file (Square square, Square square2)
77
file_to_ascii (&s1, square);
78
file_to_ascii (&s2, square2);
89
char *p = strchr (str, 'x');
97
delete_plus (char *str)
99
char *p = strchr (str, '+');
102
while ((*p = *(p+1)))
107
delete_ep (char *str)
109
char *p = strstr (str, "ep");
112
while ((*p = *(p+2)))
117
delete_equal (char *str)
119
char *p = strstr (str, "=");
122
while ((*p = *(p+1)))
127
delete_hash (char *str)
129
char *p = strstr (str, "#");
132
while ((*p = *(p+1)))
137
move_to_ascii (char *p, Square from, Square to)
141
file_to_ascii (&p, from);
142
rank_to_ascii (&p, from);
149
a = (a & 7) + A8; /* white */
151
a = (a & 7) + A1; /* black */
153
*p++ = a - a / 10 * 10 + 96; /* a - h */
154
*p++ = a / 10 + 47 ; /* 1 - 8 */
156
*p++ = piece_to_ascii_t[((to >> 3) & 7)-1];
158
file_to_ascii (&p, to);
159
rank_to_ascii (&p, to);
168
ascii_to_piece (char p)
187
g_assert_not_reached ();
193
piece_to_ascii (int piece)
195
static char piece_to_ascii_full[]= {'P','N','B','R','Q','K'};
201
i = norm_piece (piece);
204
return piece_to_ascii_full[i];
206
return tolower(piece_to_ascii_full[i]);
208
g_assert_not_reached ();
214
ascii_to_move (Position *pos, char *p, Square *from, Square *to)
220
if (!strcmp (p, "o-o-o")) {
221
if (position_get_color_to_move (pos) == WHITE) {
229
if (position_get_color_to_move (pos) == WHITE) {
240
*from = (*p - 'a' + 1) + (*(p + 1) - '1' + 2 ) * 10;
242
*to = (*p - 'a' + 1) + (*(p + 1) - '1' + 2 ) * 10;
245
if (*p == 'q' || *p == 'r' || *p == 'b' || *p =='n' ||
246
*p =='Q' || *p =='R' || *p == 'B' || *p == 'N' ) {
249
*to = 128 + *to - A1 + (ascii_to_piece (*p) + 1) * 8;
251
*to = 128 + *to - A8 + (ascii_to_piece (*p) + 1) * 8;
253
g_assert_not_reached ();
258
san_to_move (Position *pos, char *str, Square *from, Square *to)
260
Square zugliste[AB_ZUGL];
262
gshort anz, anz_n, anz_s;
265
gchar liste[100][10];
273
ap = zugliste + AB_ZUG_S;
274
anz = position_legal_move (pos, &ap, &anz_s, &anz_n);
276
for (aq = ap, i = 0; i < anz; i++, aq += 2) {
278
piece_move_to_ascii (p, pos->square[*aq], *aq, *(aq + 1));
285
if (!strcmp (p, str)) {
299
if (!strcmp(p,str)) {
307
if (!strcmp(p,str)) {
318
if (!strcmp (p, str)) {
330
if (!strcmp(p,str)) {
339
if (!strcmp(p,str)) {
350
if (!strcmp(p,str)) {
362
norm_piece (Piece piece)
373
piece_move_to_ascii (char *p, Piece piece, Square from, Square to)
377
if ((piece == WK || piece == BK) && abs (from - to) == 2) {
386
g_assert_not_reached ();
389
i = norm_piece (piece);
390
*p++ = piece_to_ascii_t[i];
391
move_to_ascii (p, from, to);
395
move_to_san (Position *pos, Square from, Square to)
397
Square checksquare, checkto;
398
Piece piece, promote;
399
int norm, desrank, desfile, inc;
400
int i, tempdesfile, tempdesrank;
403
const int jump[]={ 8, 12,19, 21,-8,-12,-19,-21};
405
san = g_new0 (char, 12);
408
desrank = desfile = promote = 0;
410
/* Handle Promotion */
412
promote = ((to >> 3) & 7)-1;
421
piece = pos->square[to];
424
/* Check if we have to designate the rank or file */
428
/* Check like rooks and bishops */
431
/* Check for other rooks/queens */
434
tempdesfile = tempdesrank = 0;
436
checksquare = 20 + (to % 10);
437
checkto = 90 + (to % 10);
438
if (from / 10 > to / 10 )
440
else if (from / 10 < to /10)
441
checksquare = to + 10;
444
checksquare = 10 * (to / 10) + 1;
445
checkto = 10 * (to / 10) + 8;
446
if (from % 10 > to % 10)
448
else if (from % 10 < to % 10)
449
checksquare = to + 1;
455
while (checksquare <= checkto) {
456
if (pos->square[checksquare] == piece && checksquare != to) {
457
if (same_rank(from, checksquare))
459
else if (same_file(from, checksquare))
463
} else if (pos->square[checksquare] != EMPTY && checksquare < to) {
464
tempdesfile = tempdesrank = 0; /* A piece is in the way */
465
} else if (pos->square[checksquare] != EMPTY && checksquare > to) {
466
break; /* A piece is in the way */
471
if (tempdesfile == 1) desfile = 1;
472
if (tempdesrank == 1) desrank = 1;
474
if (piece == WR || piece == BR) break;
477
/* Check for other bishops/queens */
480
tempdesfile = tempdesrank = 0;
482
checksquare = to - (((to % 10) - 1) * 11);
483
checkto = to + ((9 - (to / 10)) * 11);
484
if (from % 10 > to % 10 && from / 10 > to / 10)
486
else if (from % 10 < to % 10 && from / 10 < to / 10)
487
checksquare = to + 11;
490
checksquare = to - ((8 - (to % 10)) * 9);
491
checkto = to + ((9 - (to / 10)) * 9);
492
if (from % 10 > to % 10 && from / 10 < to / 10)
493
checksquare = to + 9;
494
else if (from % 10 < to % 10 && from / 10 > to / 10)
501
while (checksquare <= checkto) {
502
if (pos->square[checksquare] == piece && checksquare != to) {
503
if (same_rank(from, checksquare))
505
else if (same_file(from, checksquare))
509
} else if (pos->square[checksquare] != EMPTY && checksquare < to) {
510
tempdesfile = tempdesrank = 0; /* A piece is in the way */
511
} else if (pos->square[checksquare] != EMPTY && checksquare > to) {
512
break; /* A piece is in the way */
517
if (tempdesfile == 1) desfile = 1;
518
if (tempdesrank == 1) desrank = 1;
523
/* Check for other knights */
525
if (pos->square[to+jump[i]] == piece && to+jump[i] >= 0) {
526
if (same_rank(from, to+jump[i]))
528
else if (same_file(from, to+jump[i]))
538
/* Handle Castling */
539
if ((piece == WK || piece == BK) && abs(from-to) == 2) {
541
strcpy(temp,"O-O-O");
545
/* The piece letter */
546
norm = norm_piece(piece);
548
*temp++ = piece_to_ascii_t[norm];
550
/* The rank/file designators */
552
file_to_ascii(&temp, from);
554
rank_to_ascii(&temp, from);
556
/* If there was a capture */
557
if (position_last_piece_captured (pos) != EMPTY) {
558
if (piece == WP || piece == BP)
559
file_to_ascii (&temp, from);
563
/* Destination square */
564
square_to_ascii (&temp, to);
566
/* If there was promotion */
569
norm = norm_piece(promote);
570
*temp++ = piece_to_ascii_t[norm];
577
san = g_strdup (temp);