RootSearchStats

dicechess.engine.search.RootSearchStats
final case class RootSearchStats(legalTurns: Int, candidatesSelected: Int, candidatesCompleted: Int, candidatesAbandoned: Int = ..., cutoffs: Int = ..., rollsSaved: Int = ..., probeCutoffs: Int = ..., ttProbes: Int = ..., ttHits: Int = ..., ttCutoffs: Int = ..., candidatesCollapsed: Int = ..., collapseRejected: Boolean = ...)

One move's root telemetry from ExpectimaxSearch: how wide the decision node really was.

candidatesCompleted < candidatesSelected means the wall-clock deadline truncated the anytime loop — the move was chosen among fewer candidates than ExpectimaxConfig.candidateLimit allowed. Persistently tiny completion counts on production hardware mean the effective search degenerates toward "play the pre-ranker's first pick", which no amount of candidate-limit tuning can fix — that evidence is exactly what this type exists to surface.

An immediate king-capture win reports 0/0 selected/completed: no candidate was pre-ranked or expanded, so counting it as a completed candidate would overstate the searched width. A forced pass (no legal turn for the roll) reports all-zero — legalTurns == 0 is what tells the two apart, keeping the sink's contract at exactly one record per findBestMove call.

Value parameters

candidatesAbandoned

candidates whose chance node was cut mid-expansion by the deadline (at most one: the search stops afterwards). Their partial expectation is discarded rather than ranked, so this counts work paid for and thrown away — a persistent non-zero value means the per-move budget is too small for even one candidate at this width.

candidatesCompleted

how many selected candidates were fully expanded through the chance node. Ranking needs comparable values, and a full expansion is one way to get one; a transposition-table hit (RootSearchStats.ttHits) and a collapsed candidate (RootSearchStats.candidatesCollapsed) are the other two, and are counted separately because they did no expansion work

candidatesSelected

how many turns survived pre-ranking (at most the candidate limit)

legalTurns

size of the full legal-turn list before pre-ranking

Attributes

Source
ExpectimaxSearch.scala
Graph
Supertypes
trait Serializable
trait Product
trait Equals
class Object
trait Matchable
class Any
Show all

Members list

Value members

Concrete methods

def deadlineTruncated: Boolean

Whether the deadline cut the loop short of the selected candidate set. A rejected collapse batch leaves the same counters at zero without the clock having run out, so it is excluded rather than reported as truncation.

Whether the deadline cut the loop short of the selected candidate set. A rejected collapse batch leaves the same counters at zero without the clock having run out, so it is excluded rather than reported as truncation.

Attributes

Source
ExpectimaxSearch.scala
def fellBackToPreRank: Boolean

Nothing was scored, so the turn came from the pre-ranker alone — the search contributed nothing beyond candidate selection. True for either reason it can happen: the deadline elapsed first, or the collapse model's batch was refused. RootSearchStats.collapseRejected and RootSearchStats.candidatesAbandoned tell them apart.

Nothing was scored, so the turn came from the pre-ranker alone — the search contributed nothing beyond candidate selection. True for either reason it can happen: the deadline elapsed first, or the collapse model's batch was refused. RootSearchStats.collapseRejected and RootSearchStats.candidatesAbandoned tell them apart.

Attributes

Source
ExpectimaxSearch.scala

Inherited methods

def productElementNames: Iterator[String]

An iterator over the names of all the elements of this product.

An iterator over the names of all the elements of this product.

Attributes

Inherited from:
Product
def productIterator: Iterator[Any]

An iterator over all the elements of this product.

An iterator over all the elements of this product.

Attributes

Returns

in the default implementation, an Iterator[Any]

Inherited from:
Product