Пример #1
0
/*
    Makes a move_t from a supplied string (in long algebraic notation), or
    returns 0 if it's an invalid move.
*/
move_t move_from_text(const char* text, board_t* board) {
    int text_length = strlen(text);
    if (text_length != 4 && text_length != 5) return 0;

    move_t move = (((text[1]-'1')*8)+(tolower(text[0])-'a')) + ((((text[3]-'1')*8)+(tolower(text[2])-'a'))<<6);
    if (text_length == 5)
        if (board->to_move == WHITE)
            move |= piece_type_from_char(toupper(text[4]))<<23;
        else
            move |= piece_type_from_char(tolower(text[4]))<<23;

    move_t move_list[MAX_MOVES];
    move_t* end_of_move_list = generate_pseudolegal_moves(board, move_list);
    for (int i = 0; &move_list[i] != end_of_move_list; i++) {
        if ((move_list[i]&0x7800FFF) == move) {
            if (IS_CASTLE(move_list[i]) && !is_legal_castle(board, move_list[i])) return 0;
            make_move(board, move_list[i]);
            if (!is_king_in_check(board, !board->to_move)) {
                undo_move(board, move_list[i]);
                return move_list[i];
            }
       }
    }

    return 0;
}
Move move_from_san(Position &pos, const std::string &movestr) {
  assert(pos.is_ok());

  MovePicker mp = MovePicker(pos, false, MOVE_NONE, MOVE_NONE, MOVE_NONE,
                             MOVE_NONE, OnePly);

  // Castling moves
  if(movestr == "O-O-O") {
    Move m;
    while((m = mp.get_next_move()) != MOVE_NONE)
      if(move_is_long_castle(m) && pos.move_is_legal(m))
        return m;
    return MOVE_NONE;
  }
  else if(movestr == "O-O") {
    Move m;
    while((m = mp.get_next_move()) != MOVE_NONE)
      if(move_is_short_castle(m) && pos.move_is_legal(m))
        return m;
    return MOVE_NONE;
  }

  // Normal moves
  const char *cstr = movestr.c_str();
  const char *c;
  char *cc;
  char str[10];
  int i;

  // Initialize str[] by making a copy of movestr with the characters
  // 'x', '=', '+' and '#' removed.
  cc = str;
  for(i=0, c=cstr; i<10 && *c!='\0' && *c!='\n' && *c!=' '; i++, c++)
    if(!strchr("x=+#", *c)) {
      *cc = strchr("nrq", *c)? toupper(*c) : *c;
      cc++;
    }
  *cc = '\0';

  int left = 0, right = strlen(str) - 1;
  PieceType pt = NO_PIECE_TYPE, promotion;
  Square to;
  File fromFile = FILE_NONE;
  Rank fromRank = RANK_NONE;

  // Promotion?
  if(strchr("BNRQ", str[right])) {
    promotion = piece_type_from_char(str[right]);
    right--;
  }
  else
    promotion = NO_PIECE_TYPE;

  // Find the moving piece:
  if(left < right) {
    if(strchr("BNRQK", str[left])) {
      pt = piece_type_from_char(str[left]);
      left++;
    }
    else
      pt = PAWN;
  }

  // Find the to square:
  if(left < right) {
    if(str[right] < '1' || str[right] > '8' ||
       str[right-1] < 'a' || str[right-1] > 'h')
      return MOVE_NONE;
    to = make_square(file_from_char(str[right-1]), rank_from_char(str[right]));
    right -= 2;
  }
  else
    return MOVE_NONE;

  // Find the file and/or rank of the from square:
  if(left <= right) {
    if(strchr("abcdefgh", str[left])) {
      fromFile = file_from_char(str[left]);
      left++;
    }
    if(strchr("12345678", str[left]))
      fromRank = rank_from_char(str[left]);
  }

  // Look for a matching move:
  Move m, move = MOVE_NONE;
  int matches = 0;

  while((m = mp.get_next_move()) != MOVE_NONE) {
    bool match = true;
    if(pos.type_of_piece_on(move_from(m)) != pt)
      match = false;
    else if(move_to(m) != to)
      match = false;
    else if(move_promotion(m) != promotion)
      match = false;
    else if(fromFile != FILE_NONE && fromFile != square_file(move_from(m)))
      match = false;
    else if(fromRank != RANK_NONE && fromRank != square_rank(move_from(m)))
      match = false;
    if(match) {
      move = m;
      matches++;
    }
  }

  if(matches == 1)
    return move;
  else
    return MOVE_NONE;
}
Пример #3
0
/*
    Sets up a board to the position indicated by the FEN string.
*/
void set_board_from_fen_string(board_t* board, const char* fen_string) {
    int fen_index = 0, fen_length = strlen(fen_string), square;
    char current_char;

    for (square=A1; square <= H8; square++) board->pieces[square] = EMPTY;
    for (int i = 0; i < NUMBER_OF_PIECES-2; i++) board->piece_bitboard[i] = 0;
    board->color_bitboard[WHITE] = board->color_bitboard[BLACK] = 0;
    board->can_castle = 0;
    board->passed_square = 0;
    board->fifty_move_rule_counter = 0;
    board->material[WHITE] = board->material[BLACK] = 0;
    board->hash_key = 0;
    board->state_index = 0;

    // set pieces
    for (int rank = 7; rank >= 0; rank--) {
        int file = 0;
        do {
            if (file > 7) { fprintf(stderr, "FEN read error: too many files\n"); return; }
            current_char = fen_string[fen_index++];
            if (current_char >= '1' && current_char <= '8') file += (current_char - '0');
            else {
                board->pieces[rank*8+file] = piece_type_from_char(current_char);
                file++;
            }
        } while (fen_string[fen_index] != '/' && fen_string[fen_index] != ' ');
        fen_index++;
    }
    if (fen_string[fen_index-1] != ' ') { fprintf(stderr, "FEN read error: too many ranks\n"); return; }

    // set side to move
    if (fen_string[fen_index] == 'W' || fen_string[fen_index] == 'w') board->to_move = WHITE;
    else if (fen_string[fen_index] == 'B' || fen_string[fen_index] == 'b') {
        board->to_move = BLACK;
        board->hash_key ^= hash_keys.side;
    } else { fprintf(stderr, "FEN read error: invalid side to move\n"); return; }
    fen_index += 2;

    // set castling permissions
    if (fen_index < fen_length) {
        do {
            switch (fen_string[fen_index]) {
                case 'K':
                    board->can_castle |= WHITE_CASTLE_OO;
                    board->hash_key ^= hash_keys.white_king_side_castle;
                    break;
                case 'Q':
                    board->can_castle |= WHITE_CASTLE_OOO;
                    board->hash_key ^= hash_keys.white_queen_side_castle;
                    break;
                case 'k':
                    board->can_castle |= BLACK_CASTLE_OO;
                    board->hash_key ^= hash_keys.black_king_side_castle;
                    break;
                case 'q':
                    board->can_castle |= BLACK_CASTLE_OOO;
                    board->hash_key ^= hash_keys.black_queen_side_castle;
                    break;
                case '-': break;
                default: fprintf(stderr, "FEN read error: invalid castle permission\n"); return;
            }
        } while (fen_string[++fen_index] != ' ' && fen_index < fen_length);
    }

    // set en-passant square
    fen_index++;
    if (fen_index+1 < fen_length && fen_string[fen_index] != '-') {
        board->passed_square = (fen_string[fen_index]-'a'+1) + (fen_string[fen_index+1]-'0')*8 - 9;
        if (board->passed_square < A1 || board->passed_square > H8) { fprintf(stderr, "FEN read error: invalid en-passant square\n"); return; }
        board->hash_key ^= hash_keys.en_passant_targets[board->passed_square];
    }

    // set up bitboards & material values
    for (square=A1; square <= H8; square++) {
        switch(board->pieces[square]) {
            case WHITE_KING:
                board->king_position[WHITE] = square;
                board->hash_key ^= hash_keys.keys[square][WHITE_KING];
                break;
            case BLACK_KING:
                board->king_position[BLACK] = square;
                board->hash_key ^= hash_keys.keys[square][BLACK_KING];
                break;
            default:
                board->piece_bitboard[board->pieces[square]] |= SQUARE_MASK[square];
                board->material[COLOR_OF_PIECE(board->pieces[square])] += MATERIAL_VALUE[board->pieces[square]];
                board->hash_key ^= hash_keys.keys[square][board->pieces[square]];
                break;
        }
    }
    board->color_bitboard[WHITE] = board->piece_bitboard[WHITE_PAWN] | board->piece_bitboard[WHITE_ROOK] | board->piece_bitboard[WHITE_BISHOP] |
        board->piece_bitboard[WHITE_KNIGHT] | board->piece_bitboard[WHITE_QUEEN] | SQUARE_MASK[board->king_position[WHITE]];
    board->color_bitboard[BLACK] = board->piece_bitboard[BLACK_PAWN] | board->piece_bitboard[BLACK_ROOK] | board->piece_bitboard[BLACK_BISHOP] |
        board->piece_bitboard[BLACK_KNIGHT] | board->piece_bitboard[BLACK_QUEEN] | SQUARE_MASK[board->king_position[BLACK]];
    board->all_pieces_bitboard = board->color_bitboard[WHITE] | board->color_bitboard[BLACK];
}