gameanalysis

package
v0.13.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 26, 2026 License: GPL-3.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const CurrentAnalysisVersion = 2

CurrentAnalysisVersion is incremented when the analysis output format gains new fields. The browse table shows ✓ for versions >= 2.

Variables

This section is empty.

Functions

This section is empty.

Types

type AnalysisConfig

type AnalysisConfig struct {
	// Early/mid game (>7 tiles in bag)
	SimPlaysEarlyMid int
	SimPliesEarlyMid int
	SimStopEarlyMid  int // 90, 95, 98, 99, or 999

	// Early pre-endgame (2-7 tiles in bag)
	SimPlaysEarlyPreEndgame int
	SimPliesEarlyPreEndgame int
	SimStopEarlyPreEndgame  int

	// Pre-endgame (1 tile in bag) - uses PEG solver
	PEGEarlyCutoff bool

	Threads int

	// Optional: analyze only one player (-1 = both, 0 = player 0, 1 = player 1, or player nickname)
	OnlyPlayer       int
	OnlyPlayerByName string

	// UseExposedOppRacks enables using opponent rack information revealed
	// through challenged phonies when analyzing the subsequent turn.
	UseExposedOppRacks bool
}

AnalysisConfig holds configuration for game analysis

func DefaultAnalysisConfig

func DefaultAnalysisConfig() *AnalysisConfig

DefaultAnalysisConfig returns sensible defaults

type AnalysisStore added in v0.12.3

type AnalysisStore struct {
	// contains filtered or unexported fields
}

AnalysisStore is a thin wrapper around the local SQLite analysis database.

func OpenStore added in v0.12.3

func OpenStore(dataPath string) (*AnalysisStore, error)

OpenStore opens (or creates) the analysis database at <dataPath>/analysis.db.

func (*AnalysisStore) Close added in v0.12.3

func (s *AnalysisStore) Close() error

Close closes the database connection.

func (*AnalysisStore) Delete added in v0.12.3

func (s *AnalysisStore) Delete(name string) error

Delete removes an analysis by name. Returns nil if it didn't exist.

func (*AnalysisStore) Exists added in v0.12.3

func (s *AnalysisStore) Exists(name string) bool

Exists reports whether an analysis with the given name is stored.

func (*AnalysisStore) Get added in v0.12.3

func (s *AnalysisStore) Get(name string) (*StoredAnalysis, error)

Get retrieves a single analysis by name. Returns sql.ErrNoRows if not found.

func (*AnalysisStore) List added in v0.12.3

func (s *AnalysisStore) List(limit int) ([]StoredAnalysis, error)

List returns the N most recent analyses, or all if limit <= 0.

func (*AnalysisStore) ListByBatch added in v0.12.3

func (s *AnalysisStore) ListByBatch(batchName string) ([]StoredAnalysis, error)

ListByBatch returns all analyses belonging to a batch, ordered by created_at.

func (*AnalysisStore) Save added in v0.12.3

func (s *AnalysisStore) Save(name, batchName, playerInfo, lexicon string, analysisVersion int, analyzerVersion string, resultJSON []byte) error

Save inserts or replaces an analysis record.

type Analyzer

type Analyzer struct {
	// contains filtered or unexported fields
}

Analyzer analyzes completed games

func New

func New(cfg *config.Config, analysisCfg *AnalysisConfig, version string) *Analyzer

New creates a new Analyzer

func (*Analyzer) AnalyzeGame

func (a *Analyzer) AnalyzeGame(ctx context.Context, history *pb.GameHistory) (*GameAnalysisResult, error)

AnalyzeGame analyzes every move in a game and returns the results

func (*Analyzer) AnalyzeSingleTurn added in v0.12.3

func (a *Analyzer) AnalyzeSingleTurn(ctx context.Context, history *pb.GameHistory, rules *game.GameRules, turnNum int) (*TurnAnalysis, error)

AnalyzeSingleTurn analyzes a single turn in the game This can be used standalone or called in a loop by AnalyzeGame

func (*Analyzer) AnalyzeSingleTurnFromHistory added in v0.12.3

func (a *Analyzer) AnalyzeSingleTurnFromHistory(ctx context.Context, history *pb.GameHistory, turnNum int) (*TurnAnalysis, error)

AnalyzeSingleTurnFromHistory analyzes a single turn, building the game rules from history This is a convenience wrapper around AnalyzeSingleTurn for shell commands

type BatchAnalysisResult

