Increase number of tunables (bench 5459982)
This commit is contained in:
@@ -438,20 +438,20 @@ proc updateHistories(self: SearchManager, sideToMove: PieceColor, move: Move, pi
|
||||
let startAttacked = self.board.position.threats.contains(move.startSquare)
|
||||
let targetAttacked = self.board.position.threats.contains(move.targetSquare)
|
||||
if move.isQuiet():
|
||||
var bonus = (if good: self.parameters.moveBonuses.conthist.good else: -self.parameters.moveBonuses.conthist.bad) * depth
|
||||
|
||||
if ply > 0 and not self.board.positions[^2].fromNull:
|
||||
let prevPiece = self.stack[ply - 1].piece
|
||||
|
||||
let bonus = (if good: self.parameters.moveBonuses.conthist.ply1.good else: -self.parameters.moveBonuses.conthist.ply1.bad) * depth
|
||||
self.histories.continuationHistory[sideToMove][piece.kind][move.targetSquare][prevPiece.color][prevPiece.kind][self.stack[ply - 1].move.targetSquare] += (bonus - abs(bonus) * self.conthistScore(sideToMove, piece, move.targetSquare, ply, 1) div HISTORY_SCORE_CAP).int16
|
||||
if ply > 1 and not self.board.positions[^3].fromNull:
|
||||
let prevPiece = self.stack[ply - 2].piece
|
||||
let bonus = (if good: self.parameters.moveBonuses.conthist.ply2.good else: -self.parameters.moveBonuses.conthist.ply2.bad) * depth
|
||||
self.histories.continuationHistory[sideToMove][piece.kind][move.targetSquare][prevPiece.color][prevPiece.kind][self.stack[ply - 2].move.targetSquare] += (bonus - abs(bonus) * self.conthistScore(sideToMove, piece, move.targetSquare, ply, 2) div HISTORY_SCORE_CAP).int16
|
||||
if ply > 3 and not self.board.positions[^5].fromNull:
|
||||
let prevPiece = self.stack[ply - 4].piece
|
||||
let bonus = (if good: self.parameters.moveBonuses.conthist.ply4.good else: -self.parameters.moveBonuses.conthist.ply4.bad) * depth
|
||||
self.histories.continuationHistory[sideToMove][piece.kind][move.targetSquare][prevPiece.color][prevPiece.kind][self.stack[ply - 4].move.targetSquare] += (bonus - abs(bonus) * self.conthistScore(sideToMove, piece, move.targetSquare, ply, 4) div HISTORY_SCORE_CAP).int16
|
||||
|
||||
bonus = (if good: self.parameters.moveBonuses.quiet.good else: -self.parameters.moveBonuses.quiet.bad) * depth
|
||||
let bonus = (if good: self.parameters.moveBonuses.quiet.good else: -self.parameters.moveBonuses.quiet.bad) * depth
|
||||
self.histories.quietHistory[sideToMove][move.startSquare][move.targetSquare][startAttacked][targetAttacked] += int16(bonus - abs(bonus) * self.historyScore(sideToMove, move) div HISTORY_SCORE_CAP)
|
||||
|
||||
elif move.isCapture():
|
||||
@@ -483,7 +483,7 @@ proc scoreMove(self: SearchManager, hashMove: Move, move: Move, ply: int): Score
|
||||
|
||||
# Good/bad tacticals
|
||||
if move.isTactical():
|
||||
let winning = self.parameters.see(self.board.position, move, 0)
|
||||
let winning = self.parameters.see(self.board.position, move, 0, SeeOrdering)
|
||||
if move.isCapture():
|
||||
result.data += self.historyScore(sideToMove, move)
|
||||
# Prioritize attacking our opponent's
|
||||
@@ -839,7 +839,7 @@ proc qsearch(self: var SearchManager, root: static bool, ply: int, alpha, beta:
|
||||
elif scoredMove.stage() == BadNoisy:
|
||||
false
|
||||
else:
|
||||
self.parameters.see(self.board.position, move, 0)
|
||||
self.parameters.see(self.board.position, move, 0, SeePruning)
|
||||
# Skip known bad captures
|
||||
if not winning:
|
||||
continue
|
||||
@@ -849,7 +849,7 @@ proc qsearch(self: var SearchManager, root: static bool, ply: int, alpha, beta:
|
||||
|
||||
# Qsearch futility pruning: similar to FP in regular search, but we skip moves
|
||||
# that gain no material on top of not improving alpha (given a margin)
|
||||
if not recapture and not self.stack[ply].inCheck and staticEval + self.parameters.qsearchFpEvalMargin <= alpha and not self.parameters.see(self.board.position, move, 1):
|
||||
if not recapture and not self.stack[ply].inCheck and staticEval + self.parameters.qsearchFpEvalMargin <= alpha and not self.parameters.see(self.board.position, move, 1, SeePruning):
|
||||
continue
|
||||
let kingSq = self.board.position.kingSquare(self.board.sideToMove)
|
||||
self.stack[ply].move = move
|
||||
@@ -1056,7 +1056,9 @@ proc search(self: var SearchManager, depth, ply: int, alpha, beta: Score, isPV,
|
||||
# Reverse futility pruning: if the static eval suggests a fail high is likely,
|
||||
# cut off the node
|
||||
|
||||
let margin = (self.parameters.rfpMargins.base * depth) - self.parameters.rfpMargins.improving * improving.int
|
||||
let rfpBase = if hashMove.isQuiet(): self.parameters.rfpMargins.base.quiet else: self.parameters.rfpMargins.base.noisy
|
||||
let rfpImproving = if hashMove.isQuiet(): self.parameters.rfpMargins.improving.quiet else: self.parameters.rfpMargins.improving.noisy
|
||||
let margin = (rfpBase * depth) - rfpImproving * improving.int
|
||||
|
||||
if ttAdjustedEval - margin >= beta:
|
||||
# Instead of returning the static eval, we do something known as "fail mid"
|
||||
@@ -1097,7 +1099,8 @@ proc search(self: var SearchManager, depth, ply: int, alpha, beta: Score, isPV,
|
||||
NMP_DEPTH_REDUCTION = 3
|
||||
NMP_EVAL_DEPTH_MAX_REDUCTION = 3
|
||||
var reduction = NMP_BASE_REDUCTION + depth div NMP_DEPTH_REDUCTION
|
||||
reduction += min((staticEval - beta) div self.parameters.nmpEvalDivisor, NMP_EVAL_DEPTH_MAX_REDUCTION)
|
||||
let nmpDivisor = if hashMove.isQuiet(): self.parameters.nmpEvalDivisor.quiet else: self.parameters.nmpEvalDivisor.noisy
|
||||
reduction += min((staticEval - beta) div nmpDivisor, NMP_EVAL_DEPTH_MAX_REDUCTION)
|
||||
let score = -self.search(depth - reduction, ply + 1, -beta - 1, -beta, isPV=false, root=false, cutNode=not cutNode)
|
||||
self.board.unmakeMove()
|
||||
if self.shouldStop():
|
||||
@@ -1178,7 +1181,7 @@ proc search(self: var SearchManager, depth, ply: int, alpha, beta: Score, isPV,
|
||||
if lmrDepth <= SEE_PRUNING_MAX_DEPTH and (move.isQuiet() or move.isCapture() or move.isEnPassant()):
|
||||
# SEE pruning: prune moves with a bad enough SEE score
|
||||
let margin = -depth * (if move.isQuiet(): self.parameters.seePruningMargin.quiet else: self.parameters.seePruningMargin.capture)
|
||||
if not self.parameters.see(self.board.position, move, margin):
|
||||
if not self.parameters.see(self.board.position, move, margin, SeePruning):
|
||||
inc(seenMoves)
|
||||
continue
|
||||
var singular = 0
|
||||
@@ -1213,7 +1216,9 @@ proc search(self: var SearchManager, depth, ply: int, alpha, beta: Score, isPV,
|
||||
|
||||
# Multiple extensions. Hash move is increasingly singular: explore it
|
||||
# even deeper
|
||||
for margin in [self.parameters.doubleExtMargin, self.parameters.tripleExtMargin]:
|
||||
let doubleExtMargin = if hashMove.isQuiet(): self.parameters.doubleExtMargin.quiet else: self.parameters.doubleExtMargin.noisy
|
||||
let tripleExtMargin = if hashMove.isQuiet(): self.parameters.tripleExtMargin.quiet else: self.parameters.tripleExtMargin.noisy
|
||||
for margin in [doubleExtMargin, tripleExtMargin]:
|
||||
if singularScore <= newAlpha - margin:
|
||||
inc(singular)
|
||||
elif newBeta >= beta:
|
||||
@@ -1314,7 +1319,8 @@ proc search(self: var SearchManager, depth, ply: int, alpha, beta: Score, isPV,
|
||||
let prevMove = self.stack[ply - 1].move
|
||||
self.histories.counterMoves[prevMove.startSquare][prevMove.targetSquare] = move
|
||||
|
||||
let histDepth = depth + (bestScore - beta > self.parameters.historyDepthEvalThreshold).int
|
||||
let historyEvalThreshold = if move.isQuiet(): self.parameters.historyDepthEvalThreshold.quiet else: self.parameters.historyDepthEvalThreshold.noisy
|
||||
let histDepth = depth + (bestScore - beta > historyEvalThreshold).int
|
||||
# If the best move we found is a tactical move, we don't want to punish quiets,
|
||||
# because they still might be good (just not as good wrt the best move).
|
||||
# Very important to note that move == bestMove here!
|
||||
@@ -1420,16 +1426,18 @@ proc aspirationSearch(self: var SearchManager, depth: int, score: Score): Score
|
||||
# Reset the reduction whenever we fail low to ensure
|
||||
# we don't miss good stuff that seems bad at first
|
||||
reduction = 0
|
||||
# Try again with larger window
|
||||
delta = Score(delta * self.parameters.aspWindowWideningFactor.failLow div 128)
|
||||
elif score >= beta:
|
||||
beta = min(SCORE_INF, score + delta)
|
||||
# Whenever we fail high, reduce the search depth as we
|
||||
# expect the score to be good for our opponent anyway
|
||||
reduction += 1
|
||||
# Try again with larger window
|
||||
delta = Score(delta * self.parameters.aspWindowWideningFactor.failHigh div 128)
|
||||
else:
|
||||
# Value was within the alpha-beta bounds, we're done
|
||||
break
|
||||
# Try again with larger window
|
||||
delta += delta
|
||||
if delta >= Score(self.parameters.aspWindowMaxSize):
|
||||
# Window got too wide, give up and search with the full range
|
||||
# of alpha-beta values
|
||||
|
||||
@@ -206,7 +206,9 @@ proc scale(self: var SearchLimit, limiter: SearchLimiter, params: SearchParamete
|
||||
totalNodes = limiter.searchStats.nodeCount.load(moRelaxed)
|
||||
bestMoveNodes = limiter.searchStats.spentNodes[move.startSquare][move.targetSquare].load(moRelaxed)
|
||||
bestMoveFrac = bestMoveNodes.float / totalNodes.float
|
||||
scaleFactor = params.nodeTmBaseOffset - bestMoveFrac * params.nodeTmScaleFactor
|
||||
baseOffset = if move.isQuiet(): params.nodeTmBaseOffset.quiet else: params.nodeTmBaseOffset.noisy
|
||||
factor = if move.isQuiet(): params.nodeTmScaleFactor.quiet else: params.nodeTmScaleFactor.noisy
|
||||
scaleFactor = baseOffset - bestMoveFrac * factor
|
||||
self.lowerBound = min(self.upperBound, (self.origLowerBound.float * scaleFactor).uint64)
|
||||
|
||||
|
||||
|
||||
@@ -18,17 +18,22 @@ import heimdall/[pieces, board, position]
|
||||
import heimdall/util/tunables
|
||||
|
||||
|
||||
func gain(parameters: SearchParameters, position: Position, move: Move): int =
|
||||
type
|
||||
SeeContext* = enum
|
||||
SeeOrdering, SeePruning
|
||||
|
||||
|
||||
func gain(weights: array[Pawn..Empty, int], position: Position, move: Move): int =
|
||||
## Returns how much a single move gains in terms
|
||||
## of static material value
|
||||
if move.isCastling():
|
||||
return 0
|
||||
if move.isEnPassant():
|
||||
return parameters.staticPieceScore(Pawn)
|
||||
return weights[Pawn]
|
||||
|
||||
result = parameters.staticPieceScore(position.on(move.targetSquare))
|
||||
result = weights[position.on(move.targetSquare).kind]
|
||||
if move.isPromotion():
|
||||
result += parameters.staticPieceScore(move.flag().promotionToPiece()) - parameters.staticPieceScore(Pawn)
|
||||
result += weights[move.flag().promotionToPiece()] - weights[Pawn]
|
||||
|
||||
|
||||
func popLeastValuable(position: Position, occupancy: var Bitboard, attackers: Bitboard, stm: PieceColor): PieceKind =
|
||||
@@ -44,7 +49,7 @@ func popLeastValuable(position: Position, occupancy: var Bitboard, attackers: Bi
|
||||
return Empty
|
||||
|
||||
|
||||
proc see*(parameters: SearchParameters, position: Position, move: Move, threshold: int): bool =
|
||||
proc see*(parameters: SearchParameters, position: Position, move: Move, threshold: int, context: SeeContext): bool =
|
||||
## Statically evaluates a sequence of exchanges
|
||||
## starting from the given one and returns whether
|
||||
## the exchange can beat the given threshold.
|
||||
@@ -54,12 +59,18 @@ proc see*(parameters: SearchParameters, position: Position, move: Move, threshol
|
||||
|
||||
# Yoinked from Stormphrax
|
||||
|
||||
var score = gain(parameters, position, move) - threshold
|
||||
let weights = case context:
|
||||
of SeeOrdering: parameters.seeWeights.ordering
|
||||
of SeePruning:
|
||||
if move.isQuiet(): parameters.seeWeights.pruneQuiet
|
||||
else: parameters.seeWeights.pruneNoisy
|
||||
|
||||
var score = gain(weights, position, move) - threshold
|
||||
if score < 0:
|
||||
return false
|
||||
|
||||
var next = if move.isPromotion(): move.flag().promotionToPiece() else: position.on(move.startSquare).kind
|
||||
score -= parameters.staticPieceScore(next)
|
||||
score -= weights[next]
|
||||
|
||||
if score >= 0:
|
||||
return true
|
||||
@@ -92,7 +103,7 @@ proc see*(parameters: SearchParameters, position: Position, move: Move, threshol
|
||||
|
||||
attackers = attackers and occupancy
|
||||
|
||||
score = -score - 1 - parameters.staticPieceScore(next)
|
||||
score = -score - 1 - weights[next]
|
||||
stm = stm.opposite()
|
||||
|
||||
if score >= 0:
|
||||
@@ -103,4 +114,4 @@ proc see*(parameters: SearchParameters, position: Position, move: Move, threshol
|
||||
# We beat the threshold, hooray!
|
||||
break
|
||||
|
||||
return position.sideToMove != stm
|
||||
return position.sideToMove != stm
|
||||
|
||||
@@ -34,10 +34,10 @@ type
|
||||
|
||||
SearchParameters* = ref object
|
||||
# NMP: Reduce search depth by min((staticEval - beta) / divisor, maxValue)
|
||||
nmpEvalDivisor*: int
|
||||
nmpEvalDivisor*: tuple[quiet, noisy: int]
|
||||
|
||||
# RFP: Prune only when staticEval - (depth * base - improving_margin * improving) >= beta
|
||||
rfpMargins*: tuple[base, improving: int]
|
||||
rfpMargins*: tuple[base, improving: tuple[quiet, noisy: int]]
|
||||
|
||||
# FP: Prune only when (staticEval + offset) + margin * (depth + improving) <= alpha
|
||||
fpEvalMargin*: int
|
||||
@@ -55,6 +55,9 @@ type
|
||||
# of alpha beta values once the window
|
||||
# size gets to this value
|
||||
aspWindowMaxSize*: int
|
||||
# Delta widening divisors (delta = delta * 128 / divisor)
|
||||
# for fail low (score <= alpha) and fail high (score >= beta)
|
||||
aspWindowWideningFactor*: tuple[failLow, failHigh: int]
|
||||
|
||||
# Only prune quiet/capture moves whose SEE score
|
||||
# is < this value times depth
|
||||
@@ -62,7 +65,7 @@ type
|
||||
|
||||
# Good/bad moves get their bonus/malus * depth in their
|
||||
# respective history tables
|
||||
moveBonuses*: tuple[quiet, capture, conthist: tuple[good, bad: int]]
|
||||
moveBonuses*: tuple[quiet, capture: tuple[good, bad: int], conthist: tuple[ply1, ply2, ply4: tuple[good, bad: int]]]
|
||||
|
||||
# Time management
|
||||
|
||||
@@ -72,15 +75,15 @@ type
|
||||
|
||||
# These are tuned as integers and then divided by 1000
|
||||
# when loading them in
|
||||
nodeTmBaseOffset*: float
|
||||
nodeTmScaleFactor*: float
|
||||
nodeTmBaseOffset*: tuple[quiet, noisy: float]
|
||||
nodeTmScaleFactor*: tuple[quiet, noisy: float]
|
||||
|
||||
# Eval margin for qsearch futility pruning
|
||||
qsearchFpEvalMargin*: int
|
||||
|
||||
# Score margins for multiple extensions
|
||||
doubleExtMargin*: int
|
||||
tripleExtMargin*: int
|
||||
doubleExtMargin*: tuple[quiet, noisy: int]
|
||||
tripleExtMargin*: tuple[quiet, noisy: int]
|
||||
|
||||
# Material scaling parameters
|
||||
materialScalingOffset*: int
|
||||
@@ -88,10 +91,10 @@ type
|
||||
|
||||
# Eval threshold for increasing depth
|
||||
# for move history updates
|
||||
historyDepthEvalThreshold*: int
|
||||
historyDepthEvalThreshold*: tuple[quiet, noisy: int]
|
||||
|
||||
# Tunable piece weights
|
||||
seeWeights*: array[Pawn..Empty, int]
|
||||
# Tunable piece weights for SEE (split by context)
|
||||
seeWeights*: tuple[ordering, pruneQuiet, pruneNoisy: array[Pawn..Empty, int]]
|
||||
materialWeights*: array[Pawn..Empty, int]
|
||||
|
||||
# LMR table parameters (tuned as integers, divided by 1000)
|
||||
@@ -121,41 +124,63 @@ NonPawnCorrHistWeightScale, 254
|
||||
AspWindowMaxSize, 980
|
||||
NonPawnCorrHistEvalScale, 470
|
||||
MaterialKnightWeight, 465
|
||||
DoubleExtMargin, 15
|
||||
SEEQueenWeight, 1257
|
||||
NodeTMBaseOffset, 2861
|
||||
DoubleExtMarginQuiet, 15
|
||||
DoubleExtMarginNoisy, 15
|
||||
SEEOrdQueenWeight, 1257
|
||||
SEEPruneQuietQueenWeight, 1257
|
||||
SEEPruneNoisyQueenWeight, 1257
|
||||
NodeTMBaseOffsetQuiet, 2861
|
||||
NodeTMBaseOffsetNoisy, 2861
|
||||
SEEPruningQuietMargin, 79
|
||||
SEEPruningCaptureMargin, 124
|
||||
NMPEvalDivisor, 243
|
||||
RFPImprovingMargin, 135
|
||||
HistoryDepthEvalThreshold, 53
|
||||
NMPEvalDivisorQuiet, 243
|
||||
NMPEvalDivisorNoisy, 243
|
||||
RFPImprovingMarginQuiet, 135
|
||||
RFPImprovingMarginNoisy, 135
|
||||
HistoryDepthEvalThresholdQuiet, 53
|
||||
HistoryDepthEvalThresholdNoisy, 53
|
||||
BadQuietMalus, 280
|
||||
ContHistMalus, 280
|
||||
SEEKnightWeight, 465
|
||||
ContHistMalusPly1, 280
|
||||
ContHistMalusPly2, 280
|
||||
ContHistMalusPly4, 280
|
||||
SEEOrdKnightWeight, 465
|
||||
SEEPruneQuietKnightWeight, 465
|
||||
SEEPruneNoisyKnightWeight, 465
|
||||
NonPawnCorrHistMinValue, -12428
|
||||
RFPBaseMargin, 168
|
||||
RFPBaseMarginQuiet, 168
|
||||
RFPBaseMarginNoisy, 168
|
||||
HistoryLMRQuietDivisor, 10901
|
||||
MajorCorrHistMaxValue, 12028
|
||||
PawnCorrHistWeightScale, 255
|
||||
SEEPawnWeight, 99
|
||||
SEERookWeight, 691
|
||||
SEEOrdPawnWeight, 99
|
||||
SEEPruneQuietPawnWeight, 99
|
||||
SEEPruneNoisyPawnWeight, 99
|
||||
SEEOrdRookWeight, 691
|
||||
SEEPruneQuietRookWeight, 691
|
||||
SEEPruneNoisyRookWeight, 691
|
||||
MinorCorrHistWeightScale, 260
|
||||
AspWindowInitialSize, 19
|
||||
MinorCorrHistMinValue, -12442
|
||||
QSearchFPEvalMargin, 211
|
||||
MajorCorrHistMinValue, -12308
|
||||
TripleExtMargin, 50
|
||||
TripleExtMarginQuiet, 50
|
||||
TripleExtMarginNoisy, 50
|
||||
MaterialRookWeight, 647
|
||||
HistoryLMRNoisyDivisor, 13902
|
||||
GoodCaptureBonus, 45
|
||||
NodeTMScaleFactor, 1634
|
||||
NodeTMScaleFactorQuiet, 1634
|
||||
NodeTMScaleFactorNoisy, 1634
|
||||
MatScalingOffset, 26283
|
||||
GoodQuietBonus, 261
|
||||
ContHistBonus, 261
|
||||
ContHistBonusPly1, 261
|
||||
ContHistBonusPly2, 261
|
||||
ContHistBonusPly4, 261
|
||||
MajorCorrHistWeightScale, 257
|
||||
PawnCorrHistMinValue, -12060
|
||||
PawnCorrHistMaxValue, 12461
|
||||
SEEBishopWeight, 485
|
||||
SEEOrdBishopWeight, 485
|
||||
SEEPruneQuietBishopWeight, 485
|
||||
SEEPruneNoisyBishopWeight, 485
|
||||
FPBaseOffset, 5
|
||||
BadCaptureMalus, 113
|
||||
FPEvalMargin, 98
|
||||
@@ -177,8 +202,10 @@ template addTunableParameter(name: string, min, max, default: int, quantized = f
|
||||
proc initTunableParameters: Table[string, TunableParameter] =
|
||||
## Adds all our tunable parameters to the global
|
||||
## parameter list
|
||||
addTunableParameter("RFPBaseMargin", 1, 200, 100)
|
||||
addTunableParameter("RFPImprovingMargin", 1, 200, 100)
|
||||
addTunableParameter("RFPBaseMarginQuiet", 1, 200, 100)
|
||||
addTunableParameter("RFPBaseMarginNoisy", 1, 200, 100)
|
||||
addTunableParameter("RFPImprovingMarginQuiet", 1, 200, 100)
|
||||
addTunableParameter("RFPImprovingMarginNoisy", 1, 200, 100)
|
||||
addTunableParameter("FPEvalMargin", 1, 500, 250)
|
||||
addTunableParameter("FPBaseOffset", 0, 200, 1)
|
||||
# Value asspulled by cj, btw
|
||||
@@ -186,32 +213,54 @@ proc initTunableParameters: Table[string, TunableParameter] =
|
||||
addTunableParameter("HistoryLMRNoisyDivisor", 6144, 24576, 12288, true)
|
||||
addTunableParameter("AspWindowInitialSize", 1, 60, 30)
|
||||
addTunableParameter("AspWindowMaxSize", 1, 2000, 1000)
|
||||
addTunableParameter("AspWindowWideningFailLow", 128, 384, 256)
|
||||
addTunableParameter("AspWindowWideningFailHigh", 128, 384, 256)
|
||||
addTunableParameter("SEEPruningQuietMargin", 1, 160, 80)
|
||||
addTunableParameter("SEEPruningCaptureMargin", 1, 320, 160)
|
||||
addTunableParameter("GoodQuietBonus", 1, 340, 170)
|
||||
addTunableParameter("BadQuietMalus", 1, 900, 450)
|
||||
addTunableParameter("GoodCaptureBonus", 1, 90, 45)
|
||||
addTunableParameter("BadCaptureMalus", 1, 224, 112)
|
||||
addTunableParameter("ContHistBonus", 1, 340, 170)
|
||||
addTunableParameter("ContHistMalus", 1, 900, 450)
|
||||
addTunableParameter("ContHistBonusPly1", 1, 340, 170)
|
||||
addTunableParameter("ContHistMalusPly1", 1, 900, 450)
|
||||
addTunableParameter("ContHistBonusPly2", 1, 340, 170)
|
||||
addTunableParameter("ContHistMalusPly2", 1, 900, 450)
|
||||
addTunableParameter("ContHistBonusPly4", 1, 340, 170)
|
||||
addTunableParameter("ContHistMalusPly4", 1, 900, 450)
|
||||
# Values yoinked from Stormphrax :3
|
||||
addTunableParameter("NodeTMBaseOffset", 1000, 3000, 2630)
|
||||
addTunableParameter("NodeTMScaleFactor", 1000, 2500, 1700)
|
||||
addTunableParameter("NodeTMBaseOffsetQuiet", 1000, 3000, 2630)
|
||||
addTunableParameter("NodeTMBaseOffsetNoisy", 1000, 3000, 2630)
|
||||
addTunableParameter("NodeTMScaleFactorQuiet", 1000, 2500, 1700)
|
||||
addTunableParameter("NodeTMScaleFactorNoisy", 1000, 2500, 1700)
|
||||
addTunableParameter("QSearchFPEvalMargin", 100, 400, 200)
|
||||
# We copying sf on this one
|
||||
addTunableParameter("DoubleExtMargin", 0, 80, 40)
|
||||
addTunableParameter("TripleExtMargin", 50, 200, 100)
|
||||
addTunableParameter("DoubleExtMarginQuiet", 0, 80, 40)
|
||||
addTunableParameter("DoubleExtMarginNoisy", 0, 80, 40)
|
||||
addTunableParameter("TripleExtMarginQuiet", 50, 200, 100)
|
||||
addTunableParameter("TripleExtMarginNoisy", 50, 200, 100)
|
||||
|
||||
addTunableParameter("MatScalingOffset", 13250, 53000, 26500)
|
||||
addTunableParameter("MatScalingDivisor", 16384, 65536, 32768)
|
||||
addTunableParameter("NMPEvalDivisor", 120, 350, 245)
|
||||
addTunableParameter("HistoryDepthEvalThreshold", 25, 100, 50)
|
||||
addTunableParameter("NMPEvalDivisorQuiet", 120, 350, 245)
|
||||
addTunableParameter("NMPEvalDivisorNoisy", 120, 350, 245)
|
||||
addTunableParameter("HistoryDepthEvalThresholdQuiet", 25, 100, 50)
|
||||
addTunableParameter("HistoryDepthEvalThresholdNoisy", 25, 100, 50)
|
||||
|
||||
addTunableParameter("SEEPawnWeight", 50, 200, 100)
|
||||
addTunableParameter("SEEKnightWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEBishopWeight", 225, 900, 450)
|
||||
addTunableParameter("SEERookWeight", 325, 1300, 650)
|
||||
addTunableParameter("SEEQueenWeight", 625, 2500, 1250)
|
||||
addTunableParameter("SEEOrdPawnWeight", 50, 200, 100)
|
||||
addTunableParameter("SEEOrdKnightWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEOrdBishopWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEOrdRookWeight", 325, 1300, 650)
|
||||
addTunableParameter("SEEOrdQueenWeight", 625, 2500, 1250)
|
||||
addTunableParameter("SEEPruneQuietPawnWeight", 50, 200, 100)
|
||||
addTunableParameter("SEEPruneQuietKnightWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEPruneQuietBishopWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEPruneQuietRookWeight", 325, 1300, 650)
|
||||
addTunableParameter("SEEPruneQuietQueenWeight", 625, 2500, 1250)
|
||||
addTunableParameter("SEEPruneNoisyPawnWeight", 50, 200, 100)
|
||||
addTunableParameter("SEEPruneNoisyKnightWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEPruneNoisyBishopWeight", 225, 900, 450)
|
||||
addTunableParameter("SEEPruneNoisyRookWeight", 325, 1300, 650)
|
||||
addTunableParameter("SEEPruneNoisyQueenWeight", 625, 2500, 1250)
|
||||
addTunableParameter("MaterialPawnWeight", 50, 200, 100)
|
||||
addTunableParameter("MaterialKnightWeight", 225, 900, 450)
|
||||
addTunableParameter("MaterialBishopWeight", 225, 900, 450)
|
||||
@@ -274,10 +323,14 @@ proc setParameter*(self: SearchParameters, name: string, value: int) =
|
||||
# This is ugly, but short of macro shenanigans it's
|
||||
# the best we can do
|
||||
case name:
|
||||
of "RFPBaseMargin":
|
||||
self.rfpMargins.base = value
|
||||
of "RFPImprovingMargin":
|
||||
self.rfpMargins.improving = value
|
||||
of "RFPBaseMarginQuiet":
|
||||
self.rfpMargins.base.quiet = value
|
||||
of "RFPBaseMarginNoisy":
|
||||
self.rfpMargins.base.noisy = value
|
||||
of "RFPImprovingMarginQuiet":
|
||||
self.rfpMargins.improving.quiet = value
|
||||
of "RFPImprovingMarginNoisy":
|
||||
self.rfpMargins.improving.noisy = value
|
||||
of "FPEvalMargin":
|
||||
self.fpEvalMargin = value
|
||||
of "FPBaseOffset":
|
||||
@@ -290,6 +343,10 @@ proc setParameter*(self: SearchParameters, name: string, value: int) =
|
||||
self.aspWindowInitialSize = value
|
||||
of "AspWindowMaxSize":
|
||||
self.aspWindowMaxSize = value
|
||||
of "AspWindowWideningFailLow":
|
||||
self.aspWindowWideningFactor.failLow = value
|
||||
of "AspWindowWideningFailHigh":
|
||||
self.aspWindowWideningFactor.failHigh = value
|
||||
of "SEEPruningQuietMargin":
|
||||
self.seePruningMargin.quiet = value
|
||||
of "SEEPruningCaptureMargin":
|
||||
@@ -298,42 +355,82 @@ proc setParameter*(self: SearchParameters, name: string, value: int) =
|
||||
self.moveBonuses.quiet.good = value
|
||||
of "BadQuietMalus":
|
||||
self.moveBonuses.quiet.bad = value
|
||||
of "ContHistBonus":
|
||||
self.moveBonuses.conthist.good = value
|
||||
of "ContHistMalus":
|
||||
self.moveBonuses.conthist.bad = value
|
||||
of "ContHistBonusPly1":
|
||||
self.moveBonuses.conthist.ply1.good = value
|
||||
of "ContHistMalusPly1":
|
||||
self.moveBonuses.conthist.ply1.bad = value
|
||||
of "ContHistBonusPly2":
|
||||
self.moveBonuses.conthist.ply2.good = value
|
||||
of "ContHistMalusPly2":
|
||||
self.moveBonuses.conthist.ply2.bad = value
|
||||
of "ContHistBonusPly4":
|
||||
self.moveBonuses.conthist.ply4.good = value
|
||||
of "ContHistMalusPly4":
|
||||
self.moveBonuses.conthist.ply4.bad = value
|
||||
of "GoodCaptureBonus":
|
||||
self.moveBonuses.capture.good = value
|
||||
of "BadCaptureMalus":
|
||||
self.moveBonuses.capture.bad = value
|
||||
of "NodeTMBaseOffset":
|
||||
self.nodeTmBaseOffset = value / 1000
|
||||
of "NodeTMScaleFactor":
|
||||
self.nodeTmScaleFactor = value / 1000
|
||||
of "NodeTMBaseOffsetQuiet":
|
||||
self.nodeTmBaseOffset.quiet = value / 1000
|
||||
of "NodeTMBaseOffsetNoisy":
|
||||
self.nodeTmBaseOffset.noisy = value / 1000
|
||||
of "NodeTMScaleFactorQuiet":
|
||||
self.nodeTmScaleFactor.quiet = value / 1000
|
||||
of "NodeTMScaleFactorNoisy":
|
||||
self.nodeTmScaleFactor.noisy = value / 1000
|
||||
of "QSearchFPEvalMargin":
|
||||
self.qsearchFpEvalMargin = value
|
||||
of "DoubleExtMargin":
|
||||
self.doubleExtMargin = value
|
||||
of "DoubleExtMarginQuiet":
|
||||
self.doubleExtMargin.quiet = value
|
||||
of "DoubleExtMarginNoisy":
|
||||
self.doubleExtMargin.noisy = value
|
||||
of "MatScalingDivisor":
|
||||
self.materialScalingDivisor = value
|
||||
of "MatScalingOffset":
|
||||
self.materialScalingOffset = value
|
||||
of "NMPEvalDivisor":
|
||||
self.nmpEvalDivisor = value
|
||||
of "TripleExtMargin":
|
||||
self.tripleExtMargin = value
|
||||
of "HistoryDepthEvalThreshold":
|
||||
self.historyDepthEvalThreshold = value
|
||||
of "SEEPawnWeight":
|
||||
self.seeWeights[Pawn] = value
|
||||
of "SEEKnightWeight":
|
||||
self.seeWeights[Knight] = value
|
||||
of "SEEBishopWeight":
|
||||
self.seeWeights[Bishop] = value
|
||||
of "SEERookWeight":
|
||||
self.seeWeights[Rook] = value
|
||||
of "SEEQueenWeight":
|
||||
self.seeWeights[Queen] = value
|
||||
of "NMPEvalDivisorQuiet":
|
||||
self.nmpEvalDivisor.quiet = value
|
||||
of "NMPEvalDivisorNoisy":
|
||||
self.nmpEvalDivisor.noisy = value
|
||||
of "TripleExtMarginQuiet":
|
||||
self.tripleExtMargin.quiet = value
|
||||
of "TripleExtMarginNoisy":
|
||||
self.tripleExtMargin.noisy = value
|
||||
of "HistoryDepthEvalThresholdQuiet":
|
||||
self.historyDepthEvalThreshold.quiet = value
|
||||
of "HistoryDepthEvalThresholdNoisy":
|
||||
self.historyDepthEvalThreshold.noisy = value
|
||||
of "SEEOrdPawnWeight":
|
||||
self.seeWeights.ordering[Pawn] = value
|
||||
of "SEEOrdKnightWeight":
|
||||
self.seeWeights.ordering[Knight] = value
|
||||
of "SEEOrdBishopWeight":
|
||||
self.seeWeights.ordering[Bishop] = value
|
||||
of "SEEOrdRookWeight":
|
||||
self.seeWeights.ordering[Rook] = value
|
||||
of "SEEOrdQueenWeight":
|
||||
self.seeWeights.ordering[Queen] = value
|
||||
of "SEEPruneQuietPawnWeight":
|
||||
self.seeWeights.pruneQuiet[Pawn] = value
|
||||
of "SEEPruneQuietKnightWeight":
|
||||
self.seeWeights.pruneQuiet[Knight] = value
|
||||
of "SEEPruneQuietBishopWeight":
|
||||
self.seeWeights.pruneQuiet[Bishop] = value
|
||||
of "SEEPruneQuietRookWeight":
|
||||
self.seeWeights.pruneQuiet[Rook] = value
|
||||
of "SEEPruneQuietQueenWeight":
|
||||
self.seeWeights.pruneQuiet[Queen] = value
|
||||
of "SEEPruneNoisyPawnWeight":
|
||||
self.seeWeights.pruneNoisy[Pawn] = value
|
||||
of "SEEPruneNoisyKnightWeight":
|
||||
self.seeWeights.pruneNoisy[Knight] = value
|
||||
of "SEEPruneNoisyBishopWeight":
|
||||
self.seeWeights.pruneNoisy[Bishop] = value
|
||||
of "SEEPruneNoisyRookWeight":
|
||||
self.seeWeights.pruneNoisy[Rook] = value
|
||||
of "SEEPruneNoisyQueenWeight":
|
||||
self.seeWeights.pruneNoisy[Queen] = value
|
||||
of "MaterialPawnWeight":
|
||||
self.materialWeights[Pawn] = value
|
||||
of "MaterialKnightWeight":
|
||||
@@ -407,10 +504,14 @@ proc getParameter*(self: SearchParameters, name: string): int =
|
||||
# This is ugly, but short of macro shenanigans it's
|
||||
# the best we can do
|
||||
case name:
|
||||
of "RFPBaseMargin":
|
||||
self.rfpMargins.base
|
||||
of "RFPImprovingMargin":
|
||||
self.rfpMargins.improving
|
||||
of "RFPBaseMarginQuiet":
|
||||
self.rfpMargins.base.quiet
|
||||
of "RFPBaseMarginNoisy":
|
||||
self.rfpMargins.base.noisy
|
||||
of "RFPImprovingMarginQuiet":
|
||||
self.rfpMargins.improving.quiet
|
||||
of "RFPImprovingMarginNoisy":
|
||||
self.rfpMargins.improving.noisy
|
||||
of "FPEvalMargin":
|
||||
self.fpEvalMargin
|
||||
of "FPBaseOffset":
|
||||
@@ -423,6 +524,10 @@ proc getParameter*(self: SearchParameters, name: string): int =
|
||||
self.aspWindowInitialSize
|
||||
of "AspWindowMaxSize":
|
||||
self.aspWindowMaxSize
|
||||
of "AspWindowWideningFailLow":
|
||||
self.aspWindowWideningFactor.failLow
|
||||
of "AspWindowWideningFailHigh":
|
||||
self.aspWindowWideningFactor.failHigh
|
||||
of "SEEPruningQuietMargin":
|
||||
self.seePruningMargin.quiet
|
||||
of "SEEPruningCaptureMargin":
|
||||
@@ -431,42 +536,82 @@ proc getParameter*(self: SearchParameters, name: string): int =
|
||||
self.moveBonuses.quiet.good
|
||||
of "BadQuietMalus":
|
||||
self.moveBonuses.quiet.bad
|
||||
of "ContHistBonus":
|
||||
self.moveBonuses.conthist.good
|
||||
of "ContHistMalus":
|
||||
self.moveBonuses.conthist.bad
|
||||
of "ContHistBonusPly1":
|
||||
self.moveBonuses.conthist.ply1.good
|
||||
of "ContHistMalusPly1":
|
||||
self.moveBonuses.conthist.ply1.bad
|
||||
of "ContHistBonusPly2":
|
||||
self.moveBonuses.conthist.ply2.good
|
||||
of "ContHistMalusPly2":
|
||||
self.moveBonuses.conthist.ply2.bad
|
||||
of "ContHistBonusPly4":
|
||||
self.moveBonuses.conthist.ply4.good
|
||||
of "ContHistMalusPly4":
|
||||
self.moveBonuses.conthist.ply4.bad
|
||||
of "GoodCaptureBonus":
|
||||
self.moveBonuses.capture.good
|
||||
of "BadCaptureMalus":
|
||||
self.moveBonuses.capture.bad
|
||||
of "NodeTMBaseOffset":
|
||||
int(self.nodeTmBaseOffset * 1000)
|
||||
of "NodeTMScaleFactor":
|
||||
int(self.nodeTmScaleFactor * 1000)
|
||||
of "NodeTMBaseOffsetQuiet":
|
||||
int(self.nodeTmBaseOffset.quiet * 1000)
|
||||
of "NodeTMBaseOffsetNoisy":
|
||||
int(self.nodeTmBaseOffset.noisy * 1000)
|
||||
of "NodeTMScaleFactorQuiet":
|
||||
int(self.nodeTmScaleFactor.quiet * 1000)
|
||||
of "NodeTMScaleFactorNoisy":
|
||||
int(self.nodeTmScaleFactor.noisy * 1000)
|
||||
of "QSearchFPEvalMargin":
|
||||
self.qsearchFpEvalMargin
|
||||
of "DoubleExtMargin":
|
||||
self.doubleExtMargin
|
||||
of "DoubleExtMarginQuiet":
|
||||
self.doubleExtMargin.quiet
|
||||
of "DoubleExtMarginNoisy":
|
||||
self.doubleExtMargin.noisy
|
||||
of "MatScalingDivisor":
|
||||
self.materialScalingDivisor
|
||||
of "MatScalingOffset":
|
||||
self.materialScalingOffset
|
||||
of "NMPEvalDivisor":
|
||||
self.nmpEvalDivisor
|
||||
of "TripleExtMargin":
|
||||
self.tripleExtMargin
|
||||
of "HistoryDepthEvalThreshold":
|
||||
self.historyDepthEvalThreshold
|
||||
of "SEEPawnWeight":
|
||||
self.seeWeights[Pawn]
|
||||
of "SEEKnightWeight":
|
||||
self.seeWeights[Knight]
|
||||
of "SEEBishopWeight":
|
||||
self.seeWeights[Bishop]
|
||||
of "SEERookWeight":
|
||||
self.seeWeights[Rook]
|
||||
of "SEEQueenWeight":
|
||||
self.seeWeights[Queen]
|
||||
of "NMPEvalDivisorQuiet":
|
||||
self.nmpEvalDivisor.quiet
|
||||
of "NMPEvalDivisorNoisy":
|
||||
self.nmpEvalDivisor.noisy
|
||||
of "TripleExtMarginQuiet":
|
||||
self.tripleExtMargin.quiet
|
||||
of "TripleExtMarginNoisy":
|
||||
self.tripleExtMargin.noisy
|
||||
of "HistoryDepthEvalThresholdQuiet":
|
||||
self.historyDepthEvalThreshold.quiet
|
||||
of "HistoryDepthEvalThresholdNoisy":
|
||||
self.historyDepthEvalThreshold.noisy
|
||||
of "SEEOrdPawnWeight":
|
||||
self.seeWeights.ordering[Pawn]
|
||||
of "SEEOrdKnightWeight":
|
||||
self.seeWeights.ordering[Knight]
|
||||
of "SEEOrdBishopWeight":
|
||||
self.seeWeights.ordering[Bishop]
|
||||
of "SEEOrdRookWeight":
|
||||
self.seeWeights.ordering[Rook]
|
||||
of "SEEOrdQueenWeight":
|
||||
self.seeWeights.ordering[Queen]
|
||||
of "SEEPruneQuietPawnWeight":
|
||||
self.seeWeights.pruneQuiet[Pawn]
|
||||
of "SEEPruneQuietKnightWeight":
|
||||
self.seeWeights.pruneQuiet[Knight]
|
||||
of "SEEPruneQuietBishopWeight":
|
||||
self.seeWeights.pruneQuiet[Bishop]
|
||||
of "SEEPruneQuietRookWeight":
|
||||
self.seeWeights.pruneQuiet[Rook]
|
||||
of "SEEPruneQuietQueenWeight":
|
||||
self.seeWeights.pruneQuiet[Queen]
|
||||
of "SEEPruneNoisyPawnWeight":
|
||||
self.seeWeights.pruneNoisy[Pawn]
|
||||
of "SEEPruneNoisyKnightWeight":
|
||||
self.seeWeights.pruneNoisy[Knight]
|
||||
of "SEEPruneNoisyBishopWeight":
|
||||
self.seeWeights.pruneNoisy[Bishop]
|
||||
of "SEEPruneNoisyRookWeight":
|
||||
self.seeWeights.pruneNoisy[Rook]
|
||||
of "SEEPruneNoisyQueenWeight":
|
||||
self.seeWeights.pruneNoisy[Queen]
|
||||
of "MaterialPawnWeight":
|
||||
self.materialWeights[Pawn]
|
||||
of "MaterialKnightWeight":
|
||||
@@ -561,12 +706,12 @@ proc getSPSAInput*(parameters: SearchParameters): string =
|
||||
|
||||
func staticPieceScore*(parameters: SearchParameters, kind: PieceKind): int {.inline.} =
|
||||
## Returns a static score for the given piece
|
||||
## type to be used inside SEE
|
||||
parameters.seeWeights[kind]
|
||||
## type using SEE ordering weights (used for MVV)
|
||||
parameters.seeWeights.ordering[kind]
|
||||
|
||||
func staticPieceScore*(parameters: SearchParameters, piece: Piece): int {.inline.} =
|
||||
## Returns a static score for the given piece
|
||||
## to be used inside SEE
|
||||
## using SEE ordering weights (used for MVV)
|
||||
parameters.staticPieceScore(piece.kind)
|
||||
|
||||
func materialPieceScore*(parameters: SearchParameters, kind: PieceKind): int {.inline.} =
|
||||
|
||||
Reference in New Issue
Block a user