X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=004d6994731ca106e0dd3d7afd6fb5f5b31fd719;hp=28da877525a4773a87b1f25c31bd8ccca1da068d;hb=e3b03278129e4d7f130826aef209668b3268aa94;hpb=e304db9d1ecf6a2318708483c90fadecf4fac4ee diff --git a/src/position.cpp b/src/position.cpp index 28da8775..004d6994 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -41,7 +41,7 @@ static const string PieceToChar(" PNBRQK pnbrqk"); CACHE_LINE_ALIGNMENT Score pieceSquareTable[PIECE_NB][SQUARE_NB]; -Value PieceValue[2][18] = { // [Mg / Eg][piece / pieceType] +Value PieceValue[PHASE_NB][PIECE_NB] = { { VALUE_ZERO, PawnValueMg, KnightValueMg, BishopValueMg, RookValueMg, QueenValueMg }, { VALUE_ZERO, PawnValueEg, KnightValueEg, BishopValueEg, RookValueEg, QueenValueEg } }; @@ -86,10 +86,10 @@ void init() { for (PieceType pt = PAWN; pt <= KING; pt++) { - PieceValue[Mg][make_piece(BLACK, pt)] = PieceValue[Mg][pt]; - PieceValue[Eg][make_piece(BLACK, pt)] = PieceValue[Eg][pt]; + PieceValue[MG][make_piece(BLACK, pt)] = PieceValue[MG][pt]; + PieceValue[EG][make_piece(BLACK, pt)] = PieceValue[EG][pt]; - Score v = make_score(PieceValue[Mg][pt], PieceValue[Eg][pt]); + Score v = make_score(PieceValue[MG][pt], PieceValue[EG][pt]); for (Square s = SQ_A1; s <= SQ_H8; s++) { @@ -400,10 +400,8 @@ void Position::print(Move move) const { sync_cout; if (move) - { - Position p(*this); - cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move); - } + cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") + << move_to_san(*const_cast(this), move); for (Square sq = SQ_A1; sq <= SQ_H8; sq++) if (piece_on(sq) != NO_PIECE) @@ -475,37 +473,6 @@ Bitboard Position::attacks_from(Piece p, Square s, Bitboard occ) { } -/// Position::move_attacks_square() tests whether a move from the current -/// position attacks a given square. - -bool Position::move_attacks_square(Move m, Square s) const { - - assert(is_ok(m)); - assert(is_ok(s)); - - Bitboard occ, xray; - Square from = from_sq(m); - Square to = to_sq(m); - Piece piece = piece_moved(m); - - assert(!is_empty(from)); - - // Update occupancy as if the piece is moving - occ = pieces() ^ from ^ to; - - // The piece moved in 'to' attacks the square 's' ? - if (attacks_from(piece, to, occ) & s) - return true; - - // Scan for possible X-ray attackers behind the moved piece - xray = (attacks_bb< ROOK>(s, occ) & pieces(color_of(piece), QUEEN, ROOK)) - | (attacks_bb(s, occ) & pieces(color_of(piece), QUEEN, BISHOP)); - - // Verify attackers are triggered by our move and not already existing - return xray && (xray ^ (xray & attacks_from(s))); -} - - /// Position::pl_move_is_legal() tests whether a pseudo-legal move is legal bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { @@ -772,9 +739,9 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI Key k = st->key; // Copy some fields of old state to our new StateInfo object except the ones - // which are recalculated from scratch anyway, then switch our state pointer - // to point to the new, ready to be updated, state. - memcpy(&newSt, st, sizeof(ReducedStateInfo)); + // which are going to be recalculated from scratch anyway, then switch our state + // pointer to point to the new, ready to be updated, state. + memcpy(&newSt, st, StateCopySize64 * sizeof(uint64_t)); newSt.previous = st; st = &newSt; @@ -830,7 +797,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI st->pawnKey ^= Zobrist::psq[them][PAWN][capsq]; } else - st->npMaterial[them] -= PieceValue[Mg][capture]; + st->npMaterial[them] -= PieceValue[MG][capture]; // Remove the captured piece byTypeBB[ALL_PIECES] ^= capsq; @@ -938,7 +905,7 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI - pieceSquareTable[make_piece(us, PAWN)][to]; // Update material - st->npMaterial[us] += PieceValue[Mg][promotion]; + st->npMaterial[us] += PieceValue[MG][promotion]; } // Update pawn hash key @@ -1243,7 +1210,7 @@ int Position::see_sign(Move m) const { // Early return if SEE cannot be negative because captured piece value // is not less then capturing one. Note that king moves always return // here because king midgame value is set to 0. - if (PieceValue[Mg][piece_on(to_sq(m))] >= PieceValue[Mg][piece_moved(m)]) + if (PieceValue[MG][piece_on(to_sq(m))] >= PieceValue[MG][piece_moved(m)]) return 1; return see(m); @@ -1290,7 +1257,7 @@ int Position::see(Move m) const { stm = ~color_of(piece_on(from)); stmAttackers = attackers & pieces(stm); if (!stmAttackers) - return PieceValue[Mg][captured]; + return PieceValue[MG][captured]; // The destination square is defended, which makes things rather more // difficult to compute. We proceed by building up a "swap list" containing @@ -1298,14 +1265,14 @@ int Position::see(Move m) const { // destination square, where the sides alternately capture, and always // capture with the least valuable piece. After each capture, we look for // new X-ray attacks from behind the capturing piece. - swapList[0] = PieceValue[Mg][captured]; + swapList[0] = PieceValue[MG][captured]; captured = type_of(piece_on(from)); do { assert(slIndex < 32); // Add the new entry to the swap list - swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[Mg][captured]; + swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured]; slIndex++; // Locate and remove from 'occupied' the next least valuable attacker @@ -1347,9 +1314,6 @@ void Position::clear() { for (int i = 0; i < 8; i++) for (int j = 0; j < 16; j++) pieceList[0][i][j] = pieceList[1][i][j] = SQ_NONE; - - for (Square sq = SQ_A1; sq <= SQ_H8; sq++) - board[sq] = NO_PIECE; } @@ -1463,7 +1427,7 @@ Value Position::compute_non_pawn_material(Color c) const { Value value = VALUE_ZERO; for (PieceType pt = KNIGHT; pt <= QUEEN; pt++) - value += piece_count(c, pt) * PieceValue[Mg][pt]; + value += piece_count(c, pt) * PieceValue[MG][pt]; return value; } @@ -1472,36 +1436,31 @@ 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. -template +template bool Position::is_draw() const { - // Draw by material? if ( !pieces(PAWN) && (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMg)) return true; - // Draw by the 50 moves rule? if (st->rule50 > 99 && (!in_check() || MoveList(*this).size())) return true; - // Draw by repetition? - if (!SkipRepetition) + if (CheckRepetition) { - int i = 4, e = std::min(st->rule50, st->pliesFromNull); + int i = 4, e = std::min(st->rule50, st->pliesFromNull), cnt; if (i <= e) { StateInfo* stp = st->previous->previous; - do { + for (cnt = 0; i <= e; i += 2) + { stp = stp->previous->previous; - if (stp->key == st->key) + if (stp->key == st->key && (!CheckThreeFold || ++cnt >= 2)) return true; - - i +=2; - - } while (i <= e); + } } } @@ -1509,8 +1468,9 @@ bool Position::is_draw() const { } // Explicit template instantiations -template bool Position::is_draw() const; -template bool Position::is_draw() const; +template bool Position::is_draw() const; +template bool Position::is_draw() const; +template bool Position::is_draw() const; /// Position::flip() flips position with the white and black sides reversed. This