~ubuntu-branches/ubuntu/trusty/polyglot/trusty

« back to all changes in this revision

Viewing changes to fen.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Korff
  • Date: 2005-10-09 21:56:20 UTC
  • Revision ID: james.westby@ubuntu.com-20051009215620-dcuqynujzvmiglpj
Tags: upstream-1.3
ImportĀ upstreamĀ versionĀ 1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
// fen.cpp
 
3
 
 
4
// includes
 
5
 
 
6
#include <cctype>
 
7
#include <cstdio>
 
8
#include <cstdlib>
 
9
 
 
10
#include "board.h"
 
11
#include "colour.h"
 
12
#include "fen.h"
 
13
#include "piece.h"
 
14
#include "square.h"
 
15
#include "util.h"
 
16
 
 
17
// "constants"
 
18
 
 
19
const char * StartFen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
 
20
 
 
21
// variables
 
22
 
 
23
static const bool Strict = false;
 
24
 
 
25
// functions
 
26
 
 
27
// board_from_fen()
 
28
 
 
29
bool board_from_fen(board_t *board, const char string[]) {
 
30
 
 
31
   int pos;
 
32
   int file, rank, sq;
 
33
   int c;
 
34
   int i, len;
 
35
   int piece;
 
36
 
 
37
   ASSERT(board!=NULL);
 
38
   ASSERT(string!=NULL);
 
39
 
 
40
   board_clear(board);
 
41
 
 
42
   pos = 0;
 
43
   c = string[pos];
 
44
 
 
45
   // piece placement
 
46
 
 
47
   for (rank = 7; rank >= 0; rank--) {
 
48
 
 
49
      for (file = 0; file < 8;) {
 
50
 
 
51
         sq = square_make(file,rank);
 
52
 
 
53
         if (c >= '1' && c <= '8') { // empty square(s)
 
54
 
 
55
            len = c - '0';
 
56
            if (file + len > 8) my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
57
 
 
58
            for (i = 0; i < len; i++) {
 
59
               board->square[sq++] = Empty;
 
60
               file++;
 
61
            }
 
62
 
 
63
         } else { // piece
 
64
 
 
65
            piece = piece_from_char(c);
 
66
            if (piece == PieceNone256) my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
67
 
 
68
            board->square[sq++] = piece;
 
69
            file++;
 
70
         }
 
71
 
 
72
         c = string[++pos];
 
73
      }
 
74
 
 
75
      if (rank > 0) {
 
76
         if (c != '/') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
77
         c = string[++pos];
 
78
     }
 
79
   }
 
80
 
 
81
   // active colour
 
82
 
 
83
   if (c != ' ') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
84
   c = string[++pos];
 
85
 
 
86
   switch (c) {
 
87
   case 'w' :
 
88
      board->turn = White;
 
89
      break;
 
90
   case 'b' :
 
91
      board->turn = Black;
 
92
      break;
 
93
   default :
 
94
      my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
95
      break;
 
96
   }
 
97
 
 
98
   c = string[++pos];
 
99
 
 
100
   // castling
 
101
 
 
102
   if (c != ' ') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
103
   c = string[++pos];
 
104
 
 
105
   board->flags = FlagsNone;
 
106
 
 
107
   if (c == '-') { // no castling rights
 
108
 
 
109
      c = string[++pos];
 
110
 
 
111
   } else {
 
112
 
 
113
      if (c == 'K') {
 
114
         board->flags |= FlagsWhiteKingCastle;
 
115
         c = string[++pos];
 
116
      }
 
117
 
 
118
      if (c == 'Q') {
 
119
         board->flags |= FlagsWhiteQueenCastle;
 
120
         c = string[++pos];
 
121
      }
 
122
 
 
123
      if (c == 'k') {
 
124
         board->flags |= FlagsBlackKingCastle;
 
125
         c = string[++pos];
 
126
      }
 
127
 
 
128
      if (c == 'q') {
 
129
         board->flags |= FlagsBlackQueenCastle;
 
130
         c = string[++pos];
 
131
      }
 
132
   }
 
133
 
 
134
   // en-passant
 
135
 
 
136
   if (c != ' ') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
137
   c = string[++pos];
 
138
 
 
139
   if (c == '-') { // no en-passant
 
140
 
 
141
      sq = SquareNone;
 
142
      c = string[++pos];
 
143
 
 
144
   } else {
 
145
 
 
146
      if (c < 'a' || c > 'h') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
147
      file = file_from_char(c);
 
148
      c = string[++pos];
 
149
 
 
150
      if (c < '1' || c > '8') my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
151
      rank = rank_from_char(c);
 
152
      c = string[++pos];
 
153
 
 
154
      sq = square_make(file,rank);
 
155
   }
 
156
 
 
157
   board->ep_square = sq;
 
158
 
 
159
   // halfmove clock
 
160
 
 
161
   board->ply_nb = 0;
 
162
   board->move_nb = 0; // HACK, in case of broken syntax
 
163
 
 
164
   if (c != ' ') {
 
165
      if (!Strict) goto update;
 
166
      my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
167
   }
 
168
   c = string[++pos];
 
169
 
 
170
   if (!isdigit(c)) {
 
171
      if (!Strict) goto update;
 
172
      my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
173
   }
 
174
 
 
175
   board->ply_nb = atoi(&string[pos]);
 
176
   do c = string[++pos]; while (isdigit(c));
 
177
 
 
178
   // fullmove number
 
179
 
 
180
   board->move_nb = 0;
 
181
 
 
182
   if (c != ' ') {
 
183
      if (!Strict) goto update;
 
184
      my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
185
   }
 
186
   c = string[++pos];
 
187
 
 
188
   if (!isdigit(c)) {
 
189
      if (!Strict) goto update;
 
190
      my_fatal("board_from_fen(): bad FEN (pos=%d)\n",pos);
 
191
   }
 
192
 
 
193
   board->move_nb = atoi(&string[pos]) - 1;
 
194
   do c = string[++pos]; while (isdigit(c));
 
195
 
 
196
   // board update
 
197
 
 
198
update:
 
199
   board_init_list(board);
 
200
 
 
201
   return true;
 
202
}
 
