X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=9c61cc88181e89411427d9158b92108d35285344;hp=d3ca869b8215e20e22e947f95e946f4fdfb53116;hb=44fbbeafc90c0caf3002c82585c0163adeec0bff;hpb=22ede4442cd285d7365b9497c3be65fb2c66b4be diff --git a/src/position.cpp b/src/position.cpp index d3ca869b..9c61cc88 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -152,9 +152,9 @@ Position::Position(const Position& pos, int th) { nodes = 0; } -Position::Position(const string& fen, int th) { +Position::Position(const string& fen, bool isChess960, int th) { - from_fen(fen); + from_fen(fen, isChess960); threadID = th; } @@ -175,7 +175,7 @@ void Position::detach() { /// string. This function is not very robust - make sure that input FENs are /// correct (this is assumed to be the responsibility of the GUI). -void Position::from_fen(const string& fen) { +void Position::from_fen(const string& fen, bool c960) { /* A FEN string defines a particular position using only the ASCII character set. @@ -205,6 +205,7 @@ void Position::from_fen(const string& fen) { */ char token; + int hmc, fmn; std::istringstream ss(fen); Rank rank = RANK_8; File file = FILE_A; @@ -264,7 +265,13 @@ void Position::from_fen(const string& fen) { st->epSquare = fenEpSquare; } - // 5-6. Halfmove clock and fullmove number are not parsed + // 5. Halfmove clock + if (ss >> hmc) + st->rule50 = hmc; + + // 6. Fullmove number + if (ss >> fmn) + startPosPlyCounter = (fmn - 1) * 2 + int(sideToMove == BLACK); // Various initialisations castleRightsMask[make_square(initialKFile, RANK_1)] ^= WHITE_OO | WHITE_OOO; @@ -274,6 +281,7 @@ void Position::from_fen(const string& fen) { castleRightsMask[make_square(initialQRFile, RANK_1)] ^= WHITE_OOO; castleRightsMask[make_square(initialQRFile, RANK_8)] ^= BLACK_OOO; + isChess960 = c960; find_checkers(); st->key = compute_key(); @@ -349,7 +357,7 @@ bool Position::set_castling_rights(char token) { /// Position::to_fen() returns a FEN representation of the position. In case /// of Chess960 the Shredder-FEN notation is used. Mainly a debugging function. -const string Position::to_fen(bool isChess960) const { +const string Position::to_fen() const { string fen; Square sq; @@ -436,8 +444,7 @@ void Position::print(Move move) const { cout << c << pieceLetters.from_piece(piece) << c << '|'; } } - bool chess960 = (cout.iword(0) != 0); // See set960() - cout << dottedLine << "Fen is: " << to_fen(chess960) << "\nKey is: " << st->key << endl; + cout << dottedLine << "Fen is: " << to_fen() << "\nKey is: " << st->key << endl; requestPending = false; } @@ -524,7 +531,7 @@ Bitboard Position::attacks_from(Piece p, Square s) const { case WB: case BB: return attacks_from(s); case WR: case BR: return attacks_from(s); case WQ: case BQ: return attacks_from(s); - default: return StepAttackBB[p][s]; + default: return NonSlidingAttacksBB[p][s]; } } @@ -537,7 +544,7 @@ Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) { case WB: case BB: return bishop_attacks_bb(s, occ); case WR: case BR: return rook_attacks_bb(s, occ); case WQ: case BQ: return bishop_attacks_bb(s, occ) | rook_attacks_bb(s, occ); - default: return StepAttackBB[p][s]; + default: return NonSlidingAttacksBB[p][s]; } } @@ -766,6 +773,23 @@ bool Position::move_is_check(Move m, const CheckInfo& ci) const { } +/// Position::do_setup_move() makes a permanent move on the board. +/// It should be used when setting up a position on board. +/// You can't undo the move. + +void Position::do_setup_move(Move m, StateInfo& newSt) { + + do_move(m, newSt); + + // Reset "game ply" in case we made a non-reversible move. + // "game ply" is used for repetition detection. + if (st->rule50 == 0) + st->gamePly = 0; + + // Update the number of plies played from the starting position + startPosPlyCounter++; +} + /// Position::do_move() makes a move, and saves all information necessary /// to a StateInfo object. The move is assumed to be legal. /// Pseudo-legal moves should be filtered out before this function is called. @@ -1533,22 +1557,6 @@ void Position::clear() { } -/// Position::reset_game_ply() simply sets gamePly to 0. It is used from the -/// UCI interface code, whenever a non-reversible move is made in a -/// 'position fen moves m1 m2 ...' command. This makes it possible -/// for the program to handle games of arbitrary length, as long as the GUI -/// handles draws by the 50 move rule correctly. - -void Position::reset_game_ply() { - - st->gamePly = 0; -} - -void Position::inc_startpos_ply_counter() { - - startPosPlyCounter++; -} - /// Position::put_piece() puts a piece on the given square of the board, /// updating the board array, pieces list, bitboards, and piece counts. @@ -1683,7 +1691,7 @@ bool Position::is_draw() const { return true; // Draw by the 50 moves rule? - if (st->rule50 > 99 && (st->rule50 > 100 || !is_mate())) + if (st->rule50 > 99 && !is_mate()) return true; // Draw by repetition? @@ -1701,7 +1709,7 @@ bool Position::is_draw() const { bool Position::is_mate() const { MoveStack moves[MOVES_MAX]; - return is_check() && generate_moves(*this, moves) == moves; + return is_check() && generate(*this, moves) == moves; } @@ -1722,8 +1730,8 @@ bool Position::has_mate_threat() { do_null_move(st1); // Then generate pseudo-legal moves that could give check - last = generate_non_capture_checks(*this, mlist); - last = generate_captures(*this, last); + last = generate(*this, mlist); + last = generate(*this, last); // Loop through the moves, and see if one of them gives mate Bitboard pinned = pinned_pieces(sideToMove);