Skip to content

Commit

Permalink
SPSA tune search, king safety, history updates, tempo (#690)
Browse files Browse the repository at this point in the history
Elo   | 5.67 +- 2.46 (95%)
Conf  | 8.0+0.08s Threads=1 Hash=32MB
Games | N: 40006 W: 10812 L: 10159 D: 19035
Penta | [592, 4628, 9013, 5075, 695]
http://chess.grantnet.us/test/34396/

Elo   | 2.14 +- 2.15 (95%)
SPRT  | 40.0+0.40s Threads=1 Hash=128MB
LLR   | 2.89 (-2.25, 2.89) [0.00, 3.00]
Games | N: 48152 W: 11690 L: 11393 D: 25069
Penta | [364, 5618, 11799, 5947, 348]
http://chess.grantnet.us/test/34392/

Bench: 34121414
  • Loading branch information
TerjeKir authored Nov 12, 2023
1 parent 66bf22b commit 6ffe42b
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 30 deletions.
8 changes: 4 additions & 4 deletions src/evaluate.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const int PieceValue[2][PIECE_NB] = {
};

// Bonus for being the side to move
const int Tempo = 15;
const int Tempo = 19;

// Misc bonuses and maluses
const int PawnDoubled = S(-11,-48);
Expand Down Expand Up @@ -137,9 +137,9 @@ const int Mobility[4][28] = {
};

// KingSafety [pt-2]
const int AttackPower[4] = { 35, 18, 31, 81 };
const int CheckPower[4] = { 85, 39, 72, 68 };
const int CountModifier[8] = { 0, 0, 65, 124, 96, 124, 123, 128 };
const int AttackPower[4] = { 36, 19, 22, 72 };
const int CheckPower[4] = { 71, 39, 80, 74 };
const int CountModifier[8] = { 0, 0, 63, 126, 96, 124, 124, 128 };


// Evaluates pawns
Expand Down
8 changes: 4 additions & 4 deletions src/history.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@
#define NoisyEntry(move) (&thread->captureHistory[piece(move)][toSq(move)][PieceTypeOf(capturing(move))])
#define ContEntry(offset, move) (&(*(ss-offset)->continuation)[piece(move)][toSq(move)])

#define QuietHistoryUpdate(move, bonus) (HistoryBonus(QuietEntry(move), bonus, 6000))
#define NoisyHistoryUpdate(move, bonus) (HistoryBonus(NoisyEntry(move), bonus, 16900))
#define ContHistoryUpdate(offset, move, bonus) (HistoryBonus(ContEntry(offset, move), bonus, 21250))
#define QuietHistoryUpdate(move, bonus) (HistoryBonus(QuietEntry(move), bonus, 5885))
#define NoisyHistoryUpdate(move, bonus) (HistoryBonus(NoisyEntry(move), bonus, 14500))
#define ContHistoryUpdate(offset, move, bonus) (HistoryBonus(ContEntry(offset, move), bonus, 23930))


INLINE void HistoryBonus(int16_t *cur, int bonus, int div) {
*cur += bonus - *cur * abs(bonus) / div;
}

INLINE int Bonus(Depth depth) {
return MIN(2135, 400 * depth - 280);
return MIN(2300, 315 * depth - 255);
}

INLINE void UpdateContHistories(Stack *ss, Move move, int bonus) {
Expand Down
6 changes: 3 additions & 3 deletions src/movepicker.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static void ScoreMoves(MovePicker *mp, const int stage) {
: GetCaptureHistory(thread, move) + PieceValue[MG][capturing(move)];
}

SortMoves(list, -1000 * mp->depth);
SortMoves(list, -1280 * mp->depth);
}

// Returns the next move to try in a position
Expand All @@ -96,8 +96,8 @@ Move NextMove(MovePicker *mp) {
case NOISY_GOOD:
// Save seemingly bad noisy moves for later
while ((move = PickNextMove(mp)))
if ( mp->list.moves[mp->list.next-1].score > 13450
|| (mp->list.moves[mp->list.next-1].score > -9000 && SEE(pos, move, mp->threshold)))
if ( mp->list.moves[mp->list.next-1].score > 13470
|| (mp->list.moves[mp->list.next-1].score > -8830 && SEE(pos, move, mp->threshold)))
return move;
else
mp->list.moves[mp->bads++].move = move;
Expand Down
38 changes: 19 additions & 19 deletions src/search.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ static int Reductions[2][32][32];
CONSTR(1) InitReductions() {
for (int depth = 1; depth < 32; ++depth)
for (int moves = 1; moves < 32; ++moves)
Reductions[0][depth][moves] = 0.10 + log(depth) * log(moves) / 3.00, // capture
Reductions[1][depth][moves] = 1.50 + log(depth) * log(moves) / 2.10; // quiet
Reductions[0][depth][moves] = 0.20 + log(depth) * log(moves) / 3.35, // capture
Reductions[1][depth][moves] = 1.35 + log(depth) * log(moves) / 2.75; // quiet
}

// Checks if the move is in the list of searchmoves if any were given
Expand Down Expand Up @@ -122,7 +122,7 @@ static int Quiescence(Thread *thread, Stack *ss, int alpha, const int beta) {
if (eval > alpha)
alpha = eval;

futility = eval + 60;
futility = eval + 68;
bestScore = eval;

moveloop:
Expand Down Expand Up @@ -298,7 +298,7 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth
bool improving = !inCheck && eval > (ss-2)->eval;

// Internal iterative reduction based on Rebel's idea
if (pvNode && depth >= 4 && !ttMove)
if (pvNode && depth >= 3 && !ttMove)
depth--;

if (cutnode && depth >= 8 && !ttMove)
Expand All @@ -311,15 +311,15 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth
// Reverse Futility Pruning
if ( depth < 7
&& eval >= beta
&& eval - 100 * depth - (ss-1)->histScore / 300 >= beta
&& (!ttMove || GetHistory(thread, ss, ttMove) > 7700))
&& eval - 80 * depth - (ss-1)->histScore / 230 >= beta
&& (!ttMove || GetHistory(thread, ss, ttMove) > 7300))
return eval;

// Null Move Pruning
if ( eval >= beta
&& eval >= ss->eval
&& ss->eval >= beta + 140 - 15 * depth
&& (ss-1)->histScore < 26000
&& ss->eval >= beta + 135 - 19 * depth
&& (ss-1)->histScore < 25500
&& pos->nonPawnCount[sideToMove] > (depth > 8)) {

Depth reduction = 3 + depth / 4 + MIN(3, (eval - beta) / 256);
Expand Down Expand Up @@ -364,7 +364,7 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth

// Cut if the reduced depth search beats the threshold
if (score >= probCutBeta)
return score - 115;
return score - 138;
}
}

Expand Down Expand Up @@ -397,19 +397,19 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth
&& thread->doPruning
&& bestScore > -TBWIN_IN_MAX) {

int R = Reductions[quiet][MIN(31, depth)][MIN(31, moveCount)] - ss->histScore / 8192;
int R = Reductions[quiet][MIN(31, depth)][MIN(31, moveCount)] - ss->histScore / 8550;
Depth lmrDepth = depth - 1 - R;

// Quiet late move pruning
if (moveCount > (improving ? depth * depth : depth * depth / 2))
if (moveCount > (improving ? 1 + depth * depth : -2 + depth * depth / 2))
mp.onlyNoisy = true;

// History pruning
if (lmrDepth < 3 && ss->histScore < -1024 * depth)
continue;

// SEE pruning
if (lmrDepth < 8 && !SEE(pos, move, quiet ? -50 * depth : -95 * depth))
if (lmrDepth < 7 && !SEE(pos, move, quiet ? -50 * depth : -85 * depth))
continue;
}

