}
} // r > RANK_3
- // Scale down bonus for candidate passers which need more than one
- // pawn push to become passed, or have a pawn in front of them.
- if ( !pos.pawn_passed(Us, s + Up)
- || (pos.pieces(PAWN) & (s + Up)))
- bonus = bonus / 2;
-
- score += bonus - PassedFile * edge_distance(file_of(s));
+ score += bonus - PassedFile * edge_distance(file_of(s), pos.max_file());
+ }
+
+ // Scale by maximum promotion piece value
+ Value maxMg = VALUE_ZERO, maxEg = VALUE_ZERO;
+ for (PieceType pt : pos.promotion_piece_types())
+ {
+ maxMg = std::max(maxMg, PieceValue[MG][pt]);
+ maxEg = std::max(maxEg, PieceValue[EG][pt]);
+ }
+ score = make_score(mg_value(score) * int(maxMg - PawnValueMg) / (QueenValueMg - PawnValueMg),
+ eg_value(score) * int(maxEg - PawnValueEg) / (QueenValueEg - PawnValueEg));
+
+ // Score passed shogi pawns
+ const Square* pl = pos.squares(Us, SHOGI_PAWN);
+ Square s;
+
+ PieceType pt = pos.promoted_piece_type(SHOGI_PAWN);
+ if (pt != NO_PIECE_TYPE)
+ {
+ while ((s = *pl++) != SQ_NONE)
+ {
+ if ((pos.pieces(Them, SHOGI_PAWN) & forward_file_bb(Us, s)) || relative_rank(Us, s, pos.max_rank()) == pos.max_rank())
+ continue;
+
+ Square blockSq = s + Up;
+ int d = std::max(pos.promotion_rank() - relative_rank(Us, s, pos.max_rank()), 1);
+ d += !!(attackedBy[Them][ALL_PIECES] & ~attackedBy2[Us] & blockSq);
+ score += make_score(PieceValue[MG][pt], PieceValue[EG][pt]) / (4 * d * d);
+ }
}
if (T)
&& depth >= 5
&& abs(beta) < VALUE_TB_WIN_IN_MAX_PLY)
{
- Value raisedBeta = std::min(beta + 189 - 45 * improving, VALUE_INFINITE);
+ Value raisedBeta = std::min(beta + (189 + 20 * !!pos.capture_the_flag_piece()) * (1 + pos.check_counting() + (pos.extinction_value() != VALUE_NONE)) - 45 * improving, VALUE_INFINITE);
- MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &thisThread->captureHistory);
+ MovePicker mp(pos, ttMove, raisedBeta - ss->staticEval, &captureHistory);
int probCutCount = 0;
while ( (move = mp.next_move()) != MOVE_NONE
&& bestValue > VALUE_TB_LOSS_IN_MAX_PLY)
{
// Skip quiet moves if movecount exceeds our FutilityMoveCount threshold
- moveCountPruning = moveCount >= futility_move_count(improving, depth);
+ moveCountPruning = moveCount >= futility_move_count(improving, depth)
+ || (pos.must_capture() && (moveCountPruning || (pos.capture(move) && pos.legal(move))));
+ // Reduced depth of the next LMR search
+ int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
+
if ( !captureOrPromotion
- && !givesCheck)
+ && !givesCheck
+ && !(pos.must_capture() && pos.attackers_to(to_sq(move), ~us)))
{
- // Reduced depth of the next LMR search
- int lmrDepth = std::max(newDepth - reduction(improving, depth, moveCount), 0);
-
// Countermoves based pruning (~20 Elo)
if ( lmrDepth < 4 + ((ss-1)->statScore > 0 || (ss-1)->moveCount == 1)
- && (*contHist[0])[movedPiece][to_sq(move)] < CounterMovePruneThreshold
- && (*contHist[1])[movedPiece][to_sq(move)] < CounterMovePruneThreshold)
+ && (*contHist[0])[history_slot(movedPiece)][to_sq(move)] < CounterMovePruneThreshold
+ && (*contHist[1])[history_slot(movedPiece)][to_sq(move)] < CounterMovePruneThreshold)
continue;
// Futility pruning: parent node (~5 Elo)
continue;
// Prune moves with negative SEE (~20 Elo)
- if (!pos.see_ge(move, Value(-(32 - std::min(lmrDepth, 18)) * lmrDepth * lmrDepth)))
+ if (!pos.see_ge(move, Value(-(32 - std::min(lmrDepth, 18) + 10 * !!pos.capture_the_flag_piece()) * lmrDepth * lmrDepth)))
continue;
}
- else if (!pos.see_ge(move, Value(-194 - 120 * pos.captures_to_hand()) * depth)) // (~25 Elo)
- continue;
+ else
+ {
+ if ( !givesCheck
+ && lmrDepth < 1
+ && captureHistory[movedPiece][to_sq(move)][type_of(pos.piece_on(to_sq(move)))] < 0)
+ continue;
+
- if (!pos.see_ge(move, Value(-194) * depth)) // (~25 Elo)
++ if (!pos.see_ge(move, Value(-194 - 120 * pos.captures_to_hand()) * depth)) // (~25 Elo)
+ continue;
+ }
}
// Step 14. Extensions (~75 Elo)
r++;
// Decrease/increase reduction for moves with a good/bad history (~30 Elo)
- r -= ss->statScore / 16434;
+ r -= ss->statScore / (16434 - 4434 * pos.captures_to_hand());
}
-
- // Increase reduction for captures/promotions if late move and at low depth
- else if (depth < 8 && moveCount > 2)
- r++;
+ else
+ {
+ // Increase reduction for captures/promotions if late move and at low depth
+ if (depth < 8 && moveCount > 2)
+ r++;
+
+ // Unless giving check, this capture is likely bad
+ if ( !givesCheck
+ && ss->staticEval + PieceValue[EG][pos.captured_piece()] + 200 * depth <= alpha)
+ r++;
+ }
Depth d = Utility::clamp(newDepth - r, 1, newDepth);