From: Fabian Fichter Date: Sat, 6 Apr 2019 13:05:36 +0000 (+0200) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=47da2cf3120f89cd7c422fe1711d05e61489331e;p=fairystockfish.git Merge official-stockfish/master bench: 3258421 --- 47da2cf3120f89cd7c422fe1711d05e61489331e diff --cc src/bitboard.cpp index 3e56bb9,2adf277..aceff1b --- a/src/bitboard.cpp +++ b/src/bitboard.cpp @@@ -27,16 -27,12 +27,15 @@@ uint8_t PopCnt16[1 << 16]; uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; - Bitboard BoardSizeBB[FILE_NB][RANK_NB]; - Bitboard SquareBB[SQUARE_NB]; - Bitboard ForwardRanksBB[COLOR_NB][RANK_NB]; Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; Bitboard LineBB[SQUARE_NB][SQUARE_NB]; -Bitboard DistanceRingBB[SQUARE_NB][8]; -Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; -Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; +Bitboard DistanceRingBB[SQUARE_NB][FILE_NB]; +Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; + Bitboard SquareBB[SQUARE_NB]; ++Bitboard BoardSizeBB[FILE_NB][RANK_NB]; Bitboard KingFlank[FILE_NB] = { QueenSide ^ FileDBB, QueenSide, QueenSide, diff --cc src/bitboard.h index 57489ba,7798663..38db8e0 --- a/src/bitboard.h +++ b/src/bitboard.h @@@ -95,20 -68,14 +95,20 @@@ constexpr Bitboard Center = (FileD extern uint8_t PopCnt16[1 << 16]; extern uint8_t SquareDistance[SQUARE_NB][SQUARE_NB]; - extern Bitboard BoardSizeBB[FILE_NB][RANK_NB]; - extern Bitboard SquareBB[SQUARE_NB]; extern Bitboard BetweenBB[SQUARE_NB][SQUARE_NB]; extern Bitboard LineBB[SQUARE_NB][SQUARE_NB]; -extern Bitboard DistanceRingBB[SQUARE_NB][8]; -extern Bitboard PseudoAttacks[PIECE_TYPE_NB][SQUARE_NB]; -extern Bitboard PawnAttacks[COLOR_NB][SQUARE_NB]; +extern Bitboard DistanceRingBB[SQUARE_NB][FILE_NB]; +extern Bitboard PseudoAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard PseudoMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard LeaperAttacks[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; +extern Bitboard LeaperMoves[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB]; extern Bitboard KingFlank[FILE_NB]; + extern Bitboard SquareBB[SQUARE_NB]; ++extern Bitboard BoardSizeBB[FILE_NB][RANK_NB]; +#ifdef LARGEBOARDS +int popcount(Bitboard b); // required for 128 bit pext +#endif /// Magic holds all magic bitboards relevant data for a single square struct Magic { @@@ -135,15 -102,14 +135,14 @@@ extern Magic RookMagics[SQUARE_NB]; extern Magic BishopMagics[SQUARE_NB]; - - /// Overloads of bitwise operators between a Bitboard and a Square for testing - /// whether a given bit is set in a bitboard, and for setting and clearing bits. - inline Bitboard square_bb(Square s) { - assert(s >= SQ_A1 && s <= SQ_H8); + assert(s >= SQ_A1 && s <= SQ_MAX); return SquareBB[s]; } - + + /// Overloads of bitwise operators between a Bitboard and a Square for testing + /// whether a given bit is set in a bitboard, and for setting and clearing bits. + inline Bitboard operator&( Bitboard b, Square s) { return b & square_bb(s); } inline Bitboard operator|( Bitboard b, Square s) { return b | square_bb(s); } inline Bitboard operator^( Bitboard b, Square s) { return b ^ square_bb(s); } diff --cc src/evaluate.cpp index ab938bc,51cba65..66ee10f --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@@ -235,28 -224,25 +235,31 @@@ namespace constexpr Color Them = (Us == WHITE ? BLACK : WHITE); constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH); constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH); - constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB); + Bitboard LowRanks = rank_bb(relative_rank(Us, RANK_2, pos.max_rank())) | rank_bb(relative_rank(Us, RANK_3, pos.max_rank())); - const Square ksq = pos.square(Us); + const Square ksq = pos.count(Us) ? pos.square(Us) : SQ_NONE; + Bitboard dblAttackByPawn = pawn_double_attacks_bb(pos.pieces(Us, PAWN)); + // Find our pawns that are blocked or on the first two ranks Bitboard b = pos.pieces(Us, PAWN) & (shift(pos.pieces()) | LowRanks); // Squares occupied by those pawns, by our king or queen or controlled by // enemy pawns are excluded from the mobility area. - mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them)); + if (pos.must_capture()) + mobilityArea[Us] = AllSquares; + else + mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pe->pawn_attacks(Them) | shift(pos.pieces(Them, SHOGI_PAWN))); // Initialize attackedBy[] for king and pawns - attackedBy[Us][KING] = pos.attacks_from(ksq); + attackedBy[Us][KING] = pos.count(Us) ? pos.attacks_from(Us, ksq) : 0; attackedBy[Us][PAWN] = pe->pawn_attacks(Us); - attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN]; - attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN]) - | dblAttackByPawn; + attackedBy[Us][SHOGI_PAWN] = shift(pos.pieces(Us, SHOGI_PAWN)); + attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN] | attackedBy[Us][SHOGI_PAWN]; + attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN]) + | (attackedBy[Us][KING] & attackedBy[Us][SHOGI_PAWN]) - | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN]); ++ | (attackedBy[Us][PAWN] & attackedBy[Us][SHOGI_PAWN]) ++ | dblAttackByPawn; // Init our king safety tables kingRing[Us] = attackedBy[Us][KING]; @@@ -273,9 -259,7 +276,9 @@@ kingAttacksCount[Them] = kingAttackersWeight[Them] = 0; // Remove from kingRing[] the squares defended by two pawns - kingRing[Us] &= ~pawn_double_attacks_bb(pos.pieces(Us, PAWN)); + kingRing[Us] &= ~dblAttackByPawn; + + kingRing[Us] &= pos.board_bb(); } diff --cc src/material.cpp index fe3d0e5,ee5d4bc..9fd8832 --- a/src/material.cpp +++ b/src/material.cpp @@@ -141,99 -132,76 +141,99 @@@ Entry* probe(const Position& pos) Value npm = clamp(npm_w + npm_b, EndgameLimit, MidgameLimit); // Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME] - e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit)); - + if (pos.captures_to_hand()) + { + npm = VALUE_ZERO; + for (PieceType pt : pos.piece_types()) + npm += (pos.count_in_hand(WHITE, pt) + pos.count_in_hand(BLACK, pt)) * PieceValue[MG][make_piece(WHITE, pt)]; + e->gamePhase = Phase(PHASE_MIDGAME * (MidgameLimit - std::min(npm, MidgameLimit)) / MidgameLimit); + } + else + e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit)); + +#ifdef LARGEBOARDS + // Disable endgame evaluation until it works independent of board size + if (false) +#else + if (pos.endgame_eval()) +#endif + { - // Let's look if we have a specialized evaluation function for this particular - // material configuration. Firstly we look for a fixed configuration one, then - // for a generic one if the previous search failed. - if ((e->evaluationFunction = pos.this_thread()->endgames.probe(key)) != nullptr) + // Let's look if we have a specialized evaluation function for this particular + // material configuration. Firstly we look for a fixed configuration one, then + // for a generic one if the previous search failed. + if ((e->evaluationFunction = pos.this_thread()->endgames.probe(key)) != nullptr) + return e; + + for (Color c = WHITE; c <= BLACK; ++c) ++ if (is_KFsPsK(pos, c)) ++ { ++ e->evaluationFunction = &EvaluateKFsPsK[c]; + return e; ++ } + - for (Color c = WHITE; c <= BLACK; ++c) - if (is_KFsPsK(pos, c)) - { - e->evaluationFunction = &EvaluateKFsPsK[c]; - return e; - } - - for (Color c = WHITE; c <= BLACK; ++c) - if (is_KXK(pos, c)) - { - e->evaluationFunction = &EvaluateKXK[c]; - return e; - } - - // OK, we didn't find any special evaluation function for the current material - // configuration. Is there a suitable specialized scaling function? - const EndgameBase* sf; - - if ((sf = pos.this_thread()->endgames.probe(key)) != nullptr) ++ for (Color c = WHITE; c <= BLACK; ++c) + if (is_KXK(pos, c)) { - e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned + e->evaluationFunction = &EvaluateKXK[c]; return e; } - // We didn't find any specialized scaling function, so fall back on generic - // ones that refer to more than one material distribution. Note that in this - // case we don't return after setting the function. - for (Color c = WHITE; c <= BLACK; ++c) + // OK, we didn't find any special evaluation function for the current material + // configuration. Is there a suitable specialized scaling function? + const auto* sf = pos.this_thread()->endgames.probe(key); + + if (sf) + { + e->scalingFunction[sf->strongSide] = sf; // Only strong color assigned + return e; + } + + // We didn't find any specialized scaling function, so fall back on generic + // ones that refer to more than one material distribution. Note that in this + // case we don't return after setting the function. + for (Color c = WHITE; c <= BLACK; ++c) + { + if (is_KBPsK(pos, c)) + e->scalingFunction[c] = &ScaleKBPsK[c]; + + else if (is_KQKRPs(pos, c)) + e->scalingFunction[c] = &ScaleKQKRPs[c]; + } + + if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board + { + if (!pos.count(BLACK)) { - if (is_KBPsK(pos, c)) - e->scalingFunction[c] = &ScaleKBPsK[c]; + assert(pos.count(WHITE) >= 2); - else if (is_KQKRPs(pos, c)) - e->scalingFunction[c] = &ScaleKQKRPs[c]; + e->scalingFunction[WHITE] = &ScaleKPsK[WHITE]; } + else if (!pos.count(WHITE)) + { + assert(pos.count(BLACK) >= 2); - if (npm_w + npm_b == VALUE_ZERO && pos.pieces(PAWN)) // Only pawns on the board + e->scalingFunction[BLACK] = &ScaleKPsK[BLACK]; + } + else if (pos.count(WHITE) == 1 && pos.count(BLACK) == 1) { - if (!pos.count(BLACK)) - { - assert(pos.count(WHITE) >= 2); - - e->scalingFunction[WHITE] = &ScaleKPsK[WHITE]; - } - else if (!pos.count(WHITE)) - { - assert(pos.count(BLACK) >= 2); - - e->scalingFunction[BLACK] = &ScaleKPsK[BLACK]; - } - else if (pos.count(WHITE) == 1 && pos.count(BLACK) == 1) - { - // This is a special case because we set scaling functions - // for both colors instead of only one. - e->scalingFunction[WHITE] = &ScaleKPKP[WHITE]; - e->scalingFunction[BLACK] = &ScaleKPKP[BLACK]; - } + // This is a special case because we set scaling functions + // for both colors instead of only one. + e->scalingFunction[WHITE] = &ScaleKPKP[WHITE]; + e->scalingFunction[BLACK] = &ScaleKPKP[BLACK]; } + } - // Zero or just one pawn makes it difficult to win, even with a small material - // advantage. This catches some trivial draws like KK, KBK and KNK and gives a - // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN). - if (!pos.count(WHITE) && npm_w - npm_b <= BishopValueMg) - e->factor[WHITE] = uint8_t(npm_w < RookValueMg ? SCALE_FACTOR_DRAW : - npm_b <= BishopValueMg ? 4 : 14); + // Zero or just one pawn makes it difficult to win, even with a small material + // advantage. This catches some trivial draws like KK, KBK and KNK and gives a + // drawish scale factor for cases such as KRKBP and KmmKm (except for KBBKN). + if (!pos.count(WHITE) && npm_w - npm_b <= BishopValueMg) + e->factor[WHITE] = uint8_t(npm_w < RookValueMg ? SCALE_FACTOR_DRAW : + npm_b <= BishopValueMg ? 4 : 14); - if (!pos.count(BLACK) && npm_b - npm_w <= BishopValueMg) - e->factor[BLACK] = uint8_t(npm_b < RookValueMg ? SCALE_FACTOR_DRAW : - npm_w <= BishopValueMg ? 4 : 14); + if (!pos.count(BLACK) && npm_b - npm_w <= BishopValueMg) + e->factor[BLACK] = uint8_t(npm_b < RookValueMg ? SCALE_FACTOR_DRAW : + npm_w <= BishopValueMg ? 4 : 14); + } // Evaluate the material imbalance. We use PIECE_TYPE_NONE as a place holder // for the bishop pair "extended piece", which allows us to be more flexible diff --cc src/pawns.cpp index 134acc4,7edaa6e..32cddcd --- a/src/pawns.cpp +++ b/src/pawns.cpp @@@ -130,10 -128,14 +130,14 @@@ namespace // Score this pawn if (support | phalanx) - score += Connected[opposed][bool(phalanx)][popcount(support)][relative_rank(Us, s, pos.max_rank())]; - + { - int r = relative_rank(Us, s); ++ int r = relative_rank(Us, s, pos.max_rank()); + int v = phalanx ? Connected[r] + Connected[r + 1] : 2 * Connected[r]; + v = 17 * popcount(support) + (v >> (opposed + 1)); + score += make_score(v, v * (r - 2) / 4); + } else if (!neighbours) - score -= Isolated, e->weakUnopposed[Us] += !opposed; + score -= Isolated * (1 + 2 * pos.must_capture()), e->weakUnopposed[Us] += !opposed; else if (backward) score -= Backward, e->weakUnopposed[Us] += !opposed; @@@ -142,31 -144,6 +146,26 @@@ score -= Doubled; } + const Square* pl_shogi = pos.squares(Us); + + ourPawns = pos.pieces(Us, SHOGI_PAWN); + theirPawns = pos.pieces(Them, SHOGI_PAWN); + + // Loop through all shogi pawns of the current color and score each one + while ((s = *pl_shogi++) != SQ_NONE) + { + assert(pos.piece_on(s) == make_piece(Us, SHOGI_PAWN)); + + File f = file_of(s); + + e->semiopenFiles[Us] &= ~(1 << f); + - opposed = theirPawns & forward_file_bb(Us, s); + neighbours = ourPawns & adjacent_files_bb(f); - phalanx = neighbours & rank_bb(s); - - if (phalanx) - score += Connected[opposed][bool(phalanx)][0][relative_rank(Us, s, pos.max_rank())] / 2; + - else if (!neighbours) ++ if (!neighbours) + score -= Isolated / 2; + } + return score; } diff --cc src/search.cpp index c74e10e,a9a62db..d27f486 --- a/src/search.cpp +++ b/src/search.cpp @@@ -724,13 -724,12 +729,12 @@@ namespace { int bonus = -(ss-1)->statScore / 512; - pureStaticEval = evaluate(pos); - ss->staticEval = eval = pureStaticEval + bonus; + ss->staticEval = eval = evaluate(pos) + bonus; } else - ss->staticEval = eval = pureStaticEval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos); - ss->staticEval = eval = -(ss-1)->staticEval + 2 * Eval::Tempo; ++ ss->staticEval = eval = -(ss-1)->staticEval + 2 * Eval::tempo_value(pos); - tte->save(posKey, VALUE_NONE, ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, pureStaticEval); + tte->save(posKey, VALUE_NONE, ttPv, BOUND_NONE, DEPTH_NONE, MOVE_NONE, eval); } // Step 7. Razoring (~2 Elo) @@@ -764,11 -753,9 +768,11 @@@ && (ss-1)->currentMove != MOVE_NULL && (ss-1)->statScore < 23200 && eval >= beta - && pureStaticEval >= beta - 36 * depth / ONE_PLY + 225 + && ss->staticEval >= beta - 36 * depth / ONE_PLY + 225 && !excludedMove && pos.non_pawn_material(us) + && (pos.pieces(~us) ^ pos.pieces(~us, PAWN)) + && (pos.pieces() ^ pos.pieces(BREAKTHROUGH_PIECE) ^ pos.pieces(CLOBBER_PIECE)) && (ss->ply >= thisThread->nmpMinPly || us != thisThread->nmpColor)) { assert(eval - beta >= 0); @@@ -850,10 -836,9 +854,9 @@@ } // Step 11. Internal iterative deepening (~2 Elo) - if ( depth >= (8 - 2 * pos.captures_to_hand()) * ONE_PLY - && !ttMove) - if (depth >= 8 * ONE_PLY && !ttMove) ++ if (depth >= (8 - 2 * pos.captures_to_hand()) * ONE_PLY && !ttMove) { - search(pos, ss, alpha, beta, depth - 7 * ONE_PLY, cutNode); + search(pos, ss, alpha, beta, depth - (7 - 2 * pos.captures_to_hand()) * ONE_PLY, cutNode); tte = TT.probe(posKey, ttHit); ttValue = ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;