From: Fabian Fichter Date: Tue, 9 Mar 2021 20:58:02 +0000 (+0100) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=11f69453204efaa0c01d790ab2e1551592a2f972;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 11f69453204efaa0c01d790ab2e1551592a2f972 diff --cc src/evaluate.cpp index 3440ad8,d55ef69..93f2b84 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -484,43 -422,8 +484,42 @@@ namespace else if (Pt == BISHOP && (attacks_bb(s, pos.pieces(PAWN)) & kingRing[Them])) score += BishopOnKingRing; + if (Pt > QUEEN) + b = (b & pos.pieces()) | (pos.moves_from(Us, Pt, s) & ~pos.pieces() & pos.board_bb()); + int mob = popcount(b & mobilityArea[Us]); - - mobility[Us] += MobilityBonus[Pt - 2][mob]; + if (Pt <= QUEEN) + mobility[Us] += MobilityBonus[Pt - 2][mob]; + else + mobility[Us] += MaxMobility * (mob - 2) / (8 + mob); + + // Piece promotion bonus + if (pos.promoted_piece_type(Pt) != NO_PIECE_TYPE) + { + Bitboard zone = zone_bb(Us, pos.promotion_rank(), pos.max_rank()); + if (zone & (b | s)) + score += make_score(PieceValue[MG][pos.promoted_piece_type(Pt)] - PieceValue[MG][Pt], + PieceValue[EG][pos.promoted_piece_type(Pt)] - PieceValue[EG][Pt]) / (zone & s && b ? 6 : 12); + } + else if (pos.piece_demotion() && pos.unpromoted_piece_on(s)) + score -= make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)], + PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 4; + else if (pos.captures_to_hand() && pos.unpromoted_piece_on(s)) + score += make_score(PieceValue[MG][Pt] - PieceValue[MG][pos.unpromoted_piece_on(s)], + PieceValue[EG][Pt] - PieceValue[EG][pos.unpromoted_piece_on(s)]) / 8; + + // Penalty if the piece is far from the kings in drop variants + if ((pos.captures_to_hand() || pos.two_boards()) && pos.count(Them) && pos.count(Us)) + { + if (!(b & (kingRing[Us] | kingRing[Them]))) + score -= KingProximity * distance(s, pos.square(Us)) * distance(s, pos.square(Them)); + } + + else if (pos.count(Us) && (Pt == FERS || Pt == SILVER)) + score -= EndgameKingProximity * (distance(s, pos.square(Us)) - 2); + + if (Pt == SOLDIER && (pos.pieces(Us, SOLDIER) & rank_bb(s) & adjacent_files_bb(s))) + score += ConnectedSoldier; if (Pt == BISHOP || Pt == KNIGHT) { diff --cc src/movepick.cpp index a90a518,0ceeb8e..b4d7cda --- a/src/movepick.cpp +++ b/src/movepick.cpp @@@ -107,12 -103,12 +107,12 @@@ void MovePicker::score() m.value = int(PieceValue[MG][pos.piece_on(to_sq(m))]) * 6 + (*captureHistory)[pos.moved_piece(m)][to_sq(m)][type_of(pos.piece_on(to_sq(m)))]; - else if (Type == QUIETS) + else if constexpr (Type == QUIETS) m.value = (*mainHistory)[pos.side_to_move()][from_to(m)] - + 2 * (*continuationHistory[0])[pos.moved_piece(m)][to_sq(m)] - + (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)] - + (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)] - + (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)] + + 2 * (*continuationHistory[0])[history_slot(pos.moved_piece(m))][to_sq(m)] + + (*continuationHistory[1])[history_slot(pos.moved_piece(m))][to_sq(m)] + + (*continuationHistory[3])[history_slot(pos.moved_piece(m))][to_sq(m)] + + (*continuationHistory[5])[history_slot(pos.moved_piece(m))][to_sq(m)] + (ply < MAX_LPH ? std::min(4, depth / 3) * (*lowPlyHistory)[ply][from_to(m)] : 0); else // Type == EVASIONS diff --cc src/position.cpp index 6ae1106,2eb30ca..20e6ffb --- a/src/position.cpp +++ b/src/position.cpp @@@ -1033,40 -536,18 +1033,44 @@@ bool Position::legal(Move m) const // In case of Chess960, verify if the Rook blocks some checks // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1. - return !chess960 || !(blockers_for_king(us) & to_sq(m)); + return !chess960 || !attackers_to(to, pieces() ^ to_sq(m), ~us); + } + + Bitboard occupied = (type_of(m) != DROP ? pieces() ^ from : pieces()) | to; + + // Flying general rule and bikjang + // In case of bikjang passing is always allowed, even when in check + if (st->bikjang && is_pass(m)) + return true; + if ((var->flyingGeneral && count(us)) || st->bikjang) + { + Square s = type_of(moved_piece(m)) == KING ? to : square(us); + if (attacks_bb(~us, ROOK, s, occupied) & pieces(~us, KING) & ~square_bb(to)) + return false; } - // If the moving piece is a king, check whether the destination square is - // attacked by the opponent. - if (type_of(piece_on(from)) == KING) - return !(attackers_to(to) & pieces(~us)); + // Makpong rule + if (var->makpongRule && checkers() && type_of(moved_piece(m)) == KING && (checkers() ^ to)) + return false; + ++ // Return early when without king ++ if (!count(us)) ++ return true; ++ + // If the moving piece is a king, check whether the destination + // square is attacked by the opponent. Castling moves are checked + // for legality during move generation. + if (type_of(moved_piece(m)) == KING) + return !attackers_to(to, occupied, ~us); + + Bitboard janggiCannons = pieces(JANGGI_CANNON); + if (type_of(moved_piece(m)) == JANGGI_CANNON) + janggiCannons = (type_of(m) == DROP ? janggiCannons : janggiCannons ^ from) | to; + else if (janggiCannons & to) + janggiCannons ^= to; - // A non-king move is legal if and only if it is not pinned or it - // is moving along the ray towards or away from the king. - return !(blockers_for_king(us) & from) - || aligned(from, to, square(us)); + // A non-king move is legal if the king is not under attack after the move. - return !count(us) || !(attackers_to(square(us), occupied, ~us, janggiCannons) & ~SquareBB[to]); ++ return !(attackers_to(square(us), occupied, ~us, janggiCannons) & ~SquareBB[to]); }