X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=0336a832a363291d4c07d5ade63899db790a9bca;hp=1350ddf97a5923e33c3f677bdef398df79154ea3;hb=34c7f1387d514176996144020ac6ac0c603fca4b;hpb=b1ac6c69a077c95c122a82d5b757adf9470fb308 diff --git a/src/position.cpp b/src/position.cpp index 1350ddf9..0336a832 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -76,15 +76,52 @@ CheckInfo::CheckInfo(const Position& pos) { checkSq[KING] = EmptyBoardBB; } + +/// Position c'tors. Here we always create a slower but safer copy of +/// the original position or the FEN string, we want the new born Position +/// object do not depend on any external data. Instead if we know what we +/// are doing and we need speed we can create a position with default +/// c'tor Position() and then use just fast_copy(). + +Position::Position() {} + Position::Position(const Position& pos) { - copy(pos); + + fast_copy(pos); + detach(); // Always detach() in copy c'tor to avoid surprises } Position::Position(const string& fen) { + from_fen(fen); } +/// Position::fast_copy() creates a partial copy of the given position, +/// only data that changes with a do_move() / undo_move() cycle is copied, +/// in particular for stateInfo are copied only the pointers, so that the +/// actual data remains stored in the parent Position. This is not a problem +/// if the parent Position is known not to be destroyed while we are still alive, +/// as is the common case, see detach() otherwise. + +void Position::fast_copy(const Position& pos) { + + memcpy(this, &pos, sizeof(Position)); +} + + +/// Position::detach() copies the content of the current state and castling +/// masks inside the position itself. This is needed when the st pointee could +/// become stale, as example because the caller is about to going out of scope. + +void Position::detach() { + + startState = *st; + st = &startState; + st->previous = NULL; // as a safe guard +} + + /// Position::from_fen() initializes the position object with the given FEN /// string. This function is not very robust - make sure that input FENs are /// correct (this is assumed to be the responsibility of the GUI). @@ -319,8 +356,9 @@ void Position::print(Move m) const { std::cout << std::endl; if (m != MOVE_NONE) { + Position p(*this); string col = (color_of_piece_on(move_from(m)) == BLACK ? ".." : ""); - std::cout << "Move is: " << col << move_to_san(*this, m) << std::endl; + std::cout << "Move is: " << col << move_to_san(p, m) << std::endl; } for (Rank rank = RANK_8; rank >= RANK_1; rank--) { @@ -345,15 +383,6 @@ void Position::print(Move m) const { } -/// Position::copy() creates a copy of the input position. - -void Position::copy(const Position& pos) { - - memcpy(this, &pos, sizeof(Position)); - saveState(); // detach and copy state info -} - - /// Position:hidden_checkers<>() returns a bitboard of all pinned (against the /// king) pieces for the given color and for the given pinner type. Or, when /// template parameter FindPinned is false, the pieces of the given color @@ -1272,6 +1301,11 @@ void Position::undo_null_move() { } +/// +PieceType Position::captured_piece() const { + return st->capture; +} + /// Position::see() is a static exchange evaluator: It tries to estimate the /// material gain or loss resulting from a move. There are three versions of /// this function: One which takes a destination square as input, one takes a @@ -1443,19 +1477,6 @@ int Position::see(Square from, Square to) const { } -/// Position::saveState() copies the content of the current state -/// inside startState and makes st point to it. This is needed -/// when the st pointee could become stale, as example because -/// the caller is about to going out of scope. - -void Position::saveState() { - - startState = *st; - st = &startState; - st->previous = NULL; // as a safe guard -} - - /// Position::clear() erases the position object to a pristine state, with an /// empty board, white to move, and no castling rights. @@ -1657,6 +1678,7 @@ Value Position::compute_non_pawn_material(Color c) const { /// Position::is_draw() tests whether the position is drawn by material, /// repetition, or the 50 moves rule. It does not detect stalemates, this /// must be done by the search. +// FIXME: Currently we are not handling 50 move rule correctly when in check bool Position::is_draw() const { @@ -1670,7 +1692,7 @@ bool Position::is_draw() const { return true; // Draw by repetition? - for (int i = 2; i < Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2) + for (int i = 4; i <= Min(Min(gamePly, st->rule50), st->pliesFromNull); i += 2) if (history[gamePly - i] == st->key) return true;