X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=booklook.c;h=01c734872e72b91a9fd6bc2ff6875432afdae185;hp=c9eea593c853ddb648ec7a4d647a0290fb6aedeb;hb=944e74aaa3c5b3038d16d8be1461be6f6f33a4b4;hpb=96cd2398965d355262bae77bd270a0f5bbf8069c diff --git a/booklook.c b/booklook.c index c9eea59..01c7348 100644 --- a/booklook.c +++ b/booklook.c @@ -4,6 +4,9 @@ #include #include +#define DUMP_FEN 0 +#define DUMP_ENC 0 + int cto_fd, ctg_fd, ctb_fd; unsigned int tbl2[] = { @@ -161,6 +164,45 @@ void invert_board(char *board) } } +int needs_flipping(char *board, char *castling_rights) +{ + int y, x; + + // never flip if either side can castle + if (strcmp(castling_rights, "-") != 0) + return 0; + + for (y = 0; y < 8; ++y) { + for (x = 0; x < 4; ++x) { + if (board[y * 8 + x] == 'K') + return 1; + } + } + + return 0; +} + +// horizontal flip +void flip_board(char *board, char *eps) +{ + int y, x; + + // flip the board + for (y = 0; y < 8; ++y) { + for (x = 0; x < 4; ++x) { + char tmp = board[y * 8 + x]; + board[y * 8 + (x)] = board[y * 8 + (7-x)]; + board[y * 8 + (7-x)] = tmp; + } + } + + // flip the en passant square + if (strcmp(eps, "-") != 0) { + int epsc = eps[0] - 'a'; + eps[0] = 'a' + (7 - epsc); + } +} + unsigned char position[32]; int pos_len; int bits_left; @@ -177,6 +219,43 @@ void put_bit(int x) } } +void dump_fen(char *board, int invert, int flip, char *castling_rights, char *ep_square) +{ + int y, x; + for (y = 0; y < 8; ++y) { + int space = 0; + for (x = 0; x < 8; ++x) { + int xx = (flip) ? (7-x) : x; + + if (board[y * 8 + xx] == ' ') { + ++space; + } else { + if (space != 0) + putchar('0' + space); + putchar(board[y * 8 + xx]); + space = 0; + } + } + if (space != 0) + putchar('0' + space); + if (y != 7) + putchar('/'); + } + putchar(' '); + + if (invert) + putchar('b'); + else + putchar('w'); + + printf(" %s ", castling_rights); + if (flip && strcmp(ep_square, "-") != 0) { + printf("%c%c 0 0\n", 'a' + (7 - (ep_square[0] - 'a')), ep_square[1]); + } else { + printf("%s 0 0\n", ep_square); + } +} + void encode_position(char *board, int invert, char *castling_rights, char *ep_column) { int x, y; @@ -283,36 +362,52 @@ void encode_position(char *board, int invert, char *castling_rights, char *ep_co } } } - - // en passant + if (strcmp(ep_column, "-") != 0) { int epcn = ep_column[0] - 'a'; - // only encode en passant if a capture is actually possible if ((epcn > 0 && board[3*8 + epcn - 1] == 'P') || (epcn < 7 && board[3*8 + epcn + 1] == 'P')) { - ep_any = 1; - - put_bit(epcn & 0x80); - put_bit(epcn & 0x40); - put_bit(epcn & 0x20); - put_bit(epcn & 0x10); - put_bit(epcn & 0x08); - put_bit(epcn & 0x04); - put_bit(epcn & 0x02); - put_bit(epcn & 0x01); + ep_any = 1; } } - + // really odd padding - if (bits_left > 4) { - int i, nb = bits_left - 4; + { + int nb = 0, i; + + // find the right number of bits + int right = (ep_any) ? 3 : 8; + + // castling needs four more + if (strcmp(castling_rights, "-") != 0) { + right = right + 4; + if (right > 8) + right %= 8; + } + + if (bits_left > right) + nb = bits_left - right; + else if (bits_left < right) + nb = bits_left + 8 - right; + + if (bits_left == 8 && strcmp(castling_rights, "-") == 0 && !ep_any) + nb = 8; + for (i = 0; i < nb; ++i) { - //printf("spare bit\n"); put_bit(0); } } + // en passant + if (ep_any) { + int epcn = ep_column[0] - 'a'; + + put_bit(epcn & 0x04); + put_bit(epcn & 0x02); + put_bit(epcn & 0x01); + } + // castling rights if (strcmp(castling_rights, "-") != 0) { if (invert) { @@ -329,13 +424,17 @@ void encode_position(char *board, int invert, char *castling_rights, char *ep_co } // padding stuff -#if 1 - if (bits_left != 8) { + if (bits_left == 8) { + //++pos_len; + } else { +#if 0 + ++pos_len; +#else int i, nd = 8 - bits_left; for (i = 0; i < nd; ++i) put_bit(0); - } #endif + } // and the header byte position[0] = pos_len; @@ -345,8 +444,7 @@ void encode_position(char *board, int invert, char *castling_rights, char *ep_co if (ep_any) position[0] |= 0x20; -#if 0 - // dump +#if DUMP_ENC { int i; for (i = 0; i < pos_len; ++i) { @@ -428,9 +526,11 @@ struct moveenc { struct moveenc movetable[] = { 0x00, 'P', 5, 1, 1, 0x01, 'N', 2, -1, -2, + 0x03, 'Q', 2, 0, 2, 0x04, 'P', 2, 1, 0, 0x05, 'Q', 1, 1, 0, 0x06, 'P', 4, 1, -1, + 0x08, 'Q', 2, 0, 4, 0x09, 'B', 2, 6, 6, 0x0a, 'K', 1, -1, 0, 0x0c, 'P', 1, 1, -1, @@ -442,10 +542,12 @@ struct moveenc movetable[] = { 0x14, 'P', 8, 1, 1, 0x15, 'B', 1, 5, 5, 0x18, 'P', 7, 1, 0, + 0x1a, 'Q', 2, 6, 0, 0x1b, 'B', 1, 1, -1, 0x1d, 'B', 2, 7, 7, 0x21, 'R', 2, 0, 7, 0x22, 'B', 2, 2, -2, + 0x23, 'Q', 2, 6, 6, 0x24, 'P', 8, 1, -1, 0x26, 'B', 1, 7, -7, 0x27, 'P', 3, 1, -1, @@ -461,15 +563,19 @@ struct moveenc movetable[] = { 0x34, 'N', 1, 2, 1, 0x36, 'N', 1, 1, 2, 0x37, 'Q', 1, 4, 0, + 0x38, 'Q', 2, 4, -4, 0x39, 'Q', 1, 0, 5, 0x3a, 'B', 1, 6, 6, + 0x3b, 'Q', 2, 5, -5, 0x3c, 'B', 1, 5, -5, + 0x41, 'Q', 2, 5, 5, 0x42, 'Q', 1, 7, -7, 0x44, 'K', 1, -1, 1, 0x45, 'Q', 1, 3, 3, 0x4a, 'P', 8, 2, 0, 0x4b, 'Q', 1, 5, -5, 0x4c, 'N', 2, 2, 1, + 0x4d, 'Q', 2, 1, 0, 0x50, 'R', 1, 6, 0, 0x52, 'R', 1, 0, 6, 0x54, 'B', 2, 1, -1, @@ -478,12 +584,14 @@ struct moveenc movetable[] = { 0x5f, 'P', 5, 2, 0, 0x61, 'Q', 1, 6, 6, 0x62, 'P', 2, 2, 0, + 0x63, 'Q', 2, 7, -7, 0x66, 'B', 1, 3, -3, 0x67, 'K', 1, 1, 1, 0x69, 'R', 2, 7, 0, 0x6a, 'B', 1, 4, 4, 0x6b, 'K', 1, 0, 2, /* short castling */ 0x6e, 'R', 1, 0, 5, + 0x6f, 'Q', 2, 7, 7, 0x72, 'B', 2, 7, -7, 0x74, 'Q', 1, 0, 2, 0x79, 'B', 2, 6, -6, @@ -502,7 +610,9 @@ struct moveenc movetable[] = { 0x8a, 'N', 1, -2, 1, 0x8b, 'P', 1, 1, 1, 0x8c, 'K', 1, -1, -1, + 0x8e, 'Q', 2, 2, -2, 0x8f, 'Q', 1, 0, 7, + 0x92, 'Q', 2, 1, 1, 0x94, 'Q', 1, 3, 0, 0x96, 'P', 2, 1, 1, 0x97, 'K', 1, 0, -1, @@ -512,25 +622,33 @@ struct moveenc movetable[] = { 0x9b, 'P', 3, 2, 0, 0x9d, 'Q', 1, 2, 0, 0x9f, 'B', 2, 4, -4, + 0xa0, 'Q', 2, 3, 0, 0xa2, 'Q', 1, 2, 2, 0xa3, 'P', 8, 1, 0, 0xa5, 'R', 2, 5, 0, 0xa9, 'R', 2, 0, 2, + 0xab, 'Q', 2, 6, -6, 0xad, 'R', 2, 0, 4, + 0xae, 'Q', 2, 3, 3, + 0xb0, 'Q', 2, 4, 0, 0xb1, 'P', 6, 2, 0, 0xb2, 'B', 1, 6, -6, 0xb5, 'R', 2, 0, 5, 0xb7, 'Q', 1, 5, 0, 0xb9, 'B', 2, 3, 3, 0xbb, 'P', 5, 1, 0, + 0xbc, 'Q', 2, 0, 5, + 0xbd, 'Q', 2, 2, 0, 0xbe, 'K', 1, 0, 1, 0xc1, 'B', 1, 2, 2, 0xc2, 'B', 2, 2, 2, 0xc3, 'B', 1, 2, -2, 0xc4, 'R', 2, 0, 1, 0xc5, 'R', 2, 4, 0, + 0xc6, 'Q', 2, 5, 0, 0xc7, 'P', 7, 1, -1, 0xc8, 'P', 7, 2, 0, + 0xc9, 'Q', 2, 7, 0, 0xca, 'B', 2, 3, -3, 0xcb, 'P', 6, 1, 0, 0xcc, 'B', 2, 5, -5, @@ -557,14 +675,21 @@ struct moveenc movetable[] = { 0xeb, 'P', 4, 1, 1, 0xec, 'P', 1, 1, 0, 0xed, 'Q', 1, 7, 7, + 0xee, 'Q', 2, 1, -1, 0xef, 'R', 1, 0, 4, + 0xf0, 'Q', 2, 0, 7, 0xf1, 'Q', 1, 1, 1, 0xf3, 'N', 2, 2, -1, 0xf4, 'R', 2, 2, 0, 0xf5, 'B', 2, 1, 1, 0xf6, 'K', 1, 0, -2, /* long castling */ 0xf7, 'N', 1, 1, -2, - 0xfd, 'Q', 1, 7, 0 + 0xf8, 'Q', 2, 0, 1, + 0xf9, 'Q', 2, 6, 0, + 0xfa, 'Q', 2, 0, 3, + 0xfb, 'Q', 2, 2, 2, + 0xfd, 'Q', 1, 7, 0, + 0xfe, 'Q', 2, 3, -3 }; int find_piece(char *board, char piece, int num) @@ -580,6 +705,7 @@ int find_piece(char *board, char piece, int num) } fprintf(stderr, "Couldn't find piece '%c' number %u\n", piece, num); + exit(1); } void execute_move(char *board, char *castling_rights, int inverted, char *ep_square, int from_square, int to_square) @@ -601,19 +727,33 @@ void execute_move(char *board, char *castling_rights, int inverted, char *ep_squ black_ks = black_qs = 0; else white_ks = white_qs = 0; - } else if (board[from_square] == 'R') { + } + if (board[from_square] == 'R') { if (inverted) { - if (from_square == 0) // a1 + if (from_square == 56) // h1 black_qs = 0; - else if (from_square == 7 * 8 + 0) // a8 + else if (from_square == 63) // h8 black_ks = 0; } else { - if (from_square == 0) // a1 + if (from_square == 56) // a1 white_qs = 0; - else if (from_square == 7 * 8 + 0) // a8 + else if (from_square == 63) // a8 white_ks = 0; } } + if (board[to_square] == 'r') { + if (inverted) { + if (to_square == 0) // h1 + white_qs = 0; + else if (to_square == 7) // h8 + white_ks = 0; + } else { + if (to_square == 0) // a1 + black_qs = 0; + else if (to_square == 7) // a8 + black_ks = 0; + } + } if ((black_ks | black_qs | white_ks | white_qs) == 0) { strcpy(castling_rights, "-"); @@ -632,7 +772,7 @@ void execute_move(char *board, char *castling_rights, int inverted, char *ep_squ // now the ep square if (board[from_square] == 'P' && to_square - from_square == -16) { - sprintf(ep_square, "%c%u", "abcdefgh"[from_square % 8], from_square / 8 + 2); + sprintf(ep_square, "%c%u", "abcdefgh"[from_square % 8], from_square / 8); } else { strcpy(ep_square, "-"); } @@ -647,6 +787,10 @@ void execute_move(char *board, char *castling_rights, int inverted, char *ep_squ board[to_square] = board[from_square]; board[from_square] = ' '; + // promotion + if (board[to_square] == 'P' && to_square < 8) + board[to_square] = 'Q'; + if (board[to_square] == 'K' && to_square - from_square == 2) { // short castling board[to_square - 1] = 'R'; @@ -673,7 +817,7 @@ void execute_move(char *board, char *castling_rights, int inverted, char *ep_squ #endif } -void dump_move(char *board, char *castling_rights, char *ep_col, int invert, char move, char annotation) +void dump_move(char *board, char *castling_rights, char *ep_col, int invert, int flip, char move, char annotation) { int i; char newboard[64], nkr[5], neps[3]; @@ -693,16 +837,60 @@ void dump_move(char *board, char *castling_rights, char *ep_col, int invert, cha to_row = (from_row + 8 + movetable[i].forward) % 8; to_col = (from_col + 8 + movetable[i].right) % 8; to_square = to_row * 8 + to_col; + + // do the move, and look up the new position + memcpy(newboard, board, 64); + strcpy(nkr, castling_rights); + execute_move(newboard, nkr, invert, neps, from_square, to_square); + invert_board(newboard); + + if (needs_flipping(newboard, nkr)) { + flip_board(newboard, neps); + flip = !flip; + } + + encode_position(newboard, !invert, nkr, neps); + ret = lookup_position(position, pos_len, result); + if (!ret) { +#if DUMP_FEN + if (!invert) + invert_board(newboard); + + dump_fen(newboard, !invert, flip, nkr, neps); +#endif + fprintf(stderr, "Destination move not found in book.\n"); + exit(1); + } + +#if DUMP_FEN + // very useful for regression testing (some shell and + // you can walk the entire book quite easily) + if (!invert) + invert_board(newboard); + dump_fen(newboard, !invert, flip, nkr, neps); + return; +#endif // output the move - if (invert) - printf("%c%u%c%u,", - "abcdefgh"[from_square % 8], (7 - from_square / 8) + 1, - "abcdefgh"[to_square % 8], (7 - to_square / 8) + 1); - else + { + int fromcol = from_square % 8; + int fromrow = from_square / 8; + int tocol = to_square % 8; + int torow = to_square / 8; + + if (invert) { + fromrow = 7 - fromrow; + torow = 7 - torow; + } + if (flip) { + fromcol = 7 - fromcol; + tocol = 7 - tocol; + } + printf("%c%u%c%u,", - "abcdefgh"[from_square % 8], from_square / 8 + 1, - "abcdefgh"[to_square % 8], to_square / 8 + 1); + "abcdefgh"[fromcol], fromrow + 1, + "abcdefgh"[tocol], torow + 1); + } // annotation switch (annotation) { @@ -737,36 +925,26 @@ void dump_move(char *board, char *castling_rights, char *ep_col, int invert, cha } printf(","); - // do the move, and look up the new position - memcpy(newboard, board, 64); - strcpy(nkr, castling_rights); - execute_move(newboard, nkr, invert, neps, from_square, to_square); - invert_board(newboard); - - encode_position(newboard, !invert, nkr, neps); - ret = lookup_position(position, pos_len, result); - if (!ret) { - fprintf(stderr, "Destination move not found in book.\n"); - exit(1); - } - output_stats(result, invert); return; } fprintf(stderr, "ERROR: Unknown move 0x%02x\n", move); + exit(1); } -void dump_info(char *board, char *castling_rights, char *ep_col, int invert, char *result) +void dump_info(char *board, char *castling_rights, char *ep_col, int invert, int flip, char *result) { int book_moves = result[0] >> 1; int i; - + +#if !DUMP_FEN printf(",,"); output_stats(result, !invert); +#endif for (i = 0; i < book_moves; ++i) { - dump_move(board, castling_rights, ep_col, invert, result[i * 2 + 1], result[i * 2 + 2]); + dump_move(board, castling_rights, ep_col, invert, flip, result[i * 2 + 1], result[i * 2 + 2]); } } @@ -774,19 +952,26 @@ int main(int argc, char **argv) { // encode the position char board[64], result[256]; - int invert = 0; + int invert = 0, flip; int ret; ctg_fd = open("RybkaII.ctg", O_RDONLY); cto_fd = open("RybkaII.cto", O_RDONLY); ctb_fd = open("RybkaII.ctb", O_RDONLY); decode_fen_board(argv[1], board); - + // always from white's position if (argv[2][0] == 'b') { invert = 1; invert_board(board); } + + // and the white king is always in the right half + flip = needs_flipping(board, argv[3]); + if (flip) { + flip_board(board, argv[4]); + } + #if 0 // dump the board @@ -804,11 +989,11 @@ int main(int argc, char **argv) encode_position(board, invert, argv[3], argv[4]); ret = lookup_position(position, pos_len, result); if (!ret) { - printf("Not found in book.\n"); + //fprintf(stderr, "Not found in book.\n"); exit(1); } - dump_info(board, argv[3], argv[4], invert, result); + dump_info(board, argv[3], argv[4], invert, flip, result); exit(0); }