std::string move_to_string(const Move m){ Square to = move_to(m); int type = move_type(m); if(type >= MovePN && type <= MovePQ) return square_to_string(move_from(m)) + square_to_string(to) + piece_to_char(Piece(type+Black)); return square_to_string(move_from(m)) + square_to_string(to); }
void board_disp(const board_t * board) { int file, rank, sq; int piece, c; char fen[256]; ASSERT(board!=NULL); if (!board_to_fen(board,fen,256)) ASSERT(false); my_log("POLYGLOT %s\n",fen); my_log("POLYGLOT\n"); for (rank = 7; rank >= 0; rank--) { my_log("POLYGLOT "); for (file = 0; file < 8; file++) { sq = square_make(file,rank); piece = board->square[sq]; c = (piece != Empty) ? piece_to_char(piece) : '-'; my_log("%c ",c); } my_log("\n"); } my_log("POLYGLOT\n"); my_log("POLYGLOT %s to play\n",(colour_is_black(board->turn))?"black":"white"); my_log("POLYGLOT\n"); }
static char* print_san_promotion(move m, char *str) { if (is_promotion(m)) { *str++ = '='; *str++ = toupper((unsigned char)piece_to_char(mresultp(m))); } return str; }
static void test_chars(void) { assert(char_to_file('a') == file_a); assert(char_to_file('b') == file_b); assert(char_to_file('h') == file_h); assert(char_to_file('A') == file_a); assert(char_to_file('B') == file_b); assert(char_to_file('H') == file_h); assert(char_to_rank('1', white) == rank_1); assert(char_to_rank('2', white) == rank_2); assert(char_to_rank('3', white) == rank_3); assert(char_to_rank('4', white) == rank_4); assert(char_to_rank('5', white) == rank_5); assert(char_to_rank('8', white) == rank_8); assert(char_to_rank('1', black) == rank_8); assert(char_to_rank('2', black) == rank_7); assert(char_to_rank('3', black) == rank_6); assert(char_to_rank('4', black) == rank_5); assert(char_to_rank('5', black) == rank_4); assert(char_to_rank('8', black) == rank_1); assert(index_to_file_ch(0) == 'h'); assert(index_to_file_ch(1) == 'g'); assert(index_to_file_ch(7) == 'a'); assert(index_to_file_ch(63) == 'a'); assert(index_to_rank_ch(0, white) == '8'); assert(index_to_rank_ch(1, white) == '8'); assert(index_to_rank_ch(8 + 7, white) == '7'); assert(index_to_rank_ch(63, white) == '1'); assert(index_to_rank_ch(0, black) == '1'); assert(index_to_rank_ch(1, black) == '1'); assert(index_to_rank_ch(8 + 7, black) == '2'); assert(index_to_rank_ch(63, black) == '8'); assert(piece_to_char(queen) == 'q'); assert(square_to_char(queen, white) == 'Q'); assert(square_to_char(queen, black) == 'q'); assert(is_file('f')); assert(is_file('F')); assert(!is_file('4')); assert(!is_file('i')); assert(!is_file(' ')); assert(is_rank('1')); assert(is_rank('6')); assert(!is_rank('9')); assert(!is_rank('0')); assert(!is_rank('a')); assert(!is_rank(' ')); }
static char* print_san_move(const struct position *pos, move m, char *str, enum player turn) { int piece = pos_piece_at(pos, mfrom(m)); if (mtype(m) == mt_castle_kingside) return str + sprintf(str, "O-O"); else if (mtype(m) == mt_castle_queenside) return str + sprintf(str, "O-O-O"); if (piece != pawn) *str++ = (char)toupper((unsigned char)piece_to_char(piece)); str = print_san_move_from(pos, m, str, turn); if (is_capture(m)) *str++ = 'x'; str = index_to_str(str, mto(m), turn); if (mtype(m) == mt_en_passant) return str + sprintf(str, "e.p."); str = print_san_promotion(m, str); str = print_san_check(pos, m, str); *str = '\0'; return str; }
bool board_to_fen(const board_t * board, char fen[], int size) { int pos; int file, rank; int sq, piece; int c; int len; ASSERT(board!=NULL); ASSERT(fen!=NULL); ASSERT(size>=92); // init if (size < 92) return false; pos = 0; // piece placement for (rank = Rank8; rank >= Rank1; rank--) { for (file = FileA; file <= FileH;) { sq = SQUARE_MAKE(file,rank); piece = board->square[sq]; ASSERT(piece==Empty||piece_is_ok(piece)); if (piece == Empty) { len = 0; for (; file <= FileH && board->square[SQUARE_MAKE(file,rank)] == Empty; file++) { len++; } ASSERT(len>=1&&len<=8); c = '0' + len; } else { c = piece_to_char(piece); file++; } fen[pos++] = c; } fen[pos++] = '/'; } fen[pos-1] = ' '; // HACK: remove the last '/' // active colour fen[pos++] = (COLOUR_IS_WHITE(board->turn)) ? 'w' : 'b'; fen[pos++] = ' '; // castling if (board->flags == FlagsNone) { fen[pos++] = '-'; } else { if ((board->flags & FlagsWhiteKingCastle) != 0) fen[pos++] = 'K'; if ((board->flags & FlagsWhiteQueenCastle) != 0) fen[pos++] = 'Q'; if ((board->flags & FlagsBlackKingCastle) != 0) fen[pos++] = 'k'; if ((board->flags & FlagsBlackQueenCastle) != 0) fen[pos++] = 'q'; } fen[pos++] = ' '; // en-passant if (board->ep_square == SquareNone) { fen[pos++] = '-'; } else { square_to_string(board->ep_square,&fen[pos],3); pos += 2; } fen[pos++] = ' '; // halfmove clock sprintf(&fen[pos],"%d 1",board->ply_nb); return true; }
bool board_to_fen(const board_t * board, char string[], int size) { int pos; int file, rank; int sq, piece; int c; int len; int old_pos; ASSERT(board_is_ok(board)); ASSERT(string!=NULL); ASSERT(size>=92); // init if (size < 92) return false; pos = 0; // piece placement for (rank = 7; rank >= 0; rank--) { for (file = 0; file < 8;) { sq = square_make(file,rank); piece = board->square[sq]; ASSERT(piece==Empty||piece_is_ok(piece)); if (piece == Empty) { len = 0; for (; file < 8 && board->square[square_make(file,rank)] == Empty; file++) { len++; } ASSERT(len>=1&&len<=8); c = '0' + len; } else { c = piece_to_char(piece); file++; } string[pos++] = c; } string[pos++] = '/'; } string[pos-1] = ' '; // HACK: remove the last '/' // active colour string[pos++] = (colour_is_white(board->turn)) ? 'w' : 'b'; string[pos++] = ' '; // castling old_pos = pos; if (option_get_bool("Chess960")) { // FEN-960 if (board->castle[White][SideH] != SquareNone) { string[pos++] = toupper(file_to_char(square_file(board->castle[White][SideH]))); } if (board->castle[White][SideA] != SquareNone) { string[pos++] = toupper(file_to_char(square_file(board->castle[White][SideA]))); } if (board->castle[Black][SideH] != SquareNone) { string[pos++] = tolower(file_to_char(square_file(board->castle[Black][SideH]))); } if (board->castle[Black][SideA] != SquareNone) { string[pos++] = tolower(file_to_char(square_file(board->castle[Black][SideA]))); } } else { // FEN if (board->castle[White][SideH] != SquareNone) string[pos++] = 'K'; if (board->castle[White][SideA] != SquareNone) string[pos++] = 'Q'; if (board->castle[Black][SideH] != SquareNone) string[pos++] = 'k'; if (board->castle[Black][SideA] != SquareNone) string[pos++] = 'q'; } if (pos == old_pos) string[pos++] = '-'; string[pos++] = ' '; // en-passant if (board->ep_square == SquareNone) { string[pos++] = '-'; } else { if (!square_to_string(board->ep_square,&string[pos],3)) return false; pos += 2; } string[pos++] = ' '; // halfmove clock and fullmove number sprintf(&string[pos],"%d %d",board->ply_nb,board->move_nb+1); return true; }
bool move_to_san(int move, const board_t * board, char string[], int size) { int from, to, piece; char tmp_string[256]; ASSERT(move_is_ok(move)); ASSERT(board_is_ok(board)); ASSERT(string!=NULL); ASSERT(size>=8); ASSERT(move_is_legal(move,board)); if (size < 8) return false; // init from = move_from(move); to = move_to(move); string[0] = '\0'; // castle if (move_is_castle(move,board)) { if (to > from) { strcat(string,"O-O"); } else { strcat(string,"O-O-O"); } goto check; } // from piece = board->square[from]; if (piece_is_pawn(piece)) { // pawn if (move_is_capture(move,board)) { sprintf(tmp_string,"%c",file_to_char(square_file(from))); strcat(string,tmp_string); } } else { // piece sprintf(tmp_string,"%c",toupper(piece_to_char(piece))); strcat(string,tmp_string); // ambiguity switch (ambiguity(move,board)) { case AMBIGUITY_NONE: break; case AMBIGUITY_FILE: sprintf(tmp_string,"%c",file_to_char(square_file(from))); strcat(string,tmp_string); break; case AMBIGUITY_RANK: sprintf(tmp_string,"%c",rank_to_char(square_rank(from))); strcat(string,tmp_string); break; case AMBIGUITY_SQUARE: if (!square_to_string(from,tmp_string,256)) return false; strcat(string,tmp_string); break; default: ASSERT(false); break; } } // capture if (move_is_capture(move,board)) strcat(string,"x"); // to if (!square_to_string(to,tmp_string,256)) return false; strcat(string,tmp_string); // promote if (move_is_promote(move)) { sprintf(tmp_string,"=%c",toupper(piece_to_char(move_promote(move,board)))); strcat(string,tmp_string); } // check check: if (move_is_mate(move,board)) { strcat(string,"#"); } else if (move_is_check(move,board)) { strcat(string,"+"); } return true; }
static int move_from_lan(const char string[], const board_t * board) { int len; int move; int promote; char s[256]; int from, to; int colour; int inc; int piece_char; int n; const uint8 * ptr; int piece; int side; ASSERT(string!=NULL); ASSERT(board_is_ok(board)); // init len = strlen(string); if (len != 7) return MoveNone; move = MoveNone; colour = board->turn; // promote promote = 0; switch (string[6]) { case '?': // not a promotion break; case 'N': promote = MovePromoteKnight; break; case 'B': promote = MovePromoteBishop; break; case 'R': promote = MovePromoteRook; break; case 'Q': promote = MovePromoteQueen; break; default: return MoveNone; break; } // to square s[0] = string[4]; s[1] = string[5]; s[2] = '\0'; to = square_from_string(s); if (to == SquareNone) return MoveNone; // known from square? if (string[1] != '?' && string[2] != '?') { // from square s[0] = string[1]; s[1] = string[2]; s[2] = '\0'; from = square_from_string(s); if (from == SquareNone) return MoveNone; // convert "king slide" castling to KxR if (piece_is_king(board->square[from]) && square_rank(to) == square_rank(from) && abs(to-from) > 1) { side = (to > from) ? SideH : SideA; to = board->castle[colour][side]; if (to == SquareNone) return MoveNone; } // move move = move_make(from,to) | promote; return move; } // pawn non-capture? if (string[0] == '?' && string[1] == '?') { if (board->square[to] != Empty) return MoveNone; // useful? inc = (colour_is_white(colour)) ? +16 : -16; from = to - inc; if (board->square[from] == Empty && square_side_rank(to,colour) == Rank4) { from -= inc; } if (board->square[from] != piece_make_pawn(colour)) { // useful? return MoveNone; } // move move = move_make(from,to) | promote; return move; } // pawn capture? piece_char = string[0]; if (piece_char == '?' && string[1] != '?') { piece_char = 'P'; } // attack loop n = 0; for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) { piece = board->square[from]; if (toupper(piece_to_char(piece)) == piece_char) { if (piece_attack(board,piece,from,to)) { if (true && (string[1] == '?' || file_to_char(square_file(from)) == string[1]) && (string[2] == '?' || rank_to_char(square_rank(from)) == string[2])) { if (!is_pinned(board,from,to,colour)) { move = move_make(from,to) | promote; n++; } } } } } if (n != 1) move = MoveNone; return move; }