type BatchAnalysisResult struct {
	Games           []*BatchGameResult
	PlayerStats     map[string]*BatchPlayerStats
	TotalGames      int
	SuccessfulGames int
	FailedGames     int
}

BatchAnalysisResult represents the aggregate results of analyzing multiple games

func NewBatchAnalysisResult

func NewBatchAnalysisResult() *BatchAnalysisResult

NewBatchAnalysisResult creates a new BatchAnalysisResult

func (*BatchAnalysisResult) AddGameResult

func (b *BatchAnalysisResult) AddGameResult(gameResult *BatchGameResult)

AddGameResult adds a game result to the batch and updates aggregate statistics

func (*BatchAnalysisResult) CalculateAverages

func (b *BatchAnalysisResult) CalculateAverages()

CalculateAverages calculates average statistics for all players

type BatchGameResult

type BatchGameResult struct {
	GameID      string              // e.g., "woogles:ABC123", "xt:12345", "/path/to/game.gcg"
	GameInfo    string              // e.g., "Player1 vs Player2"
	LoadError   error               // Error during game loading
	AnalysisErr error               // Error during game analysis
	Result      *GameAnalysisResult // Analysis result if successful
}

BatchGameResult represents the results for a single game in a batch analysis

type BatchPlayerStats

type BatchPlayerStats struct {
	PlayerName      string
	GamesPlayed     int
	TotalTurns      int
	TotalOptimal    int
	TotalSmall      int     // Small mistakes count
	TotalMedium     int     // Medium mistakes count
	TotalLarge      int     // Large mistakes count
	TotalMistakeIdx float64 // Sum of mistake indices
	AvgMistakeIndex float64 // Average mistake index
	AvgEstimatedELO float64 // Average estimated ELO

	// Bingo tracking
	TotalAvailableBingos int // Total number of bingo opportunities
	TotalMissedBingos    int // Total number of missed bingos
}

BatchPlayerStats represents aggregate statistics for a player across multiple games

type EndgameMoveResult added in v0.12.3

type EndgameMoveResult struct {
	MoveDescription string
	Score           int
	MoveNumber      int
}

EndgameMoveResult is a single move within an endgame variation.

type EndgameVariationResult added in v0.12.3

type EndgameVariationResult struct {
	Moves       []*EndgameMoveResult
	FinalSpread int16
}

EndgameVariationResult holds a move sequence from endgame analysis.

type GameAnalysisResult

type GameAnalysisResult struct {
	Turns           []*TurnAnalysis
	PlayerSummaries [2]*PlayerSummary
	AnalysisVersion int
	AnalyzerVersion string
}

GameAnalysisResult contains the complete analysis results for a game.

func GameAnalysisResultFromProto added in v0.12.3

func GameAnalysisResultFromProto(p *pb.GameAnalysisResult) *GameAnalysisResult

GameAnalysisResultFromProto constructs a GameAnalysisResult from a proto message. The returned struct has PlayerSummaries fully populated, and turns populated with display-string fields (move descriptions and scores from proto). PlayedMove and OptimalMove fields are nil since they require live game state.

func (*GameAnalysisResult) ToProto

ToProto converts GameAnalysisResult to protobuf message

type GamePhase

type GamePhase int

GamePhase represents the phase of the game based on tiles remaining in bag.

const (
	// PhaseEarlyMid represents early/mid game (>7 tiles in bag)
	PhaseEarlyMid GamePhase = iota
	// PhaseEarlyPreEndgame represents early pre-endgame (2-7 tiles in bag)
	PhaseEarlyPreEndgame
	// PhasePreEndgame represents pre-endgame (1 tile in bag, uses PEG solver)
	PhasePreEndgame
	// PhaseEndgame represents endgame (0 tiles in bag, uses negamax)
	PhaseEndgame
)

func (GamePhase) String

func (p GamePhase) String() string

String returns a string representation of the game phase.

type PEGOutcomeResult added in v0.12.3

type PEGOutcomeResult struct {
	Tiles   string // human-readable, e.g. "A", "EI"
	Outcome string // "win", "draw", "loss", "unknown"
	Count   int
}

PEGOutcomeResult holds a single tile-draw outcome from PEG analysis.

type PEGPlayResult added in v0.12.3

type PEGPlayResult struct {
	MoveDescription string
	Score           int
	Leave           string
	IsBingo         bool
	WinProb         float64
	Outcomes        []*PEGOutcomeResult
	HasSpread       bool
	AvgSpread       float64
	IsPlayedMove    bool
	IsIgnored       bool
}

