src/chess/pgn.c

changeset 98
9cb41383540f
parent 88
e4a648fe6ce7
equal deleted inserted replaced
97:f87cad9445b4 98:9cb41383540f
184 /* Result */ 184 /* Result */
185 char *result; 185 char *result;
186 if (gamestate->stalemate || gamestate->remis) { 186 if (gamestate->stalemate || gamestate->remis) {
187 result = "1/2-1/2"; 187 result = "1/2-1/2";
188 } else if (gamestate->checkmate || gamestate->resign) { 188 } else if (gamestate->checkmate || gamestate->resign) {
189 if (gamestate->lastmove) { 189 if (gamestate->movecount > 0) {
190 result = (gamestate->lastmove->move.piece & COLOR_MASK) == WHITE ? 190 result = (last_move(gamestate).piece & COLOR_MASK) == WHITE ?
191 "1-0" : "0-1"; 191 "1-0" : "0-1";
192 } else { 192 } else {
193 result = "0-1"; 193 result = "0-1";
194 } 194 }
195 } else { 195 } else {
196 result = "*"; 196 result = "*";
197 } 197 }
198 fprintf(stream, "[Result \"%s\"]\n\n", result); 198 fprintf(stream, "[Result \"%s\"]\n\n", result);
199 199
200 /* moves */ 200 /* moves */
201 int i = 1; 201 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
202 for (MoveList *movelist = gamestate->movelist ; 202
203 movelist ; movelist = movelist->next) { 203 if (i % 2 == 0) {
204 204 fprintf(stream, "%d. %s", 1+i/2, gamestate->moves[i].string);
205 if (++i % 2 == 0) {
206 fprintf(stream, "%d. %s", i/2, movelist->move.string);
207 } else { 205 } else {
208 fprintf(stream, " %s", movelist->move.string); 206 fprintf(stream, "%s", gamestate->moves[i].string);
209 } 207 }
210 208
211 // TODO: move time and maybe other comments 209 // TODO: move time and maybe other comments
212 210
213 /* line break every 10 moves */ 211 /* line break every 10 half-moves */
214 if ((i-1) % 20) { 212 if ((i+1) % 10) {
215 fputc(' ', stream); 213 fputc(' ', stream);
216 } else { 214 } else {
217 fputc('\n', stream); 215 fputc('\n', stream);
218 } 216 }
219 } 217 }
266 264
267 return i; 265 return i;
268 } 266 }
269 267
270 static size_t fen_color(char *str, GameState *gamestate) { 268 static size_t fen_color(char *str, GameState *gamestate) {
271 uint8_t color = opponent_color(gamestate->lastmove ? 269 uint8_t color = opponent_color(gamestate->movecount > 0 ?
272 (gamestate->lastmove->move.piece & COLOR_MASK) : BLACK); 270 (last_move(gamestate).piece & COLOR_MASK) : BLACK);
273 271
274 str[0] = color == WHITE ? 'w' : 'b'; 272 str[0] = color == WHITE ? 'w' : 'b';
275 273
276 return 1; 274 return 1;
277 } 275 }
278 276
279 static bool fen_castling_chkmoved(GameState *gamestate, 277 static bool fen_castling_chkmoved(GameState *gamestate,
280 uint8_t row, uint8_t file) { 278 uint8_t row, uint8_t file) {
281 279
282 MoveList *ml = gamestate->movelist; 280 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
283 while (ml) { 281 if (gamestate->moves[i].fromfile == file
284 if (ml->move.fromfile == file && ml->move.fromrow == row) { 282 && gamestate->moves[i].fromrow == row) {
285 return true; 283 return true;
286 } 284 }
287 ml = ml->next;
288 } 285 }
289 286
290 return false; 287 return false;
291 } 288 }
292 289
333 330
334 return str[0] == '-' ? 1 : 2; 331 return str[0] == '-' ? 1 : 2;
335 } 332 }
336 333
337 static size_t fen_halfmove(char *str, GameState *gamestate) { 334 static size_t fen_halfmove(char *str, GameState *gamestate) {
338 335 unsigned int hm = 0;
339 unsigned int i = 0; 336 for (unsigned int i = 0; i < gamestate->movecount; i++) {
340 for (MoveList *move = gamestate->movelist ; move ; move = move->next) { 337 if (gamestate->moves[i].capture
341 if (move->move.capture || (move->move.piece & PIECE_MASK) == PAWN) { 338 || (gamestate->moves[i].piece & PIECE_MASK) == PAWN) {
342 i = 0; 339 hm = 0;
343 } else { 340 } else {
344 i++; 341 hm++;
345 } 342 }
346 } 343 }
347 344
348 char m[8]; 345 return sprintf(str, "%u", hm);
349 size_t len = sprintf(m, "%u", i);
350 memcpy(str, m, len);
351
352 return len;
353 } 346 }
354 347
355 static size_t fen_movenr(char *str, GameState *gamestate) { 348 static size_t fen_movenr(char *str, GameState *gamestate) {
356 349 return sprintf(str, "%u", gamestate->movecount);
357 MoveList *move = gamestate->movelist;
358 unsigned int i = 1;
359 while (move) {
360 i++;
361 move = move->next;
362 }
363
364 char m[8];
365 size_t len = sprintf(m, "%u", i);
366 memcpy(str, m, len);
367
368 return len;
369 } 350 }
370 351
371 void compute_fen(char *str, GameState *gamestate) { 352 void compute_fen(char *str, GameState *gamestate) {
372 str += fen_pieces(str, gamestate); 353 str += fen_pieces(str, gamestate);
373 *str = ' '; str++; 354 *str = ' '; str++;

mercurial