203
 
 
204
// board_to_fen()
 
205
 
 
206
bool board_to_fen(const board_t *board, char string[], int size) {
 
207
 
 
208
   int pos;
 
209
   int file, rank;
 
210
   int sq, piece;
 
211
   int c;
 
212
   int len;
 
213
 
 
214
   ASSERT(board_is_ok(board));
 
215
   ASSERT(string!=NULL);
 
216
   ASSERT(size>=92);
 
217
 
 
218
   // init
 
219
 
 
220
   if (size < 92) return false;
 
221
 
 
222
   pos = 0;
 
223
 
 
224
   // piece placement
 
225
 
 
226
   for (rank = 7; rank >= 0; rank--) {
 
227
 
 
228
      for (file = 0; file < 8;) {
 
229
 
 
230
         sq = square_make(file,rank);
 
231
         piece = board->square[sq];
 
232
         ASSERT(piece==Empty||piece_is_ok(piece));
 
233
 
 
234
         if (piece == Empty) {
 
235
 
 
236
            len = 0;
 
237
            for (; file < 8 && board->square[square_make(file,rank)] == Empty; file++) {
 
238
               len++;
 
239
            }
 
240
 
 
241
            ASSERT(len>=1&&len<=8);
 
242
            c = '0' + len;
 
243
 
 
244
         } else {
 
245
 
 
246
            c = piece_to_char(piece);
 
247
            file++;
 
248
         }
 
249
 
 
250
         string[pos++] = c;
 
251
      }
 
252
 
 
253
      string[pos++] = '/';
 
254
   }
 
255
 
 
256
   string[pos-1] = ' '; // HACK: remove the last '/'
 
257
 
 
258
   // active colour
 
259
 
 
260
   string[pos++] = (colour_is_white(board->turn)) ? 'w' : 'b';
 
261
   string[pos++] = ' ';
 
262
 
 
263
   // castling
 
264
 
 
265
   if (board->flags == FlagsNone) {
 
266
      string[pos++] = '-';
 
267
   } else {
 
268
      if ((board->flags & FlagsWhiteKingCastle)  != 0) string[pos++] = 'K';
 
269
      if ((board->flags & FlagsWhiteQueenCastle) != 0) string[pos++] = 'Q';
 
270
      if ((board->flags & FlagsBlackKingCastle)  != 0) string[pos++] = 'k';
 
271
      if ((board->flags & FlagsBlackQueenCastle) != 0) string[pos++] = 'q';
 
272
   }
 
273
 
 
274
   string[pos++] = ' ';
 
275
 
 
276
   // en-passant
 
277
 
 
278
   if (board->ep_square == SquareNone) {
 
279
      string[pos++] = '-';
 
280
   } else {
 
281
      if (!square_to_string(board->ep_square,&string[pos],3)) return false;
 
282
      pos += 2;
 
283
   }
 
284
 
 
285
   string[pos++] = ' ';
 
286
 
 
287
   // halfmove clock and fullmove number
 
288
 
 
289
   sprintf(&string[pos],"%d %d",board->ply_nb,board->move_nb+1);
 
290
 
 
291
   return true;
 
292
}
 
293
 
 
294
// end of fen.cpp
 
295