Documentation
¶
Overview ¶
Package ogxmparser reads OGXM, the OpenGammon eXtensible Match format of HedgeHog / OpenGammon: a backgammon match stored as the moves that were played, plus engine analyses of those moves, optionally signed with Ed25519.
The format is specified in docs/OGXM_FORMAT_SPEC.md of HedgeHog's public repository (gitlab.com/eranlambooij/hedgehog-public), version 2.2, licensed CC BY 4.0. This package implements the reader side of that specification:
- Parse walks the container (2), every record (3.2) and section (4-8), enforces the hard errors a reader must, and verifies what section 11 lists: file size, CSUM, score_final, a Combined file's match_digest.
- File.Replay reconstructs every position (5.4) and expresses each as the OGID the reference implementation derives for it (package ogid).
- File.VerifySignatures reports each SIGN and MSIG as valid, invalid or unverifiable (8.1, 8.6). A failed signature is never a load error, and a key carried by the file identifies its signer, it does not make it trustworthy.
What it does not do: write files; read OGXM v1, or streams (2.6) other than one file at a time; check M4 (that a recorded play is legal for its dice; Board.Apply checks each step, M3); decode CLCK, VIDO and drawings, which are kept raw or counted.
Index ¶
- Constants
- Variables
- func DiceAction(d1, d2 int) int
- func IsOGXM(data []byte) bool
- type Alternative
- type Analysis
- type Annotation
- type Board
- type CheckerDecision
- type Checksum
- type CubeDecision
- type Currency
- type Decision
- type DecisionKind
- type File
- type FormatError
- type Game
- type GameReplay
- type KeyLookup
- type Level
- type Match
- type Player
- type Ply
- type PlyState
- type Probabilities
- type ResignDecision
- type RollDecision
- type Rollout
- type Rules
- type Seat
- type Shape
- type Signature
- type SignatureReport
- type SignatureStatus
- type Step
- type Variant
- type Verdict
Constants ¶
const ( ReaderMajor = 2 ReaderMinor = 2 )
ReaderMajor and ReaderMinor are the format version this reader implements.
const ( MaxFileSize = 64 << 20 MaxSectionSize = 16 << 20 MaxSections = 4096 MaxGames = 1000 MaxPliesPerGame = 1500 MaxTotalPlies = 100000 MaxAltsPerDecision = 1024 MaxAnalyses = 64 MaxString = 4096 MaxAnnotations = 4096 MaxDrawings = 256 MaxDecisions = 300000 MaxCoverage = 100000 MaxMatchSignatures = 16 )
Limits of spec section 10 that this reader enforces.
const ( ActionDouble = 21 ActionTake = 22 ActionDrop = 23 ActionGameOver = 24 ActionMatchOver = 25 ActionFinal = 26 ActionResignGame = 27 ActionResignMatch = 28 ActionForfeit = 29 ActionNull = 30 ActionSetPosition = 31 ActionBeaver = 32 ActionRaccoon = 33 ActionSettle = 34 ActionReserved = 35 ActionCubeSet = 36 ActionPass = 37 )
Action ids of 9.14 beyond the dice rolls 0-20.
const EquityScale = 1e6
EquityScale is the fixed-point unit of the Equity and Equity loss kinds (3.3).
const ProbabilityScale = 1e4
ProbabilityScale is the fixed-point unit of the Probability kind (3.3).
Variables ¶
var ErrNotOGXM = errors.New("ogxm: not an OGXM file")
ErrNotOGXM is returned when the data does not start with the OGXM magic.
var ErrVersion = errors.New("ogxm: unsupported version")
ErrVersion is returned for a file this reader is too old to read, or for a v1 file, which this reader does not convert.
Functions ¶
func DiceAction ¶
DiceAction returns the action id of a roll (9.14).
Types ¶
type Alternative ¶
type Alternative struct {
Steps []Step
Equity float64
Probs *Probabilities
Level *Level
IsPlayed bool
RolloutSE *float64
CubelessEquity *float64
}
Alternative is one candidate play of a checker decision (7.2).
type Analysis ¶
type Analysis struct {
ID [16]byte
MatchDigest *[32]byte
Producer *int // 9.9
Level *Level
Complete bool
Coverage []int // nil = every ply
ModelID string
ModelName string
ModelDigest *[32]byte
EngineBuild string
Currency Currency
CubeEfficiency *float64
METID string
Tables string
StartedAt *time.Time
CompletedAt *time.Time
DurationMS *int
Sources [][16]byte
Decisions []Decision
Signature *Signature
// contains filtered or unexported fields
}
Analysis is one analysis block: ANAL, its DECS and its optional SIGN (6-8.1).
type Annotation ¶
type Annotation struct {
Scope int // 9.20
Ref int
Value string
Key *string
Kind *DecisionKind
AltIndex *int
Lang string
Author string
At *time.Time
Drawings int
Analysis *[16]byte
}
Annotation is one ANNO record (8.4). Drawings are counted, not decoded.
type Board ¶
type Board [26]int8
Board is 26 signed counts indexed by absolute point (M1): positive is White, negative Black; 0 is White's bar and 25 Black's.
func (Board) Apply ¶
Apply plays the steps of seat in stored order (M3). It checks that each step moves a checker the seat holds, enters from the bar first, lands on a point the opponent does not hold, and bears off only with every checker home. It does not check M4 (that the play is a legal one for the dice).
type CheckerDecision ¶
type CheckerDecision struct {
Alternatives []Alternative
AlternativesTotal *int
BestEquity *float64 // stored only without alternatives
EquityLoss *float64 // stored only when no alternative is played
Level *Level
PositionTags *uint64
ProducerRef *int
}
CheckerDecision is a CHECKER record (7.1).
type Checksum ¶
type Checksum struct {
Algorithm int // 9.15: 0 CRC32, 3 SHA-256
Digest []byte
Verified bool // false only when the algorithm is unknown to this reader
}
Checksum is the CSUM record (8.5).
type CubeDecision ¶
type CubeDecision struct {
Verdict Verdict
NoDoubleEquity *float64
DoubleTakeEquity *float64
DoublePassEquity *float64
Probs *Probabilities
EquityLoss *float64
TakePoint *float64
WindowSearched bool
Level *Level
IsOptional bool
IsFreeCube bool
CubefulTakeValue *float64
Currency *Currency // nil = the block's
ProducerRef *int
}
CubeDecision is a CUBE record (7.4).
type Decision ¶
type Decision struct {
PlyRef int
Kind DecisionKind
Checker *CheckerDecision
Cube *CubeDecision
Resign *ResignDecision
Roll *RollDecision
}
Decision is one DECS record (7). Exactly one of the kind pointers is set for a known kind; an unknown kind leaves all nil.
type DecisionKind ¶
type DecisionKind int
DecisionKind is the decision kind enum (9.12).
const ( KindChecker DecisionKind = 0 KindCube DecisionKind = 1 KindResign DecisionKind = 2 KindRoll DecisionKind = 3 )
type File ¶
type File struct {
VersionMajor, VersionMinor uint16
MinReaderMajor, MinReaderMinor uint16
Match *Match
Games []Game
Analyses []Analysis
Annotations []Annotation
MatchSignatures []Signature
Checksum *Checksum
// Clock and Video are the raw CLCK and VIDO payloads; this reader does not
// interpret them (they are ancillary), but an MSIG may cover the clock.
Clock []byte
Video []byte
// contains filtered or unexported fields
}
File is a parsed OGXM v2 file.
func Parse ¶
Parse parses one OGXM v2 file. It verifies everything section 11 lists as verified (file size, CSUM, score_final, a Combined file's match_digest, record walks) and the replay rules this reader implements (Replay); it does not verify signatures, which VerifySignatures reports on.
func ParseReader ¶
ParseReader reads r to the end and parses it as one OGXM file.
func (*File) MatchDigest ¶
MatchDigest computes match_digest (6.1) over the stored MTCH and GAME payloads, each preceded by its length.
func (*File) Replay ¶
func (f *File) Replay() []GameReplay
Replay reconstructs every game's positions (5.4).
func (*File) VerifySignatures ¶
func (f *File) VerifySignatures(keys KeyLookup) []SignatureReport
VerifySignatures checks every SIGN and MSIG (8.1, 8.6). A failed signature is reported, never a load error. keys may be nil.
type FormatError ¶
type FormatError struct {
Section string // four-character section type, empty for the container
Offset int // byte offset within the section payload (or the file)
Msg string
}
FormatError is a hard error (section 0): the file is rejected.
func (*FormatError) Error ¶
func (e *FormatError) Error() string
type Game ¶
type Game struct {
Winner *Seat
PointsWon *int
IsLastGame bool
InitialBoard *Board // nil = the variant's opening position (5.2)
InitialCubeValue int // 1 when absent
InitialCubeOwner Seat // Centred when absent
AutoDoubles int
Termination *int // 9.7
Plies []Ply
}
Game is one GAME section (5).
type GameReplay ¶
type GameReplay struct {
Plies []PlyState // one per ply up to FailedAt
// FailedAt is the index of the first ply that does not replay, or -1
// (M9). Plies from it on have no position.
FailedAt int
Err error
Crawford bool
// ScoreBefore is the score at the game's start, White then Black (M8).
ScoreBefore [2]int
}
GameReplay is one game's replay.
type KeyLookup ¶
KeyLookup returns the public key for a key id when the file carries none, or nil. Which keys to trust is the caller's decision, never the file's: a key embedded in the file only identifies the signer.
type Match ¶
type Match struct {
Length int // 0 = money session
Variant Variant
WhiteName string
BlackName string
Rules Rules
CubeLimit int // 0 = no limit
ScoreStart [2]int
ScoreFinal *[2]int // White, Black
Result int // 9.3; 0 = absent (unfinished, or decided by the score)
Source *int // 9.4
StartedAt *time.Time
CompletedAt *time.Time
PlayerSeat *Seat
CrawfordBeforeStart bool
Event string
EventYear int
DatePrecision *int // 9.27
Stage string
Round int
Table string
City string
Country string
EventURL string
Site string
MatchRef string
WhiteProfile *Player
BlackProfile *Player
Rated bool
}
Match is the MTCH record (4).
type Player ¶
type Player struct {
UserID string
Rating *float64 // hundredths decoded: 1523.47
RatingSystem string
Country string
Kind *int // 9.28
}
Player is the nested player record (4.1).
type Ply ¶
type Ply struct {
Ref int // ply_ref (I2)
Action int // the real action id, escape resolved
Seat Seat
Steps []Step
ExtraDice *[2]int
ResignValue *int
CubeValue *int
Illegal bool
SettleValue *float64
Board *Board
CubeOwner *Seat
}
Ply is one ply record (5.1), with its extras decoded.
func (Ply) IsDiceAction ¶
IsDiceAction reports whether the ply is a dice roll (actions 0-20).
type PlyState ¶
type PlyState struct {
Before, After ogid.OGID
// UnplayedRoll marks a dice action with no step followed by a
// resignation or forfeit (5.4.5): not a checker decision.
UnplayedRoll bool
}
PlyState is one ply's reconstructed position, before and after it, as the OGIDs the reference implementation derives (ogid_before, ogid_after).
type Probabilities ¶
type Probabilities struct {
Win, GammonWin, BackgammonWin, GammonLoss, BackgammonLoss float64
}
Probabilities are cumulative, from the decision owner's view (3.3).
type ResignDecision ¶
type ResignDecision struct {
CorrectValue *int
ResignError *float64
TakeResignError *float64
Probs *Probabilities
EquityLoss *float64
Level *Level
ProducerRef *int
}
ResignDecision is a RESIGN record (7.5).
type RollDecision ¶
RollDecision is a ROLL record (7.6).
type Rollout ¶
type Rollout struct {
Trials *int
TruncationDepth *int
MovePly *int
VarianceReduction *int
Seed *uint64
BudgetMS *int
MatchPolicy *int
}
Rollout is the nested rollout record (6.2).
type Seat ¶
type Seat int
Seat is the Seat enum (9.5).
type Signature ¶
type Signature struct {
Algorithm int // 9.16: 1 = Ed25519
Signature []byte
KeyID string
PublicKey []byte
SignedAt *time.Time
Covers uint64 // MSIG only, 9.26
}
Signature is a SIGN (8.1) or MSIG (8.6) record.
type SignatureReport ¶
type SignatureReport struct {
// Analysis is the index of the analysis block a SIGN belongs to, or -1
// for an MSIG.
Analysis int
KeyID string
Status SignatureStatus
}
SignatureReport is the verdict on one SIGN or MSIG.
type SignatureStatus ¶
type SignatureStatus int
SignatureStatus is a verifier's verdict on one signature (8.1).
const ( // Unverifiable: unknown algorithm or covered section, or no public key. Unverifiable SignatureStatus = iota // Valid: the signature matches the payload under the key. Valid // Invalid: the signature does not match the payload. Invalid )
func (SignatureStatus) String ¶
func (s SignatureStatus) String() string