#include #include #include #include #include #include #include #define BUFF_SIZE 4096 typedef struct { long long pawns; long long knights; long long bishops; long long rooks; long long queen; long long king; } sets; typedef struct { sets white; sets black; bool whiteToMove; } game; game *fenGame(char *str); void playMoves(game *g, char *moves); long long *findSet(game *g, long long bit); long long *charToSet(game *g, char c); void print_bitboard(long long bitboard) { for (int i = 63; i >= 0; i--) { // Check if the i-th bit is set if ((bitboard >> i) & 1) { printf("1 "); } else { printf("0 "); } // Print a newline every 8 bits (for rows) if (i % 8 == 0) { printf("\n"); } } printf("\n"); } int main() { setbuf(stdin, NULL); setbuf(stdout, NULL); game *g = NULL; char line[BUFF_SIZE]; char *lineRest, *token; char ltz[] = "abcdefgh"; int cnt = 0; while (1) { (void)fgets(line, sizeof(line), stdin); size_t len = strlen(line); if (len - 1) line[len - 1] = '\0'; token = strtok_r(line, " ", &lineRest); if (!strcmp("uci", token)) { printf("id name RatChess 0.0\n"); printf("id author rat<3\n"); printf("uciok\n"); } else if (!strcmp("quit", token)) { return 0; } else if (!strcmp("setoption", token)) { } else if (!strcmp("position", token)) { token = strtok_r(lineRest, " ", &lineRest); if (!strcmp("fen", token)) { g = fenGame(lineRest + 1); for (int i = 0; i < 6; i++) token = strtok_r(lineRest, " ", &lineRest); } else { g = fenGame("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"); } playMoves(g, lineRest); printf("info pawns\n"); print_bitboard(g->white.pawns | g->black.pawns); } else if (!strcmp("ucinewgame", token)) { } else if (!strcmp("isready", token)) { printf("readyok\n"); } else if (!strcmp("go", token)) { if (g->whiteToMove) { printf("bestmove %c2%c4\n", ltz[cnt], ltz[cnt]); } else { printf("bestmove %c7%c5\n", ltz[cnt], ltz[cnt]); } cnt++; } } } long long *charToSet(game *g, char c) { switch (c) { case 'P': return &g->white.pawns; case 'N': return &g->white.knights; case 'B': return &g->white.bishops; case 'R': return &g->white.rooks; case 'Q': return &g->white.queen; case 'K': return &g->white.king; case 'p': return &g->black.pawns; case 'n': return &g->black.knights; case 'b': return &g->black.bishops; case 'r': return &g->black.rooks; case 'q': return &g->black.queen; case 'k': return &g->black.king; default: return NULL; } } game *fenGame(char *str) { int rank = 7; int file = 0; size_t pos = 0; game *g; g = malloc(sizeof(game)); memset(g, 0, sizeof(game)); while (str[pos] != '\0' && str[pos] != ' ') { char current_char = *str; if (isdigit(*str)) { int empty_squares = *str - '0'; file += empty_squares; str++; continue; } if (current_char == '/') { rank--; file = 0; str++; continue; } long long bit = 1LL << (rank * 8 + file); long long *set = charToSet(g, *str); if (set) *set |= bit; file++; str++; } str++; g->whiteToMove = (*str == 'w') ? true : false; return g; } void playMoves(game *g, char *moves) { char *move; move = strtok_r(moves, " ", &moves); move = strtok_r(moves, " ", &moves); while (move) { long long bit = 1LL << ((move[1] - '0' - 1) * 8 + (move[0] - 'a')); long long *set = findSet(g, bit); if (!set) { printf("info fuck\n"); return; } *set &= (~bit); bit = 1LL << ((move[3] - '0' - 1) * 8 + (move[2] - 'a')); long long *tmp = findSet(g, bit); if (tmp) *tmp &= (~bit); if (strlen(move) == 5) { set = charToSet(g, move[4]); } *set |= bit; move = strtok_r(moves, " ", &moves); g->whiteToMove = !g->whiteToMove; } } long long *findSet(game *g, long long bit) { if (g->white.pawns & bit) { return &g->white.pawns; } else if (g->white.knights & bit) { return &g->white.knights; } else if (g->white.bishops & bit) { return &g->white.bishops; } else if (g->white.rooks & bit) { return &g->white.rooks; } else if (g->white.queen & bit) { return &g->white.queen; } else if (g->white.king & bit) { return &g->white.king; } else if (g->black.pawns & bit) { return &g->black.pawns; } else if (g->black.knights & bit) { return &g->black.knights; } else if (g->black.bishops & bit) { return &g->black.bishops; } else if (g->black.rooks & bit) { return &g->black.rooks; } else if (g->black.queen & bit) { return &g->black.queen; } else if (g->black.king & bit) { return &g->black.king; } else { return NULL; } }