From: Fabian Fichter Date: Fri, 2 Apr 2021 19:37:51 +0000 (+0200) Subject: Prepare for virtual piece drops X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=751ddbc44797ced255052d5f205cfa6272cbd5fa;p=fairystockfish.git Prepare for virtual piece drops Make code more robust for negative piece count. No functional change. --- diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 77ade99..d3fce55 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -628,7 +628,7 @@ namespace { Score score = SCORE_ZERO; - if (pos.count_in_hand(Us, pt)) + if (pos.count_in_hand(Us, pt) > 0) { Bitboard b = pos.drop_region(Us, pt) & ~pos.pieces() & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]); if ((b & kingRing[Them]) && pt != SHOGI_PAWN) @@ -695,7 +695,7 @@ namespace { b2 = attacks_bb(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN)); std::function get_attacks = [this](Color c, PieceType pt) { - return attackedBy[c][pt] | (pos.piece_drops() && pos.count_in_hand(c, pt) ? pos.drop_region(c, pt) & ~pos.pieces() : Bitboard(0)); + return attackedBy[c][pt] | (pos.piece_drops() && pos.count_in_hand(c, pt) > 0 ? pos.drop_region(c, pt) & ~pos.pieces() : Bitboard(0)); }; for (PieceType pt : pos.piece_types()) { @@ -724,7 +724,7 @@ namespace { unsafeChecks |= knightChecks; break; case PAWN: - if (pos.piece_drops() && pos.count_in_hand(Them, pt)) + if (pos.piece_drops() && pos.count_in_hand(Them, pt) > 0) { pawnChecks = attacks_bb(Us, pt, ksq, pos.pieces()) & ~pos.pieces() & pos.board_bb(); if (pawnChecks & safe) @@ -759,7 +759,7 @@ namespace { if (pos.two_boards() && pos.piece_drops()) { for (PieceType pt : pos.piece_types()) - if (!pos.count_in_hand(Them, pt) && (attacks_bb(Us, pt, ksq, pos.pieces()) & safe & pos.drop_region(Them, pt) & ~pos.pieces())) + if (pos.count_in_hand(Them, pt) <= 0 && (attacks_bb(Us, pt, ksq, pos.pieces()) & safe & pos.drop_region(Them, pt) & ~pos.pieces())) { kingDanger += VirtualCheck * 500 / (500 + PieceValue[MG][pt]); // Presumably a mate threat diff --git a/src/movegen.cpp b/src/movegen.cpp index f88222a..5a473cf 100644 --- a/src/movegen.cpp +++ b/src/movegen.cpp @@ -30,7 +30,7 @@ namespace { if (pos.arrow_gating()) { for (PieceType pt_gating : pos.piece_types()) - if (pos.count_in_hand(us, pt_gating)) + if (pos.count_in_hand(us, pt_gating) > 0) { Bitboard b = pos.drop_region(us, pt_gating) & moves_bb(us, type_of(pos.piece_on(from)), to, pos.pieces() ^ from) & ~(pos.pieces() ^ from); while (b) @@ -44,11 +44,11 @@ namespace { // Gating moves if (pos.seirawan_gating() && (pos.gates(us) & from)) for (PieceType pt_gating : pos.piece_types()) - if (pos.count_in_hand(us, pt_gating) && (pos.drop_region(us, pt_gating) & from)) + if (pos.count_in_hand(us, pt_gating) > 0 && (pos.drop_region(us, pt_gating) & from)) *moveList++ = make_gating(from, to, pt_gating, from); if (pos.seirawan_gating() && T == CASTLING && (pos.gates(us) & to)) for (PieceType pt_gating : pos.piece_types()) - if (pos.count_in_hand(us, pt_gating) && (pos.drop_region(us, pt_gating) & to)) + if (pos.count_in_hand(us, pt_gating) > 0 && (pos.drop_region(us, pt_gating) & to)) *moveList++ = make_gating(from, to, pt_gating, to); return moveList; @@ -72,7 +72,7 @@ namespace { template ExtMove* generate_drops(const Position& pos, ExtMove* moveList, PieceType pt, Bitboard b) { - if (pos.count_in_hand(Us, pt)) + if (pos.count_in_hand(Us, pt) > 0) { // Restrict to valid target b &= pos.drop_region(Us, pt); @@ -373,7 +373,7 @@ namespace { if (pt != PAWN && pt != KING) moveList = generate_moves(pos, moveList, pt, piecesToMove, target); // generate drops - if (pos.piece_drops() && Type != CAPTURES && pos.count_in_hand(Us, ALL_PIECES)) + if (pos.piece_drops() && Type != CAPTURES && pos.count_in_hand(Us, ALL_PIECES) > 0) for (PieceType pt : pos.piece_types()) moveList = generate_drops(pos, moveList, pt, target & ~pos.pieces(~Us)); diff --git a/src/partner.cpp b/src/partner.cpp index 306b6e2..c53d069 100644 --- a/src/partner.cpp +++ b/src/partner.cpp @@ -140,12 +140,12 @@ void PartnerHandler::parse_ptell(std::istringstream& is, const Position& pos) { else if (token == "time") { int value; - time = (is >> value) ? value : 0; + time = (is >> value) ? value * 10 : 0; } else if (token == "otim") { int value; - opptime = (is >> value) ? value : 0; + opptime = (is >> value) ? value * 10 : 0; } } diff --git a/src/partner.h b/src/partner.h index 01b68e6..8a78882 100644 --- a/src/partner.h +++ b/src/partner.h @@ -22,6 +22,7 @@ #include #include +#include "misc.h" #include "position.h" /// PartnerHandler manages the communication with the partner @@ -42,7 +43,7 @@ struct PartnerHandler { std::atomic isFairy; std::atomic fast, sitRequested, partnerDead, weDead, weWin; - std::atomic time, opptime; + std::atomic time, opptime; Move moveRequested; }; diff --git a/src/position.cpp b/src/position.cpp index 9eef9ed..3157db0 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -362,7 +362,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, st->gatesBB[c] |= st->castlingKingSquare[c]; // Do not set castling rights for gates unless there are no pieces in hand, // which means that the file is referring to a chess960 castling right. - else if (!seirawan_gating() || count_in_hand(c, ALL_PIECES) || captures_to_hand()) + else if (!seirawan_gating() || count_in_hand(c, ALL_PIECES) > 0 || captures_to_hand()) continue; } @@ -373,7 +373,7 @@ Position& Position::set(const Variant* v, const string& fenStr, bool isChess960, // Set castling rights for 960 gating variants if (gating() && castling_enabled()) for (Color c : {WHITE, BLACK}) - if ((gates(c) & pieces(castling_king_piece())) && !castling_rights(c) && (!seirawan_gating() || count_in_hand(c, ALL_PIECES) || captures_to_hand())) + if ((gates(c) & pieces(castling_king_piece())) && !castling_rights(c) && (!seirawan_gating() || count_in_hand(c, ALL_PIECES) > 0 || captures_to_hand())) { Bitboard castling_rooks = gates(c) & pieces(castling_rook_piece()); while (castling_rooks) @@ -671,13 +671,13 @@ const string Position::fen(bool sfen, bool showPromoted, int countStarted, std:: ss << (sideToMove == WHITE ? " b " : " w "); for (Color c : {WHITE, BLACK}) for (PieceType pt = KING; pt >= PAWN; --pt) - if (pieceCountInHand[c][pt]) + if (pieceCountInHand[c][pt] > 0) { if (pieceCountInHand[c][pt] > 1) ss << pieceCountInHand[c][pt]; ss << piece_to_char()[make_piece(c, pt)]; } - if (!count_in_hand(ALL_PIECES)) + if (count_in_hand(ALL_PIECES) == 0) ss << '-'; ss << " " << gamePly + 1; return ss.str(); @@ -692,7 +692,10 @@ const string Position::fen(bool sfen, bool showPromoted, int countStarted, std:: else for (Color c : {WHITE, BLACK}) for (PieceType pt = KING; pt >= PAWN; --pt) + { + assert(pieceCountInHand[c][pt] >= 0); ss << std::string(pieceCountInHand[c][pt], piece_to_char()[make_piece(c, pt)]); + } ss << ']'; } @@ -708,7 +711,7 @@ const string Position::fen(bool sfen, bool showPromoted, int countStarted, std:: if (can_castle(WHITE_OOO)) ss << (chess960 ? char('A' + file_of(castling_rook_square(WHITE_OOO))) : 'Q'); - if (gating() && gates(WHITE) && (!seirawan_gating() || count_in_hand(WHITE, ALL_PIECES) || captures_to_hand())) + if (gating() && gates(WHITE) && (!seirawan_gating() || count_in_hand(WHITE, ALL_PIECES) > 0 || captures_to_hand())) for (File f = FILE_A; f <= max_file(); ++f) if (gates(WHITE) & file_bb(f)) ss << char('A' + f); @@ -723,7 +726,7 @@ const string Position::fen(bool sfen, bool showPromoted, int countStarted, std:: if (can_castle(BLACK_OOO)) ss << (chess960 ? char('a' + file_of(castling_rook_square(BLACK_OOO))) : 'q'); - if (gating() && gates(BLACK) && (!seirawan_gating() || count_in_hand(BLACK, ALL_PIECES) || captures_to_hand())) + if (gating() && gates(BLACK) && (!seirawan_gating() || count_in_hand(BLACK, ALL_PIECES) > 0 || captures_to_hand())) for (File f = FILE_A; f <= max_file(); ++f) if (gates(BLACK) & file_bb(f)) ss << char('a' + f); @@ -927,7 +930,7 @@ bool Position::legal(Move m) const { return false; // Illegal non-drop moves - if (must_drop() && type_of(m) != DROP && count_in_hand(us, var->mustDropType)) + if (must_drop() && type_of(m) != DROP && count_in_hand(us, var->mustDropType) > 0) { if (checkers()) { @@ -1115,7 +1118,7 @@ bool Position::pseudo_legal(const Move m) const { return piece_drops() && pc != NO_PIECE && color_of(pc) == us - && count_in_hand(us, in_hand_piece_type(m)) + && count_in_hand(us, in_hand_piece_type(m)) > 0 && (drop_region(us, type_of(pc)) & ~pieces() & to) && ( type_of(pc) == in_hand_piece_type(m) || (drop_promoted() && type_of(pc) == promoted_piece_type(in_hand_piece_type(m)))); @@ -1689,7 +1692,7 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { st->gatesBB[us] ^= to_sq(m); if (gates(them) & to) st->gatesBB[them] ^= to; - if (seirawan_gating() && !count_in_hand(us, ALL_PIECES) && !captures_to_hand()) + if (seirawan_gating() && count_in_hand(us, ALL_PIECES) == 0 && !captures_to_hand()) st->gatesBB[us] = 0; } diff --git a/src/position.h b/src/position.h index d47e61f..bc80fc8 100644 --- a/src/position.h +++ b/src/position.h @@ -1291,7 +1291,7 @@ inline void Position::remove_from_hand(Piece pc) { } inline void Position::drop_piece(Piece pc_hand, Piece pc_drop, Square s) { - assert(pieceCountInHand[color_of(pc_hand)][type_of(pc_hand)]); + assert(pieceCountInHand[color_of(pc_hand)][type_of(pc_hand)] > 0 || var->twoBoards); put_piece(pc_drop, s, pc_drop != pc_hand, pc_drop != pc_hand ? pc_hand : NO_PIECE); remove_from_hand(pc_hand); } @@ -1300,7 +1300,7 @@ inline void Position::undrop_piece(Piece pc_hand, Square s) { remove_piece(s); board[s] = NO_PIECE; add_to_hand(pc_hand); - assert(pieceCountInHand[color_of(pc_hand)][type_of(pc_hand)]); + assert(pieceCountInHand[color_of(pc_hand)][type_of(pc_hand)] > 0 || var->twoBoards); } #endif // #ifndef POSITION_H_INCLUDED diff --git a/src/search.cpp b/src/search.cpp index 3f63836..fbe2ad4 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -261,7 +261,7 @@ void MainThread::search() { // Sit in bughouse variants if partner requested it or we are dead if (rootPos.two_boards() && !Threads.abort && Options["Protocol"] == "xboard") { - while (!Threads.stop && (Partner.sitRequested || Partner.weDead) && Time.elapsed() < Limits.time[us] - 1000) + while (!Threads.stop && (Partner.sitRequested || (Partner.weDead && !Partner.partnerDead)) && Time.elapsed() < Limits.time[us] - 1000) {} } @@ -587,12 +587,12 @@ void Thread::search() { Partner.ptell("x"); Partner.weDead = false; } - else if (!Partner.weWin && bestValue >= VALUE_MATE_IN_MAX_PLY && Limits.time[~us] < Partner.time * 10) + else if (!Partner.weWin && bestValue >= VALUE_MATE_IN_MAX_PLY && Limits.time[~us] < Partner.time) { Partner.ptell("sit"); Partner.weWin = true; } - else if (Partner.weWin && (bestValue < VALUE_MATE_IN_MAX_PLY || Limits.time[~us] > Partner.time * 10)) + else if (Partner.weWin && (bestValue < VALUE_MATE_IN_MAX_PLY || Limits.time[~us] > Partner.time)) { Partner.ptell("x"); Partner.weWin = false; @@ -1965,7 +1965,7 @@ void MainThread::check_time() { if ( rootPos.two_boards() && Time.elapsed() < Limits.time[rootPos.side_to_move()] - 1000 - && (Partner.sitRequested || Partner.weDead)) + && (Partner.sitRequested || (Partner.weDead && !Partner.partnerDead))) return; if ( (Limits.use_time_management() && (elapsed > Time.maximum() - 10 || stopOnPonderhit)) diff --git a/src/timeman.cpp b/src/timeman.cpp index 8939ea7..aa90d78 100644 --- a/src/timeman.cpp +++ b/src/timeman.cpp @@ -71,10 +71,10 @@ void TimeManagement::init(const Position& pos, Search::LimitsType& limits, Color if (pos.two_boards()) { if (Partner.partnerDead && Partner.opptime) - timeLeft -= Partner.opptime * 10; + timeLeft -= Partner.opptime; else { - timeLeft = std::min(timeLeft, 5000 + std::min(std::abs(limits.time[us] - Partner.opptime * 10), TimePoint(Partner.opptime * 10))); + timeLeft = std::min(timeLeft, 5000 + std::min(std::abs(limits.time[us] - Partner.opptime), TimePoint(Partner.opptime))); if (Partner.fast || Partner.partnerDead) timeLeft /= 4; }