src/chess/pgn.c

changeset 64
4eda5df55f86
parent 60
0c50aac49e55
child 65
dcc5bd2c56c0
equal deleted inserted replaced
63:611332453da0 64:4eda5df55f86
59 char result[8]; 59 char result[8];
60 60
61 char tagkey[32]; 61 char tagkey[32];
62 char tagvalue[128]; 62 char tagvalue[128];
63 63
64 // read tag pairs 64 /* read tag pairs */
65 _Bool readmoves = 0; 65 _Bool readmoves = 0;
66 while (!readmoves) { 66 while (!readmoves) {
67 while (isspace(c = fgetc(stream))); 67 while (isspace(c = fgetc(stream)));
68 if (c == '1') { 68 if (c == '1') {
69 readmoves = 1; 69 readmoves = 1;
97 if (strcmp("Result", tagkey) == 0) { 97 if (strcmp("Result", tagkey) == 0) {
98 memcpy(result, tagvalue, 8); 98 memcpy(result, tagvalue, 8);
99 } 99 }
100 } 100 }
101 101
102 // read moves 102 /* read moves */
103 if (fgetc(stream) != '.') { 103 if (fgetc(stream) != '.') {
104 return pgn_error_missing_dot; 104 return pgn_error_missing_dot;
105 } 105 }
106 106
107 char movestr[10]; 107 char movestr[10];
108 Move move; 108 Move move;
109 uint8_t curcol = WHITE; 109 uint8_t curcol = WHITE;
110 110
111 while (readmoves) { 111 while (readmoves) {
112 // move 112 /* move */
113 while (isspace(c = fgetc(stream))); 113 while (isspace(c = fgetc(stream)));
114 i = 0; 114 i = 0;
115 do { 115 do {
116 movestr[i++] = c; 116 movestr[i++] = c;
117 if (i >= 10) { 117 if (i >= 10) {
129 apply_move(gamestate, &move); 129 apply_move(gamestate, &move);
130 130
131 // TODO: parse comments 131 // TODO: parse comments
132 while (isspace(c = fgetc(stream))); 132 while (isspace(c = fgetc(stream)));
133 133
134 // end of game data encountered 134 /* end of game data encountered */
135 if (c == EOF) { 135 if (c == EOF) {
136 break; 136 break;
137 } 137 }
138 if (c == '1' || c == '0') { 138 if (c == '1' || c == '0') {
139 c = fgetc(stream); 139 c = fgetc(stream);
142 break; 142 break;
143 } else if (c == '/') { 143 } else if (c == '/') {
144 gamestate->remis = !gamestate->stalemate; 144 gamestate->remis = !gamestate->stalemate;
145 break; 145 break;
146 } else { 146 } else {
147 // oops, it was a move number, go back! 147 /* oops, it was a move number, go back! */
148 fseek(stream, -1, SEEK_CUR); 148 fseek(stream, -1, SEEK_CUR);
149 } 149 }
150 } 150 }
151 151
152 // we have eaten the next valuable byte, so go back 152 /* we have eaten the next valuable byte, so go back */
153 fseek(stream, -1, SEEK_CUR); 153 fseek(stream, -1, SEEK_CUR);
154 154
155 // skip move number after black move 155 /* skip move number after black move */
156 if (curcol == BLACK) { 156 if (curcol == BLACK) {
157 while (isdigit(c = fgetc(stream))); 157 while (isdigit(c = fgetc(stream)));
158 if (c != '.') { 158 if (c != '.') {
159 return pgn_error_missing_dot; 159 return pgn_error_missing_dot;
160 } 160 }
167 167
168 size_t write_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo) { 168 size_t write_pgn(FILE* stream, GameState *gamestate, GameInfo *gameinfo) {
169 // TODO: tag pairs 169 // TODO: tag pairs
170 size_t bytes = 0; 170 size_t bytes = 0;
171 171
172 // Result 172 /* Result */
173 char *result; 173 char *result;
174 if (gamestate->stalemate || gamestate->remis) { 174 if (gamestate->stalemate || gamestate->remis) {
175 result = "1/2-1/2"; 175 result = "1/2-1/2";
176 } else if (gamestate->checkmate || gamestate->resign) { 176 } else if (gamestate->checkmate || gamestate->resign) {
177 if (gamestate->lastmove) { 177 if (gamestate->lastmove) {
183 } else { 183 } else {
184 result = "*"; 184 result = "*";
185 } 185 }
186 fprintf(stream, "[Result \"%s\"]\n\n", result); 186 fprintf(stream, "[Result \"%s\"]\n\n", result);
187 187
188 // moves 188 /* moves */
189 int i = 1; 189 int i = 1;
190 for (MoveList *movelist = gamestate->movelist ; 190 for (MoveList *movelist = gamestate->movelist ;
191 movelist ; movelist = movelist->next) { 191 movelist ; movelist = movelist->next) {
192 192
193 if (++i % 2 == 0) { 193 if (++i % 2 == 0) {
196 fprintf(stream, " %s", movelist->move.string); 196 fprintf(stream, " %s", movelist->move.string);
197 } 197 }
198 198
199 // TODO: move time and maybe other comments 199 // TODO: move time and maybe other comments
200 200
201 // line break every 10 moves 201 /* line break every 10 moves */
202 if (i % 20) { 202 if (i % 20) {
203 fputc(' ', stream); 203 fputc(' ', stream);
204 } else { 204 } else {
205 fputc('\n', stream); 205 fputc('\n', stream);
206 } 206 }

mercurial