Documentation
¶
Overview ¶
Package lexswiss provides shared data structures and algorithms for lexicographic Swiss pairing systems. Both the Double-Swiss (C.04.5) and Team Swiss (C.04.6) engines build on this foundation.
The lexicographic approach enumerates all legal pairings of a bracket in lexicographic order and selects the first one satisfying all criteria. This is fundamentally different from Dutch/Burstein/Dubov which use Blossom matching or transposition-based approaches.
Key shared components:
- ParticipantState: player/team state for pairing
- BuildScoreGroups: scoregroup construction
- AssignPAB: bye assignment (Art. 3.4)
- SelectUpfloaters: upfloater selection (Art. 3.5)
- PairBracket: lexicographic bracket pairing (Art. 3.6)
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func HasPlayed ¶
func HasPlayed(a, b *ParticipantState) bool
HasPlayed returns true if participant a has played against participant b (based on opponent history, which excludes forfeits).
func PairBracket ¶
func PairBracket(participants []*ParticipantState, forbidden map[[2]string]bool, criteriaFn CriteriaFunc) [][2]*ParticipantState
PairBracket pairs all participants in a bracket using the lexicographic algorithm described in Art. 3.6 (shared by Double-Swiss and Team Swiss).
The algorithm enumerates all legal pairings in lexicographic order and selects the first one satisfying all criteria. Lexicographic order means: the participant with the lowest TPN is paired with the lowest-TPN available partner first. If that leads to a dead end (remaining participants can't all be paired), the algorithm backtracks and tries the next partner.
Absolute criteria enforced by PairBracket:
- C1: No two participants play each other more than once
- Forbidden pairs are not paired
Additional criteria are checked via the CriteriaFunc parameter. If criteriaFn is nil, only C1 and forbidden pairs are checked.
Parameters:
- participants: sorted by TPN ascending
- forbidden: forbidden pairs map (nil if none)
- criteriaFn: additional criteria function (nil = no extra criteria)
Returns the list of pairs (each pair is [lower-TPN, higher-TPN]). If no complete pairing is possible, returns the best partial pairing (as many pairs as possible in lexicographic order).
Types ¶
type Color ¶
type Color int
Color represents a participant's colour assignment in a round.
type CriteriaFunc ¶
type CriteriaFunc func(a, b *ParticipantState) bool
CriteriaFunc is a function that checks whether a proposed pair satisfies system-specific criteria. Returns true if the pair is acceptable.
The function is called for each candidate pair during the lexicographic enumeration. If it returns false, the pair is skipped and the next candidate is tried.
Double-Swiss uses this for C8 (colour preferences). Team Swiss uses this for C8-C10 (colour preferences).
type ParticipantState ¶
type ParticipantState struct {
ID string
DisplayName string
InitialRank int // starting rank (by rating desc, then name asc), 1-based
TPN int // Tournament Pairing Number, 1-based (re-ranked each round)
Score float64 // cumulative pairing score (standard 1-½-0)
ColorHistory []Color // colour per round (index 0 = round 1)
Opponents []string // IDs of opponents faced (forfeits excluded)
ByeReceived bool // already received a PAB
Active bool
Rating int
}
ParticipantState holds the computed state of a single participant (player or team) for the lexicographic pairing algorithm. Built once per Pair() call from the engine's TournamentState.
This is deliberately simpler than swisslib.PlayerState because the lexicographic systems don't need float history, Blossom criteria weights, or the three-tier colour preference system.
func AssignPAB ¶
func AssignPAB(participants []*ParticipantState) *ParticipantState
AssignPAB selects the participant to receive the pairing-allocated bye per Art. 3.4 (shared by Double-Swiss and Team Swiss):
- Lowest score
- Among ties: highest TPN (lowest ranking)
- Must not have already received a PAB
Returns nil if all participants have already received a PAB.
func BuildParticipantStates ¶
func BuildParticipantStates(state *chesspairing.TournamentState) []ParticipantState
BuildParticipantStates converts a TournamentState into a sorted slice of ParticipantState values ready for the pairing algorithm.
Active participants only. Sorted by score (desc), then initial rank (asc). TPN assigned sequentially after sorting.
Pairing scores use standard 1-½-0 regardless of tournament scoring system. Forfeit games are excluded from opponent history (participants can be paired again).
func SelectUpfloater ¶
func SelectUpfloater(bracket []*ParticipantState, targetBracket []*ParticipantState, forbidden map[[2]string]bool) *ParticipantState
SelectUpfloater selects the participant to float up from a bracket to the bracket above, per Art. 3.5 (shared by Double-Swiss and Team Swiss).
The upfloater is the lowest-ranked participant (highest TPN) who has at least one compatible opponent in the target bracket. Compatibility means: (1) not already played, and (2) not a forbidden pair.
Parameters:
- bracket: participants in the current bracket (odd count)
- targetBracket: participants in the bracket above (where floater goes)
- forbidden: forbidden pairs map (nil if none)
Returns nil if no valid upfloater can be selected (all have played everyone in the target bracket).
type ScoreGroup ¶
type ScoreGroup struct {
Score float64
Participants []*ParticipantState // ordered by TPN ascending
}
ScoreGroup holds all participants with the same pairing score. Participants are ordered by TPN ascending within the group.
func BuildScoreGroups ¶
func BuildScoreGroups(participants []ParticipantState) []ScoreGroup
BuildScoreGroups creates score groups from participant states. Participants are grouped by Score and each group is sorted by TPN ascending. Returns groups in descending score order. Input need not be pre-sorted.