Expand Down Expand Up @@ -445,7 +445,7 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth
// Singular - extend by 1 or 2 ply
if (score < singularBeta) {
extension = 1;
if (!pvNode && score < singularBeta - 25 && ss->doubleExtensions <= 5)
if (!pvNode && score < singularBeta - 19 && ss->doubleExtensions <= 5)
extension = 2;
// MultiCut - ttMove as well as at least one other move seem good enough to beat beta
} else if (singularBeta >= beta)
Expand Down Expand Up @@ -477,7 +477,7 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth
// Base reduction
int r = Reductions[quiet][MIN(31, depth)][MIN(31, moveCount)];
// Adjust reduction by move history
r -= ss->histScore / 8192;
r -= ss->histScore / 8550;
// Reduce less in pv nodes
r -= pvNode;
// Reduce less when improving
Expand All @@ -496,7 +496,7 @@ static int AlphaBeta(Thread *thread, Stack *ss, int alpha, int beta, Depth depth

// Research with the same window at full depth if the reduced search failed high
if (score > alpha && lmrDepth < newDepth) {
bool deeper = score > bestScore + 55 + 13 * (newDepth - lmrDepth);
bool deeper = score > bestScore + 55 + 16 * (newDepth - lmrDepth);

newDepth += deeper;

Expand Down Expand Up @@ -583,21 +583,21 @@ static void AspirationWindow(Thread *thread, Stack *ss) {

int prevScore = thread->rootMoves[multiPV].score;

int delta = 10 + prevScore * prevScore / 16384;
int delta = 9 + prevScore * prevScore / 15500;

int alpha = MAX(prevScore - delta, -INFINITE);
int beta = MIN(prevScore + delta, INFINITE);

int x = CLAMP(prevScore / 2, -33, 33);
int x = CLAMP(prevScore / 2, -34, 34);
pos->trend = sideToMove == WHITE ? S(x, x/2) : -S(x, x/2);

// Repeatedly search and adjust the window until the score is inside the window
while (true) {

thread->doPruning =
Limits.infinite ? TimeSince(Limits.start) > 1000
: TimeSince(Limits.start) >= Limits.optimalUsage / 64
|| depth > 2 + Limits.optimalUsage / 256;
: TimeSince(Limits.start) >= Limits.optimalUsage / 58
|| depth > 2 + Limits.optimalUsage / 281;

int score = AlphaBeta(thread, ss, alpha, beta, depth, false);

Expand Down

0 comments on commit 6ffe42b

Please sign in to comment.