Introduction
Introduction Statistics Contact Development Disclaimer Help
fen_to_ascii.c - chess-puzzles - chess puzzle book generator
git clone git://git.codemadness.org/chess-puzzles
Log
Files
Refs
README
LICENSE
---
fen_to_ascii.c (5802B)
---
1 /* TODO: option to flip board? */
2
3 #include <ctype.h>
4 #include <stdio.h>
5 #include <string.h>
6
7 static char board[8][8];
8 static char highlight[8][8];
9
10 static int side_to_move = 'w'; /* default: white to move */
11 static int white_can_castle[2] = { 0, 0 }; /* allow king side, allow que…
12 static int black_can_castle[2] = { 0, 0 }; /* allow king side, allow que…
13
14 static const int showcoords = 1; /* config: show board coordinates? */
15
16 int
17 isvalidsquare(int x, int y)
18 {
19 return !(x < 0 || x >= 8 || y < 0 || y >= 8);
20 }
21
22 /* place a piece, if possible */
23 void
24 place(int piece, int x, int y)
25 {
26 if (!isvalidsquare(x, y))
27 return;
28
29 board[y][x] = piece;
30 }
31
32 /* get piece, if possible */
33 int
34 getpiece(int x, int y)
35 {
36 if (!isvalidsquare(x, y))
37 return 0;
38 return board[y][x];
39 }
40
41 int
42 squaretoxy(const char *s, int *x, int *y)
43 {
44 if (*s >= 'a' && *s <= 'h' &&
45 *(s + 1) >= '1' && *(s + 1) <= '8') {
46 *x = *s - 'a';
47 *y = '8' - *(s + 1);
48 return 1;
49 }
50 return 0;
51 }
52
53 void
54 highlightmove(int x1, int y1, int x2, int y2)
55 {
56 if (isvalidsquare(x1, y1))
57 highlight[y1][x1] = 1;
58
59 if (isvalidsquare(x2, y2))
60 highlight[y2][x2] = 1;
61 }
62
63 void
64 showpiece(int c)
65 {
66 const char *s = "";
67
68 /* simple or use unicode character */
69 #if 1
70 putchar(c);
71 return;
72 #endif
73
74 switch (c) {
75 case 'K': s = "♔"; break;
76 case 'Q': s = "♕"; break;
77 case 'R': s = "♖"; break;
78 case 'B': s = "♗"; break;
79 case 'N': s = "♘"; break;
80 case 'P': s = "♙"; break;
81 case 'k': s = "♚"; break;
82 case 'q': s = "♛"; break;
83 case 'r': s = "♜"; break;
84 case 'b': s = "♝"; break;
85 case 'n': s = "♞"; break;
86 case 'p': s = "♟"; break;
87 }
88
89 if (*s)
90 fputs(s, stdout);
91 }
92
93 void
94 showboardfen(void)
95 {
96 int x, y, piece, skip = 0;
97
98 for (y = 0; y < 8; y++) {
99 if (y > 0)
100 putchar('/');
101 skip = 0;
102 for (x = 0; x < 8; x++) {
103 piece = getpiece(x, y);
104 if (piece) {
105 if (skip)
106 putchar(skip + '0');
107 putchar(piece);
108 skip = 0;
109 } else {
110 skip++;
111 }
112 }
113 if (skip)
114 putchar(skip + '0');
115 }
116
117 /* ? TODO: detect en passant, invalid castling etc? */
118 }
119
120 /* show board */
121 /* TODO: show fancier, unicode and background square color */
122 /* TODO: use the output format similar to stockfish "d" command */
123 void
124 showboard(void)
125 {
126 int x, y, piece;
127
128 printf("Board FEN:\n");
129 showboardfen();
130 printf("\n\n");
131
132 for (y = 0; y < 8; y++) {
133 printf("+---+---+---+---+---+---+---+---+\n");
134 for (x = 0; x < 8; x++) {
135 if (x == 0)
136 putchar('|');
137 fputs(" ", stdout);
138 piece = getpiece(x, y);
139 if (piece)
140 showpiece(piece);
141 else
142 fputs(" ", stdout);
143 fputs(" ", stdout);
144 putchar('|');
145 }
146 if (showcoords) {
147 putchar(' ');
148 putchar('8' - y);
149 }
150 putchar('\n');
151 }
152 printf("+---+---+---+---+---+---+---+---+\n");
153 if (showcoords)
154 printf(" a | b | c | d | e | f | g | h |\n");
155
156 fputs("\n", stdout);
157
158 #if 0
159 if (side_to_move == 'w') {
160 fputs("White to move\n", stdout);
161 } else if (side_to_move == 'b')
162 fputs("Black to move\n", stdout);
163
164 if (white_can_castle[0])
165 fputs("White can castle king side\n", stdout);
166 if (white_can_castle[1])
167 fputs("White can castle queen side\n", stdout);
168 if (black_can_castle[0])
169 fputs("Black can castle king side\n", stdout);
170 if (black_can_castle[1])
171 fputs("Black can castle queen side\n", stdout);
172 #endif
173 }
174
175 int
176 main(int argc, char *argv[])
177 {
178 const char *fen, *moves, *s;
179 int x, y, x2, y2, field, piece;
180 char pieces[] = "PNBRQKpnbrqk", square[3];
181
182 if (argc != 3) {
183 fprintf(stderr, "usage: %s <FEN> <moves>\n", argv[0]);
184 return 1;
185 }
186
187 fen = argv[1];
188 moves = argv[2];
189
190 /* initial board state, FEN format */
191 x = y = field = 0;
192 for (s = fen; *s; s++) {
193 /* next field, fields are: piece placement data, active …
194 Castling availability, En passant target square,
195 Halfmove clock, Fullmove number */
196 if (*s == ' ') {
197 field++;
198 continue;
199 }
200
201 switch (field) {
202 case 0: /* piece placement data */
203 /* skip square */
204 if (*s >= '1' && *s <= '9') {
205 x += (*s - '0');
206 continue;
207 }
208 /* next rank */
209 if (*s == '/') {
210 x = 0;
211 y++;
212 continue;
213 }
214 /* is piece? place it */
215 if (strchr(pieces, *s))
216 place(*s, x++, y);
217 break;
218 case 1: /* active color */
219 if (*s == 'w' || *s == 'b')
220 side_to_move = *s;
221 break;
222 case 2: /* castling availability */
223 if (*s == '-') {
224 white_can_castle[0] = 0;
225 white_can_castle[1] = 0;
226 black_can_castle[0] = 0;
227 black_can_castle[1] = 0;
228 } else if (*s == 'K') {
229 white_can_castle[0] = 1;
230 } else if (*s == 'Q') {
231 white_can_castle[1] = 1;
232 } else if (*s == 'k') {
233 black_can_castle[0] = 1;
234 } else if (*s == 'q') {
235 black_can_castle[1] = 1;
236 }
237 break;
238 case 3: /* TODO: en-passant square, rest of the fields */
239 break;
240 }
241 /* TODO: parse which side to move, en-passant, etc */
242 }
243
244 /* process moves */
245 square[2] = '\0';
246 x = y = x2 = y2 = -1;
247 for (s = moves; *s; s++) {
248 if (*s == ' ')
249 continue;
250 if ((*s >= 'a' && *s <= 'h') &&
251 (*(s + 1) >= '1' && *(s + 1) <= '8') &&
252 (*(s + 2) >= 'a' && *(s + 2) <= 'h') &&
253 (*(s + 3) >= '1' && *(s + 3) <= '8')) {
254 square[0] = *s;
255 square[1] = *(s + 1);
256
257 s += 2;
258 squaretoxy(square, &x, &y);
259 piece = getpiece(x, y);
260
261 place(0, x, y); /* clear square */
262
263 /* place piece at new location */
264 square[0] = *s;
265 square[1] = *(s + 1);
266 squaretoxy(square, &x2, &y2);
267 place(piece, x2, y2);
268 s += 2;
269
270 /* possible promotion? (queen, knight, bishop) */
271 if (*s == 'q' || *s == 'n' || *s == 'b') {
272 if (side_to_move == 'w')
273 piece = toupper(*s);
274 else
275 piece = *s;
276 place(piece, x2, y2);
277 s++;
278 }
279
280 /* switch which side it is to move */
281 side_to_move = side_to_move == 'b' ? 'w' : 'b';
282 }
283 }
284 /* highlight last move */
285 highlightmove(x, y, x2, y2);
286
287 showboard();
288
289 return 0;
290 }
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.