Парсер FEN на Си
Feb. 13th, 2012 10:07 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
А не распарсить ли мне FEN на Сях, раз такая пьянка? Распаршу:
#include <assert.h> #include <ctype.h> #include <stdio.h> #define RANK "%8[12345678PNBRQKpnbrqk]" #define ENPASS "%2[abcdefgh12345678-]" #define FEN \ RANK "/" RANK "/" RANK "/" RANK "/" \ RANK "/" RANK "/" RANK "/" RANK " " \ "%1[wb] %4[KQkq-] " ENPASS " %*2d %*d\n" #define RANKS(board) \ (board)[7], (board)[6], (board)[5], (board)[4], \ (board)[3], (board)[2], (board)[1], (board)[0]
static fen() { struct { char board[8][9]; int enpassi, enpassj; enum { WHITE, BLACK } act; struct { int cshort, clong; } white, black; } pos; char buf[8][9], act[2], cast[5], enpass[3]; int n, i, j; n = scanf(FEN, RANKS(buf), act, cast, enpass); assert(11 == n); pos.act = ('w' == act[0]) ? WHITE : BLACK; pos.enpassi = enpass[1] - '1'; pos.enpassj = enpass[0] - 'a'; pos.white.cshort = ('K' == cast[0]); pos.white.clong = ('Q' == cast[1]); pos.black.cshort = ('k' == cast[2]); pos.black.clong = ('q' == cast[3]); for (i = 0; i < 8; i++) { const char *src = buf[i]; char *dst = pos.board[i]; int sq = 0; for (j = 0; j < 8; j++) { char piece = src[j]; if (!piece) { assert(8 == sq); break; } else if (isdigit(piece)) { int skip = piece - '0'; while (skip) { assert(sq < 8); dst[sq] = '.'; ++sq; --skip; } } else { assert(sq < 8); dst[sq] = src[j]; ++sq; } } } for (i = 7; i > -1; i--) printf("%.8s\n", pos.board[i]); printf("%s's move\n", pos.act ? "Black" : "White"); return 0; } main() { while (!feof(stdin)) fen(); return 0; }