src/chess/pgn.c

Fri, 17 Apr 2026 12:00:18 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 17 Apr 2026 12:00:18 +0200
changeset 102
463c648e6a9b
parent 101
d4f19182fdc2
child 106
bdc9528d3e2b
permissions
-rw-r--r--

change return type of write_pgn to void

The return value was always unused and zero.
Then intention apparently was to return the number
of written bytes, but that never happened.

50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
1 /*
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
3 *
55
54ea19938d57 updated copyright and version info
Mike Becker <universe@uap-core.de>
parents: 54
diff changeset
4 * Copyright 2016 Mike Becker. All rights reserved.
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
5 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
6 * Redistribution and use in source and binary forms, with or without
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
7 * modification, are permitted provided that the following conditions are met:
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
8 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
9 * 1. Redistributions of source code must retain the above copyright
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
10 * notice, this list of conditions and the following disclaimer.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
11 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
12 * 2. Redistributions in binary form must reproduce the above copyright
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
13 * notice, this list of conditions and the following disclaimer in the
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
14 * documentation and/or other materials provided with the distribution.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
15 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
26 * POSSIBILITY OF SUCH DAMAGE.
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
27 *
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
28 */
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
29
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
30 #include "pgn.h"
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
31 #include <ctype.h>
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
32 #include <string.h>
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
33
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
34 enum {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
35 pgn_error_missing_quote = 1,
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
36 pgn_error_missing_bracket,
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
37 pgn_error_missing_brace,
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
38 pgn_error_missing_dot,
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
39 pgn_error_move_syntax,
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
40 pgn_error_move_semantics
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
41 };
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
42
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
43 static const char* pgn_error_strings[] = {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
44 "No Error.",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
45 "Tag values must be enclosed in double-quotes.",
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
46 "Missing closing brace '}' for comment.",
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
47 "Tags must be enclosed in square brackets: '[Key \"Value\"]'.",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
48 "Move numbers must be terminated with a dot (e.g. '13.' - not '13').",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
49 "Move is syntactically incorrect.",
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
50 "Move is not valid according to chess rules."
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
51 };
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
52
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
53 const char* pgn_error_str(int code) {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
54 return pgn_error_strings[code];
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
55 }
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
56
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
57 int read_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
58 int c, i;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
59
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
60 char result[8];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
61
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
62 char tagkey[32];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
63 char tagvalue[128];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
64
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
65 /* read tag pairs */
82
e75865d90111 remove unnecessary loop variable
Mike Becker <universe@uap-core.de>
parents: 81
diff changeset
66 while (true) {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
67 while (isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
68 if (c == '1') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
69 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
70 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
71 if (c != '[') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
72 return pgn_error_missing_bracket;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
73 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
74 while (isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
75 i = 0;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
76 do {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
77 tagkey[i++] = c;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
78 } while (!isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
79 tagkey[i] = '\0';
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
80 while (isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
81 if (c != '"') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
82 return pgn_error_missing_quote;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
83 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
84 i = 0;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
85 while ((c = fgetc(stream)) != '"') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
86 if (c == '\n' || c == EOF) {
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
87 return pgn_error_missing_quote;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
88 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
89 tagvalue[i++] = c;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
90 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
91 tagvalue[i] = '\0';
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
92 if (fgetc(stream) != ']') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
93 return pgn_error_missing_bracket;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
94 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
95
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
96 if (strcmp("Result", tagkey) == 0) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
97 memcpy(result, tagvalue, 8);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
98 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
99 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
100
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
101 /* read moves */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
102 if (fgetc(stream) != '.') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
103 return pgn_error_missing_dot;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
104 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
105
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
106 char movestr[10];
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
107 Move move;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
108 uint8_t curcol = WHITE;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
109
82
e75865d90111 remove unnecessary loop variable
Mike Becker <universe@uap-core.de>
parents: 81
diff changeset
110 while (true) {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
111 /* move */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
112 while (isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
113 i = 0;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
114 do {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
115 movestr[i++] = c;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
116 if (i >= 10) {
81
82d3b044aa69 fix incorrect error value when a move string is too long in a PGN
Mike Becker <universe@uap-core.de>
parents: 80
diff changeset
117 return pgn_error_move_syntax;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
118 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
119 } while (!isspace(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
120 movestr[i] = '\0';
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
121 if (eval_move(gamestate, movestr, &move, curcol)
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
122 != VALID_MOVE_SYNTAX) {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
123 return pgn_error_move_syntax;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
124 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
125 if (validate_move(gamestate, &move) != VALID_MOVE_SEMANTICS) {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
126 return pgn_error_move_semantics;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
127 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
128 apply_move(gamestate, &move);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
129
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
130 /* skip spaces */
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
131 while (isspace(c = fgetc(stream)));
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
132
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
133 /* parse possible comment */
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
134 if (c == '{') {
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
135 // TODO: interpret comment (may contain clock info)
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
136 do {
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
137 c = fgetc(stream);
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
138 } while (c != '}' && c != EOF);
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
139 if (c == EOF) {
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
140 return pgn_error_missing_brace;
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
141 }
88
e4a648fe6ce7 fix PGN parser
Mike Becker <universe@uap-core.de>
parents: 82
diff changeset
142 /* skip spaces */
e4a648fe6ce7 fix PGN parser
Mike Becker <universe@uap-core.de>
parents: 82
diff changeset
143 while (isspace(c = fgetc(stream)));
70
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
144 }
5427beba96d1 pgn parser can now handle comments (although it ignores them for now)
Mike Becker <universe@uap-core.de>
parents: 65
diff changeset
145
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
146 /* end of game data encountered */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
147 if (c == EOF) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
148 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
149 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
150 if (c == '1' || c == '0') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
151 c = fgetc(stream);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
152 if (c == '-') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
153 gamestate->resign = !gamestate->checkmate;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
154 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
155 } else if (c == '/') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
156 gamestate->remis = !gamestate->stalemate;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
157 break;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
158 } else {
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
159 /* oops, it was a move number, go back! */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
160 fseek(stream, -1, SEEK_CUR);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
161 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
162 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
163
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
164 /* we have eaten the next valuable byte, so go back */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
165 fseek(stream, -1, SEEK_CUR);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
166
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
167 /* skip move number after black move */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
168 if (curcol == BLACK) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
169 while (isdigit(c = fgetc(stream)));
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
170 if (c != '.') {
60
0c50aac49e55 adds error messages to PGN reader
Mike Becker <universe@uap-core.de>
parents: 59
diff changeset
171 return pgn_error_missing_dot;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
172 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
173 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
174 curcol = opponent_color(curcol);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
175 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
176
59
3fa1de896666 fixes inappropriate use of EXIT_ macros + adds a sample PGN file
Mike Becker <universe@uap-core.de>
parents: 55
diff changeset
177 return 0;
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
178 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
179
102
463c648e6a9b change return type of write_pgn to void
Mike Becker <universe@uap-core.de>
parents: 101
diff changeset
180 void write_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo) {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
181 // TODO: tag pairs
102
463c648e6a9b change return type of write_pgn to void
Mike Becker <universe@uap-core.de>
parents: 101
diff changeset
182
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
183 /* Result */
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
184 char *result;
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
185 if (gamestate->stalemate || gamestate->remis) {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
186 result = "1/2-1/2";
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
187 } else if (gamestate->checkmate || gamestate->resign) {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
188 if (gamestate->movecount > 0) {
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
189 result = (last_move(gamestate).piece & COLOR_MASK) == WHITE ?
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
190 "1-0" : "0-1";
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
191 } else {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
192 result = "0-1";
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
193 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
194 } else {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
195 result = "*";
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
196 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
197 fprintf(stream, "[Result \"%s\"]\n\n", result);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
198
64
4eda5df55f86 fixes castling not printed correctly to PGN
Mike Becker <universe@uap-core.de>
parents: 60
diff changeset
199 /* moves */
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
200 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
201
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
202 if (i % 2 == 0) {
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
203 fprintf(stream, "%d. %s", 1+i/2, gamestate->moves[i].string);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
204 } else {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
205 fprintf(stream, "%s", gamestate->moves[i].string);
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
206 }
101
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
207
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
208 /* add clock times when the game was under time control */
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
209 if (gameinfo->timecontrol) {
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
210 char clkstr[16];
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
211 unsigned clkmv = i + 2; /* time for the next move! */
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
212 uint16_t clk = remaining_movetime2(gameinfo, gamestate, clkmv);
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
213 print_clk(clk, clkstr, true);
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
214 fprintf(stream, " {[%%clk %s]}", clkstr);
d4f19182fdc2 add clock times to PGN output
Mike Becker <universe@uap-core.de>
parents: 98
diff changeset
215 }
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
216
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
217 /* line break every 10 half-moves */
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
218 if ((i+1) % 10) {
50
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
219 fputc(' ', stream);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
220 } else {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
221 fputc('\n', stream);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
222 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
223 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
224
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
225 if (result[0] == '*') {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
226 fputc('\n', stream);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
227 } else {
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
228 fprintf(stream, "%s\n", result);
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
229 }
41017d0a72c5 added pgn parser and writer (without comment support yet) + minor refactorings
Mike Becker <universe@uap-core.de>
parents:
diff changeset
230 }
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
231
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
232 static size_t fen_pieces(char *str, GameState *gamestate) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
233 size_t i = 0;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
234 for (int row = 7 ; row >= 0 ; row--) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
235 unsigned int skip = 0;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
236 for (int file = 0 ; file < 8 ; file++) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
237 if (gamestate->board[row][file]) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
238 if (skip > 0) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
239 str[i++] = '0'+skip;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
240 skip = 0;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
241 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
242 switch (gamestate->board[row][file] & ~ENPASSANT_THREAT) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
243 case WHITE|KING: str[i++] = 'K'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
244 case WHITE|QUEEN: str[i++] = 'Q'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
245 case WHITE|BISHOP: str[i++] = 'B'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
246 case WHITE|KNIGHT: str[i++] = 'N'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
247 case WHITE|ROOK: str[i++] = 'R'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
248 case WHITE|PAWN: str[i++] = 'P'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
249 case BLACK|KING: str[i++] = 'k'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
250 case BLACK|QUEEN: str[i++] = 'q'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
251 case BLACK|BISHOP: str[i++] = 'b'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
252 case BLACK|KNIGHT: str[i++] = 'n'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
253 case BLACK|ROOK: str[i++] = 'r'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
254 case BLACK|PAWN: str[i++] = 'p'; break;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
255 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
256 } else {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
257 skip++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
258 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
259 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
260 if (skip > 0) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
261 str[i++] = '0'+skip;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
262 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
263 if (row > 0) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
264 str[i++] = '/';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
265 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
266 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
267
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
268 return i;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
269 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
270
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
271 static size_t fen_color(char *str, GameState *gamestate) {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
272 uint8_t color = opponent_color(gamestate->movecount > 0 ?
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
273 (last_move(gamestate).piece & COLOR_MASK) : BLACK);
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
274
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
275 str[0] = color == WHITE ? 'w' : 'b';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
276
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
277 return 1;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
278 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
279
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
280 static bool fen_castling_chkmoved(GameState *gamestate,
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
281 uint8_t row, uint8_t file) {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
282
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
283 for (unsigned i = 0 ; i < gamestate->movecount ; i++) {
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
284 if (gamestate->moves[i].fromfile == file
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
285 && gamestate->moves[i].fromrow == row) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
286 return true;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
287 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
288 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
289
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
290 return false;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
291 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
292
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
293 static size_t fen_castling(char *str, GameState *gamestate) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
294 bool K, Q, k, q;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
295
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
296 if (fen_castling_chkmoved(gamestate, rowidx('1'), fileidx('e'))) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
297 K = Q = false;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
298 } else {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
299 K = !fen_castling_chkmoved(gamestate, rowidx('1'), fileidx('h'));
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
300 Q = !fen_castling_chkmoved(gamestate, rowidx('1'), fileidx('a'));
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
301 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
302 if (fen_castling_chkmoved(gamestate, rowidx('8'), fileidx('e'))) {
80
b980a7192b5a replace _Bool with bool from C23 and/or stdbool.h
Mike Becker <universe@uap-core.de>
parents: 78
diff changeset
303 k = q = false;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
304 } else {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
305 k = !fen_castling_chkmoved(gamestate, rowidx('8'), fileidx('h'));
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
306 q = !fen_castling_chkmoved(gamestate, rowidx('8'), fileidx('a'));
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
307 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
308
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
309 size_t i = 0;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
310 if (K) str[i++] = 'K';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
311 if (Q) str[i++] = 'Q';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
312 if (k) str[i++] = 'k';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
313 if (q) str[i++] = 'q';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
314 if (!i) str[i++] = '-';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
315
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
316 return i;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
317 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
318
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
319 static size_t fen_enpassant(char *str, GameState *gamestate) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
320
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
321 str[0] = '-'; str[1] = '\0';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
322
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
323 for (int file = 0 ; file < 8 ; file++) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
324 if (gamestate->board[3][file] & ENPASSANT_THREAT) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
325 str[0] = filechr(file);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
326 str[1] = rowchr(2);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
327 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
328 if (gamestate->board[4][file] & ENPASSANT_THREAT) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
329 str[0] = filechr(file);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
330 str[1] = rowchr(5);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
331 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
332 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
333
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
334 return str[0] == '-' ? 1 : 2;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
335 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
336
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
337 static size_t fen_halfmove(char *str, GameState *gamestate) {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
338 unsigned int hm = 0;
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
339 for (unsigned int i = 0; i < gamestate->movecount; i++) {
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
340 if (gamestate->moves[i].capture
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
341 || (gamestate->moves[i].piece & PIECE_MASK) == PAWN) {
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
342 hm = 0;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
343 } else {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
344 hm++;
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
345 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
346 }
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
347
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
348 return sprintf(str, "%u", hm);
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
349 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
350
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
351 static size_t fen_movenr(char *str, GameState *gamestate) {
98
9cb41383540f change move list from linked list to array (prepares game replays)
Mike Becker <universe@uap-core.de>
parents: 88
diff changeset
352 return sprintf(str, "%u", gamestate->movecount);
54
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
353 }
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
354
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
355 void compute_fen(char *str, GameState *gamestate) {
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
356 str += fen_pieces(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
357 *str = ' '; str++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
358 str += fen_color(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
359 *str = ' '; str++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
360 str += fen_castling(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
361 *str = ' '; str++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
362 str += fen_enpassant(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
363 *str = ' '; str++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
364 str += fen_halfmove(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
365 *str = ' '; str++;
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
366 str += fen_movenr(str, gamestate);
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
367 str[0] = '\0';
eef745ba3774 implemented FEN
Mike Becker <universe@uap-core.de>
parents: 50
diff changeset
368 }

mercurial