PEGPlayResult holds per-play statistics from the pre-endgame solver.

type PlayerSummary

type PlayerSummary struct {
	PlayerName     string
	TurnsPlayed    int
	OptimalMoves   int
	AvgWinProbLoss float64

	// Mistake breakdown
	SmallMistakes  int
	MediumMistakes int
	LargeMistakes  int

	MistakeIndex float64 // Sum of mistake points (0.2 for small, 0.5 for medium, 1.0 for large)
	EstimatedELO float64 // Estimated ELO based on mistake index

	// Bingo tracking
	AvailableBingos int // Number of turns where optimal move was a bingo
	MissedBingos    int // Number of times player didn't play a bingo when optimal was a bingo
}

PlayerSummary contains aggregate statistics for a player across the game.

func (*PlayerSummary) ToProto

func (p *PlayerSummary) ToProto() *pb.PlayerSummary

ToProto converts PlayerSummary to protobuf message

type PlyStatResult added in v0.12.3

type PlyStatResult struct {
	Ply        int
	ScoreMean  float64
	ScoreStdev float64
	BingoPct   float64
}

PlyStatResult holds per-ply score and bingo statistics for a simmed play.

type SimPlayResult added in v0.12.3

type SimPlayResult struct {
	MoveDescription string
	Score           int
	Leave           string
	IsBingo         bool
	WinProb         float64
	WinProbStdErr   float64
	Equity          float64
	EquityStdErr    float64
	Iterations      int
	PlyStats        []*PlyStatResult
	IsPlayedMove    bool
	IsIgnored       bool
}

SimPlayResult holds per-play statistics from Monte Carlo simulation.

type StoredAnalysis added in v0.12.3

type StoredAnalysis struct {
	ID              int
	Name            string
	BatchName       string
	PlayerInfo      string
	Lexicon         string
	AnalysisVersion int
	AnalyzerVersion string
	ResultJSON      []byte
	CreatedAt       time.Time
	UpdatedAt       time.Time
}

StoredAnalysis is a row from the analyses table.

type TurnAnalysis

type TurnAnalysis struct {
	TurnNumber  int
	PlayerIndex int
	PlayerName  string
	Rack        string
	Phase       GamePhase
	TilesInBag  int // Number of tiles in bag at this turn

	// The move that was actually played
	PlayedMove *move.Move
	// The optimal move according to analysis
	OptimalMove *move.Move
	// Display strings used when loaded from storage (PlayedMove/OptimalMove are nil)
	PlayedMoveStr  string
	OptimalMoveStr string

	// For sim/PEG phases - win probability
	PlayedWinProb  float64
	OptimalWinProb float64
	WinProbLoss    float64 // OptimalWinProb - PlayedWinProb

	// For endgame phase - spread difference
	SpreadLoss         int16 // How much worse the played move is compared to optimal
	OptimalFinalSpread int16 // The final spread with the optimal move (endgame only)
	CurrentSpread      int   // The spread before this move (endgame only, for blown endgame detection)

	// Whether the played move was optimal
	WasOptimal bool

	// Mistake categorization
	MistakeCategory string // "Small", "Medium", "Large", or empty if optimal
	BlownEndgame    bool   // True if the mistake changed a win to a loss/tie in endgame

	// Bingo tracking
	OptimalIsBingo bool // True if the optimal move is a bingo (7 tiles)
	PlayedIsBingo  bool // True if the played move is a bingo (7 tiles)
	MissedBingo    bool // True if optimal was a bingo but player didn't play a bingo

	// Phony handling
	IsPhony         bool // The played move was a phony
	PhonyChallenged bool // A phony that was challenged off
	MissedChallenge bool // Player failed to challenge opponent's phony

	// KnownOppRack contains the known opponent tiles (if any) used in analysis.
	// This is populated when the opponent's phony was challenged off, exposing their rack.
	KnownOppRack string

	// Enriched data (v2+)
	TopSimPlays        []*SimPlayResult
	TopPEGPlays        []*PEGPlayResult
	PrincipalVariation *EndgameVariationResult
	OtherVariations    []*EndgameVariationResult
}

TurnAnalysis contains the analysis results for a single turn.

func (*TurnAnalysis) ToProto

func (t *TurnAnalysis) ToProto() *pb.TurnAnalysis

ToProto converts TurnAnalysis to protobuf message

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL