Documentation
¶
Overview ¶
Package trf implements reading and writing of TRF16 (FIDE Tournament Report File) documents. It provides a faithful in-memory representation of TRF data and bidirectional conversion to/from chesspairing.TournamentState.
Index ¶
- func Write(w io.Writer, doc *Document) error
- type AbsenceRecord
- type AccelerationRecord
- type Color
- type DetailedTeamResult
- type DetailedTeamRound
- type Document
- type ForbiddenPair
- type ForbiddenPairRecord
- type NRSRecord
- type NewTeamLine
- type OldAbsentForfeit
- type ParseError
- type PlayerLine
- type RawLine
- type ResultCode
- type RoundResult
- type Severity
- type SimpleTeamResult
- type SimpleTeamRound
- type TeamLine
- type TeamRoundEntry
- type TeamRoundScoreEntry
- type ValidationIssue
- type ValidationProfile
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AbsenceRecord ¶
type AbsenceRecord struct {
Type string `json:"type"` // "F" or "H"
Round int `json:"round"` // Round number
Players []int `json:"players"` // Start numbers of absent players/teams
}
AbsenceRecord represents a 240 line (absent participants). Format: 240 T RRR TOI1 TOI2 ... T = "F" (full forfeit) or "H" (half-point bye) RRR = round number TOI = team-or-individual start numbers
type AccelerationRecord ¶
type AccelerationRecord struct {
MatchPoints float64 `json:"matchPoints"` // Match points to add (for team)
GamePoints float64 `json:"gamePoints"` // Game points to add
FirstRound int `json:"firstRound"` // First round of acceleration
LastRound int `json:"lastRound"` // Last round of acceleration
FirstPlayer int `json:"firstPlayer"` // First player/team number
LastPlayer int `json:"lastPlayer"` // Last player/team number
Raw string `json:"raw"` // Raw line data for round-trip
}
AccelerationRecord represents a 250 line (Baku acceleration data). Format: 250 MMMM GGGG RRF RRL PPPF PPPL MMMM = match points to add, GGGG = game points to add RRF/RRL = first/last round, PPPF/PPPL = first/last player
type Color ¶
type Color int
Color in a TRF round result.
func (Color) MarshalJSON ¶
MarshalJSON encodes the Color as its TRF character string ("w", "b", or "-").
func (*Color) UnmarshalJSON ¶
UnmarshalJSON decodes a Color from its TRF character string.
type DetailedTeamResult ¶
type DetailedTeamResult struct {
TeamNumber int `json:"teamNumber"`
TeamName string `json:"teamName"`
MatchPoints float64 `json:"matchPoints"`
GamePoints float64 `json:"gamePoints"`
Rounds []DetailedTeamRound `json:"rounds"`
Raw string `json:"raw"` // Raw line data for round-trip
}
DetailedTeamResult represents an 801 line (detailed team match results per round). Format: 801 TT NNNNN MMMM GGGG T01 C RRRR BBBB ...
type DetailedTeamRound ¶
type DetailedTeamRound struct {
Opponent int `json:"opponent"` // Opponent team number (0 = no match)
Color string `json:"color"` // "w" or "b"
Results string `json:"results"` // Individual board results (e.g. "=0=1")
BoardOrder string `json:"boardOrder"` // Board order (e.g. "1234")
ByeType string `json:"byeType,omitempty"` // "FFFF", "HHHH", "ZZZZ", "UUUU" for byes, empty for normal
}
DetailedTeamRound is a single round entry in an 801 line.
type Document ¶
type Document struct {
// Tournament info (header lines 012-132)
Name string `json:"name,omitempty"` // 012
City string `json:"city,omitempty"` // 022
Federation string `json:"federation,omitempty"` // 032
StartDate string `json:"startDate,omitempty"` // 042
EndDate string `json:"endDate,omitempty"` // 052
NumPlayers int `json:"numPlayers,omitempty"` // 062
NumRated int `json:"numRated,omitempty"` // 072
NumTeams int `json:"numTeams,omitempty"` // 082
TournamentType string `json:"tournamentType,omitempty"` // 092
ChiefArbiter string `json:"chiefArbiter,omitempty"` // 102
DeputyArbiter string `json:"deputyArbiter,omitempty"` // 112 (first or only)
DeputyArbiters []string `json:"deputyArbiters,omitempty"` // 112 (all, for TRF-2026 multiple deputy arbiters)
TimeControl string `json:"timeControl,omitempty"` // 122
RoundDates []string `json:"roundDates,omitempty"` // 132
// TRF-2026 header fields (new record types)
TotalRounds26 int `json:"totalRounds26,omitempty"` // 142 (replaces XXR)
InitialColor26 string `json:"initialColor26,omitempty"` // 152 (replaces XXC; "B" or "W")
ScoringSystem string `json:"scoringSystem,omitempty"` // 162 (e.g. " W 1.0 D 0.5 L 0.0")
StartingRankMethod string `json:"startingRankMethod,omitempty"` // 172 (e.g. "IND FIDE")
CodedTournamentType string `json:"codedTournamentType,omitempty"` // 192 (e.g. "FIDE_TEAM_BAKU")
TieBreakDef string `json:"tieBreakDef,omitempty"` // 202 (e.g. "EDET/P,EMGSB/C1/P,BH:MP/C1/P,MPvGP")
EncodedTimeControl string `json:"encodedTimeControl,omitempty"` // 222 (e.g. "40/6000+30:20/3000+30:1500+30")
TeamInitialColor string `json:"teamInitialColor,omitempty"` // 352 (e.g. "WBWB")
TeamScoringSystem string `json:"teamScoringSystem,omitempty"` // 362 (e.g. "TW 2 TD 1 TL 0")
// TRF-2026 data records
Absences []AbsenceRecord `json:"absences,omitempty"` // 240 lines
Accelerations26 []AccelerationRecord `json:"accelerations26,omitempty"` // 250 lines (replaces XXS)
ForbiddenPairs26 []ForbiddenPairRecord `json:"forbiddenPairs26,omitempty"` // 260 lines (replaces XXP)
NewTeams []NewTeamLine `json:"newTeams,omitempty"` // 310 lines
TeamRoundData []TeamRoundEntry `json:"teamRoundData,omitempty"` // 300 lines
TeamRoundScores []TeamRoundScoreEntry `json:"teamRoundScores,omitempty"` // 320 lines
OldAbsentForfeits []OldAbsentForfeit `json:"oldAbsentForfeits,omitempty"` // 330 lines
DetailedTeamResults []DetailedTeamResult `json:"detailedTeamResults,omitempty"` // 801 lines
SimpleTeamResults []SimpleTeamResult `json:"simpleTeamResults,omitempty"` // 802 lines
NRSRecords []NRSRecord `json:"nrsRecords,omitempty"` // NRS lines (3-letter federation code)
Comments []string `json:"comments,omitempty"` // ### lines
// Extended data lines (TRF16 / legacy)
TotalRounds int `json:"totalRounds,omitempty"` // XXR
InitialColor string `json:"initialColor,omitempty"` // XXC (e.g. "white1")
Acceleration []string `json:"acceleration,omitempty"` // XXS lines (one per line)
ForbiddenPairs []ForbiddenPair `json:"forbiddenPairs,omitempty"` // XXP lines
// System-specific extended data lines
Cycles int `json:"cycles,omitempty"` // XXY (Round-Robin: 1=single, 2=double)
ColorBalance *bool `json:"colorBalance,omitempty"` // XXB (Round-Robin: true/false)
MaxiTournament *bool `json:"maxiTournament,omitempty"` // XXM (Lim: true/false)
ColorPreferenceType string `json:"colorPreferenceType,omitempty"` // XXT (Team: "A", "B", "none")
PrimaryScore string `json:"primaryScore,omitempty"` // XXG (Team: "match", "game")
AllowRepeatPairings *bool `json:"allowRepeatPairings,omitempty"` // XXA (Keizer: true/false)
MinRoundsBetweenRepeats int `json:"minRoundsBetweenRepeats,omitempty"` // XXK (Keizer: integer)
// Player data
Players []PlayerLine `json:"players,omitempty"` // 001 lines, sorted by StartNumber
// Team data (TRF16 legacy)
Teams []TeamLine `json:"teams,omitempty"` // 013 lines
// Unknown/custom lines preserved for round-trip fidelity
Other []RawLine `json:"other,omitempty"`
}
Document represents a complete TRF file (supports both TRF16 and TRF-2026).
func FromTournamentState ¶
func FromTournamentState(state *chesspairing.TournamentState) (*Document, map[string]int)
FromTournamentState creates a Document from a TournamentState. Players are assigned start numbers sorted by rating descending (ties broken by display name ascending, then by ID ascending for determinism). Returns the Document and a mapping from player ID to assigned start number.
func (*Document) EffectiveInitialColor ¶
EffectiveInitialColor returns the initial color from TRF-2026 (152) if set, falling back to TRF16 (XXC). Returns "" if neither is set.
func (*Document) EffectiveTotalRounds ¶
EffectiveTotalRounds returns the total rounds from TRF-2026 (142) if set, falling back to TRF16 (XXR). Returns 0 if neither is set.
func (*Document) ToTournamentState ¶
func (doc *Document) ToTournamentState() (*chesspairing.TournamentState, error)
ToTournamentState converts a Document to a TournamentState for engine use. Player IDs are set to the string representation of start numbers (e.g. "1", "2"). RoundData is reconstructed by cross-referencing per-player round results.
func (*Document) Validate ¶
func (doc *Document) Validate(profile ValidationProfile) []ValidationIssue
Validate checks the Document for completeness according to the given profile. Each profile is a superset of the previous one:
- ValidateGeneral: structural integrity (players exist, unique start numbers)
- ValidatePairingEngine: adds XXR, XXC, 092
- ValidateFIDE: adds tournament name, dates, time control, player data quality
type ForbiddenPair ¶
type ForbiddenPair struct {
Player1 int `json:"player1"` // Start number
Player2 int `json:"player2"` // Start number
}
ForbiddenPair represents an XXP forbidden pair entry.
type ForbiddenPairRecord ¶
type ForbiddenPairRecord struct {
FirstRound int `json:"firstRound"` // First round of restriction
LastRound int `json:"lastRound"` // Last round of restriction
Players []int `json:"players"` // Start numbers that are mutually forbidden
Raw string `json:"raw"` // Raw line data for round-trip
}
ForbiddenPairRecord represents a 260 line (forbidden/prohibited pairings). Format: 260 RR1 RRL TOI1 TOI2 ... RR1/RRL = first/last round of restriction TOI = player/team numbers that cannot be paired against each other
type NRSRecord ¶
type NRSRecord struct {
Federation string `json:"federation"` // 3-letter federation code (e.g. "IND")
StartNumber int `json:"startNumber"` // Player start number
Title string `json:"title,omitempty"` // Title
Name string `json:"name,omitempty"` // Player name
NationalRating int `json:"nationalRating,omitempty"` // National rating
SubFederation string `json:"subFederation,omitempty"` // Sub-federation code
NationalID string `json:"nationalID,omitempty"` // National ID
BirthDate string `json:"birthDate,omitempty"` // Birth date
Raw string `json:"raw"` // Raw line data for round-trip
}
NRSRecord represents a national rating system record line. Lines start with a 3-letter federation code instead of a numeric record code. Format is similar to 001 but may include national rating and sub-federation data.
type NewTeamLine ¶
type NewTeamLine struct {
TeamNumber int `json:"teamNumber"` // 3-char team number
TeamName string `json:"teamName"` // 32-char team name
Federation string `json:"federation,omitempty"` // 5-char federation
AvgRating float64 `json:"avgRating,omitempty"` // 6-char average rating
MatchPoints float64 `json:"matchPoints,omitempty"` // 6-char match points
GamePoints float64 `json:"gamePoints,omitempty"` // 6-char game points
Rank int `json:"rank,omitempty"` // 3-char rank
Members []int `json:"members"` // Member start numbers (4 chars each)
}
NewTeamLine represents a 310 line (TRF-2026 team record). Format: 310 SSS NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN FFFFF EEEEEE MMMMMM GGGGGG RRR PPP1 PPP2...
type OldAbsentForfeit ¶
type OldAbsentForfeit struct {
ResultType string `json:"resultType"` // "+-", "-+", "--"
Round int `json:"round"` // Round number
WhiteTeam int `json:"whiteTeam"` // White team number
BlackTeam int `json:"blackTeam"` // Black team number
}
OldAbsentForfeit represents a 330 line (legacy absent/forfeit records). Format: 330 TT RRR WWW BBB TT = result code ("+-", "-+", "--") RRR = round, WWW = white team, BBB = black team
type ParseError ¶
type ParseError struct {
Line int `json:"line"` // 1-based line number in the input
Code string `json:"code"` // Line code (e.g., "001", "012", "XXR")
Message string `json:"message"` // Human-readable description
}
ParseError describes a TRF parsing error with line context.
func (*ParseError) Error ¶
func (e *ParseError) Error() string
type PlayerLine ¶
type PlayerLine struct {
StartNumber int `json:"startNumber"`
Sex string `json:"sex,omitempty"`
Title string `json:"title,omitempty"`
Name string `json:"name,omitempty"`
Rating int `json:"rating,omitempty"`
Federation string `json:"federation,omitempty"`
FideID string `json:"fideID,omitempty"`
BirthDate string `json:"birthDate,omitempty"`
Points float64 `json:"points"`
Rank int `json:"rank"`
Rounds []RoundResult `json:"rounds,omitempty"`
}
PlayerLine represents a single 001 player line.
type RawLine ¶
type RawLine struct {
Code string `json:"code"` // The 3-character line code
Data string `json:"data"` // Everything after the code and space
}
RawLine preserves an unrecognized line for round-trip fidelity.
type ResultCode ¶
type ResultCode int
ResultCode is a TRF result character.
const ( ResultWin ResultCode = iota // "1" - win (played) ResultLoss // "0" - loss (played) ResultDraw // "=" - draw ResultForfeitWin // "+" - win by forfeit ResultForfeitLoss // "-" - loss by forfeit ResultHalfBye // "H" - half-point bye ResultFullBye // "F" - full-point bye (PAB) ResultUnpaired // "U" - unpaired (absent, 0 pts) ResultZeroBye // "Z" - zero-point bye ResultNotPlayed // "*" - not yet played ResultWinByDefault // "W" - win, opponent absent ResultDrawByDefault // "D" - draw by default ResultLossByDefault // "L" - loss by default )
func (ResultCode) Char ¶
func (rc ResultCode) Char() byte
Char returns the TRF character for the result code.
func (ResultCode) IsValid ¶
func (rc ResultCode) IsValid() bool
IsValid returns true if the result code is a recognized value.
func (ResultCode) MarshalJSON ¶
func (rc ResultCode) MarshalJSON() ([]byte, error)
MarshalJSON encodes the ResultCode as its TRF character string ("1", "0", "=", etc.).
func (ResultCode) String ¶
func (rc ResultCode) String() string
String returns the human-readable name of the result code.
func (*ResultCode) UnmarshalJSON ¶
func (rc *ResultCode) UnmarshalJSON(data []byte) error
UnmarshalJSON decodes a ResultCode from its TRF character string.
type RoundResult ¶
type RoundResult struct {
Opponent int `json:"opponent"` // Start number of opponent (0 = no opponent / bye)
Color Color `json:"color"` // White, Black, or None
Result ResultCode `json:"result"` // Win, Loss, Draw, ForfeitWin, ForfeitLoss, etc.
}
RoundResult is a single round entry from a player's 001 line.
type SimpleTeamResult ¶
type SimpleTeamResult struct {
TeamNumber int `json:"teamNumber"`
TeamName string `json:"teamName"`
MatchPoints float64 `json:"matchPoints"`
GamePoints float64 `json:"gamePoints"`
Rounds []SimpleTeamRound `json:"rounds"`
Raw string `json:"raw"` // Raw line data for round-trip
}
SimpleTeamResult represents an 802 line (simpler team round results). Format: 802 TTT NNNNN MMMMMM GGGGGG T01 C GGGGf ...
type SimpleTeamRound ¶
type SimpleTeamRound struct {
Opponent int `json:"opponent"` // Opponent team number (0 = no match)
Color string `json:"color"` // "w" or "b"
GamePoints float64 `json:"gamePoints"` // Game points scored
Forfeit bool `json:"forfeit,omitempty"` // Whether result includes forfeits
ByeType string `json:"byeType,omitempty"` // "FPB", "HPB", "ZPB", "PAB" for byes, empty for normal
}
SimpleTeamRound is a single round entry in an 802 line.
type TeamLine ¶
type TeamLine struct {
TeamNumber int `json:"teamNumber"`
TeamName string `json:"teamName"`
Members []int `json:"members"` // Start numbers of team members
}
TeamLine represents a 013 team line.
type TeamRoundEntry ¶
type TeamRoundEntry struct {
Round int `json:"round"` // Round number
Team1 int `json:"team1"` // First team number
Team2 int `json:"team2"` // Second team number
Boards []int `json:"boards"` // Player start numbers for each board (0 = empty)
}
TeamRoundEntry represents a 300 line (team round data / board assignments). Format: 300 RRR TT1 TT2 PPP1 PPP2 PPP3 PPP4 RRR = round, TT1/TT2 = team numbers, PPP = player start numbers on boards
type TeamRoundScoreEntry ¶
type TeamRoundScoreEntry struct {
TeamNumber int `json:"teamNumber"`
GamePoints float64 `json:"gamePoints"`
Scores []string `json:"scores"` // Per-round scores as strings (may be empty)
Raw string `json:"raw"` // Raw line data for round-trip
}
TeamRoundScoreEntry represents a 320 line (team round-by-round scores). Format: 320 TTT GGGG RRR1 RRR2 ...
type ValidationIssue ¶
type ValidationIssue struct {
Field string // e.g. "012", "XXR", "player.3.fideID"
Severity Severity // SeverityError or SeverityWarning
Message string // Human-readable description
}
ValidationIssue describes a single problem found during validation.
type ValidationProfile ¶
type ValidationProfile int
ValidationProfile determines which checks to apply.
const ( // ValidateGeneral checks structural integrity only. ValidateGeneral ValidationProfile = iota // ValidatePairingEngine checks fields needed by pairing programs (XXR, XXC, 092). ValidatePairingEngine // ValidateFIDE checks all fields required for FIDE rating submission. ValidateFIDE )