core

package
v0.0.0-...-528d695 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2025 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

This file contains thin wrappers around the graph module for managing graph structures in the tournament data.

Index

Constants

View Source
const (
	SeedRandom = iota
	SeedSingle = iota
	SeedTiered = iota
)

Variables

View Source
var (
	ErrBothBye        = errors.New("both bye")
	ErrBothWalkover   = errors.New("both walkover")
	ErrByeAndWalkover = errors.New("bye and walkover")
	ErrNoScore        = errors.New("no score")
	ErrEqualScore     = errors.New("equal score")
)
View Source
var (
	ErrTooFewGroups  = errors.New("the number of groups has to be at least 1")
	ErrTooManyGroups = errors.New("the number of groups is too large for the amount of entries")
	ErrTooFewQuals   = errors.New("the number of qualifications has to be at least 2")
)
View Source
var (
	ErrTooFewEntries = errors.New("not enough entries for this tournament mode")
)

Functions

func MatchesStarted

func MatchesStarted(matches ...*Match) bool

Returns true if one or more of the given matches have started

func NextId

func NextId() int

func RemoveDoubleRanks

func RemoveDoubleRanks(ranks [][]*Slot) [][]*Slot

func SeededShuffle

func SeededShuffle[S ~[]E, E any](seeded S, unseeded S, seedingMode int, rngSeed int64) S

func TieHash

func TieHash(tie []*Slot) string

Creates a hash of the given tie by sorting and concatenating the IDs of the players in the slots. Equal hashes mean the same players are in the ties

Types

type BalancedRanking

type BalancedRanking struct {
	BaseRanking
	// contains filtered or unexported fields
}

A BalancedRanking wraps another ranking and pads it with bye slots such that the number of ranks becomes a power of 2, facilitating a balanced elimination tournament tree.

func NewBalancedRanking

func NewBalancedRanking(source Ranking, rankingGraph *RankingGraph) *BalancedRanking

type BasePlacement

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

A simple index into a Ranking

func NewPlacement

func NewPlacement(ranking Ranking, place int) *BasePlacement

func (*BasePlacement) Ranking

func (p *BasePlacement) Ranking() Ranking

func (*BasePlacement) Slot

func (p *BasePlacement) Slot() *Slot

Returns the current Slot at the Placement

type BaseRanking

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

func NewBaseRanking

func NewBaseRanking() BaseRanking

func NewSlotRanking

func NewSlotRanking(slots []*Slot) *BaseRanking

Creates a BaseRanking with the given slots as the ranks

func (*BaseRanking) At

func (r *BaseRanking) At(i int) *Slot

func (*BaseRanking) Id

func (r *BaseRanking) Id() int

func (*BaseRanking) Ranks

func (r *BaseRanking) Ranks() []*Slot

type BaseTieableRanking

type BaseTieableRanking struct {
	BaseRanking

	RequiredUntiedRanks int
	// contains filtered or unexported fields
}

func NewBaseTieableRanking

func NewBaseTieableRanking(requiredUntiedRanks int) BaseTieableRanking

func (*BaseTieableRanking) AddTieBreaker

func (r *BaseTieableRanking) AddTieBreaker(tieBreaker Ranking)

func (*BaseTieableRanking) BlockingTies

func (r *BaseTieableRanking) BlockingTies(topN int) [][]*Slot

Returns the ties that are in the given top n of ranks

func (*BaseTieableRanking) BlockingUnbrokenTies

func (r *BaseTieableRanking) BlockingUnbrokenTies(topN int) [][]*Slot

Returns the same ties as BlockingTies but without tie breakers applied

func (*BaseTieableRanking) ProcessUpdate

func (r *BaseTieableRanking) ProcessUpdate(updatedTiedRanks [][]*Slot)

Embedders of the BaseTieableRanking should call this in their implementation of the UpdateRanks method to persist the update result

func (*BaseTieableRanking) RemoveTieBreaker

func (r *BaseTieableRanking) RemoveTieBreaker(tieBreaker Ranking)

func (*BaseTieableRanking) String

func (r *BaseTieableRanking) String() string

func (*BaseTieableRanking) TiedRanks

func (r *BaseTieableRanking) TiedRanks() [][]*Slot

Returns a slice of slices of slots.

A slice with multiple slots in it means the rank is tied between them.

func (*BaseTieableRanking) TryTieBreak

func (r *BaseTieableRanking) TryTieBreak(tie []*Slot) [][]*Slot

Attempts to find a tie breaker for the given tie and use it.

On success returns a slice of slices with only one slot per nested slice. If no applicable tie breaker is present the returned slice contains only one nested slice with all slots in it.

func (*BaseTieableRanking) UnbrokenTiedRanks

func (r *BaseTieableRanking) UnbrokenTiedRanks() [][]*Slot

Returns the same ranks as TiedRanks but without the tie breakers applied

type BaseTournament

type BaseTournament[FinalRanking Ranking] struct {
	// The entries ranking which contains
	// the starting slots for all participants.
	Entries Ranking

	*RankingGraph
	FinalRanking FinalRanking

	WithdrawalPolicy
	EditingPolicy
	// contains filtered or unexported fields
}

func (*BaseTournament[_]) Id

func (t *BaseTournament[_]) Id() int

func (*BaseTournament[_]) MatchList

func (t *BaseTournament[_]) MatchList() *matchList

func (BaseTournament) MatchesComplete

func (l BaseTournament) MatchesComplete() bool

Returns true when all matches in the list are complete

func (BaseTournament) MatchesOfPlayer

func (l BaseTournament) MatchesOfPlayer(player Player) []*Match

func (BaseTournament) MatchesStarted

func (l BaseTournament) MatchesStarted() bool

Returns true when any of the matches have started

func (*BaseTournament[_]) Update

func (t *BaseTournament[_]) Update(start Ranking)

type BlockingPlacement

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

A simple index into a Ranking When blocking is true, the Slot() method always returns nil. Otherwise behaves like BasePlacement.

func NewBlockingPlacement

func NewBlockingPlacement(ranking Ranking, place int, blocking bool) *BlockingPlacement

func (*BlockingPlacement) Ranking

func (p *BlockingPlacement) Ranking() Ranking

func (*BlockingPlacement) Slot

func (p *BlockingPlacement) Slot() *Slot

Returns the current Slot at the Placement

func (*BlockingPlacement) UnblockedSlot

func (p *BlockingPlacement) UnblockedSlot() *Slot

type Bye

type Bye struct {
	// This is true when the bye is due to a draw and false
	// when it's due to a player withdrawal
	Drawn bool
}

A Bye is a free win for a player.

type ConsolationBracket

type ConsolationBracket struct {
	*SingleElimination
	Consolations []*ConsolationBracket
}

func (ConsolationBracket) MatchesComplete

func (l ConsolationBracket) MatchesComplete() bool

Returns true when all matches in the list are complete

func (ConsolationBracket) MatchesOfPlayer

func (l ConsolationBracket) MatchesOfPlayer(player Player) []*Match

func (ConsolationBracket) MatchesStarted

func (l ConsolationBracket) MatchesStarted() bool

Returns true when any of the matches have started

type ConstantRanking

type ConstantRanking struct {
	BaseRanking
}

The simplest possible ranking that just provides a list of directly player filled slots

func NewConstantRanking

func NewConstantRanking(players []Player) *ConstantRanking

Creates a *ConstantRanking from the given slice of players. The ranking will provide one Slot per player while keeping the order.

type DependencyGraph

type DependencyGraph[T GraphNode] struct {
	graph.Graph[int, T]
	// contains filtered or unexported fields
}

func (*DependencyGraph[T]) AddEdge

func (g *DependencyGraph[T]) AddEdge(source, target T) error

func (*DependencyGraph[T]) BreadthSearchIter

func (g *DependencyGraph[T]) BreadthSearchIter(start T) iter.Seq2[T, int]

func (*DependencyGraph[T]) GetDependants

func (g *DependencyGraph[T]) GetDependants(source T) []T

Returns the nodes that are on the outgoing edges of the given source node (the dependants).

type DoubleElimination

type DoubleElimination struct {
	BaseTournament[*EliminationRanking]
	WinnerBracket    *SingleElimination
	EliminationGraph *EliminationGraph

	WinnerRankings map[*Match]*WinnerRanking
	// contains filtered or unexported fields
}

func NewDoubleElimination

func NewDoubleElimination(entries Ranking) (*DoubleElimination, error)

func (DoubleElimination) MatchesComplete

func (l DoubleElimination) MatchesComplete() bool

Returns true when all matches in the list are complete

func (DoubleElimination) MatchesOfPlayer

func (l DoubleElimination) MatchesOfPlayer(player Player) []*Match

func (DoubleElimination) MatchesStarted

func (l DoubleElimination) MatchesStarted() bool

Returns true when any of the matches have started

func (*DoubleElimination) ToMap

func (t *DoubleElimination) ToMap(getMatchId func(int) string) map[string]any

type EditingPolicy

type EditingPolicy interface {
	// Returns the comprehensive list of matches that are editable
	EditableMatches() []*Match

	// Updates the return value of EditableMatches
	UpdateEditableMatches()
}

type EliminationEditingPolicy

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

func (*EliminationEditingPolicy) EditableMatches

func (e *EliminationEditingPolicy) EditableMatches() []*Match

Returns the comprehensive list of matches that are editable

func (*EliminationEditingPolicy) UpdateEditableMatches

func (e *EliminationEditingPolicy) UpdateEditableMatches()

Updates the return value of EditableMatches

type EliminationGraph

type EliminationGraph struct {
	DependencyGraph[*Match]
}

The EliminationGraph has all matches of an elimination tournament as its nodes. The edges between the nodes model the path that the players take towards the final like a conventional tournament tree.

func NewEliminationGraph

func NewEliminationGraph() *EliminationGraph

type EliminationRanking

type EliminationRanking struct {
	BaseTieableRanking

	MatchList *matchList
	Entries   Ranking
}

The EliminationRanking ranks the players in an elimination tournament according to how far they reached. It is a tieable ranking with the players who lost out in the same round being tied on the same rank.

func NewEliminationRanking

func NewEliminationRanking(
	matchList *matchList,
	entries Ranking,
	finalsRankings []Ranking,
	rankingGraph *RankingGraph,
) *EliminationRanking

type EliminationWithdrawalPolicy

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

func (*EliminationWithdrawalPolicy) ListReenterMatches

func (w *EliminationWithdrawalPolicy) ListReenterMatches(player Player) []*Match

func (*EliminationWithdrawalPolicy) ListWithdrawMatches

func (w *EliminationWithdrawalPolicy) ListWithdrawMatches(player Player) []*Match

func (*EliminationWithdrawalPolicy) ReenterPlayer

func (w *EliminationWithdrawalPolicy) ReenterPlayer(player Player) []*Match

Attempts to reenter the player into the tournament. On success the specific matches that the player was reentered into are returned.

func (*EliminationWithdrawalPolicy) WithdrawPlayer

func (w *EliminationWithdrawalPolicy) WithdrawPlayer(player Player) []*Match

Withdraws the given player from the tournament. The specific matches that the player was withdrawn from are returned.

type EvenRanking

type EvenRanking struct {
	BaseRanking
	// contains filtered or unexported fields
}

An even Ranking appends a bye slot to its ranks but only if the source ranking has an uneven number of slots so it is guaranteed to have an even number.

func NewEvenRanking

func NewEvenRanking(source Ranking, rankingGraph *RankingGraph) *EvenRanking

type GraphNode

type GraphNode interface {
	// A unique ID that is used as the node hash
	Id() int
}

type GroupKnockout

type GroupKnockout struct {
	BaseTournament[*GroupKnockoutRanking]
	GroupPhase         *GroupPhase
	KnockOut           *BaseTournament[*EliminationRanking]
	KnockOutTournament KnockOutTournament
	// contains filtered or unexported fields
}

func NewGroupKnockout

func NewGroupKnockout(
	entries Ranking,
	knockoutBuilder KnockoutBuilder,
	numGroups, numQualifications int,
	walkoverScore Score,
) (*GroupKnockout, error)

func (GroupKnockout) MatchesComplete

func (l GroupKnockout) MatchesComplete() bool

Returns true when all matches in the list are complete

func (GroupKnockout) MatchesOfPlayer

func (l GroupKnockout) MatchesOfPlayer(player Player) []*Match

func (GroupKnockout) MatchesStarted

func (l GroupKnockout) MatchesStarted() bool

Returns true when any of the matches have started

func (*GroupKnockout) OverrideQualifications

func (t *GroupKnockout) OverrideQualifications(override []Player)

func (*GroupKnockout) ToMap

func (t *GroupKnockout) ToMap(getMatchId func(int) string) map[string]any

type GroupKnockoutEditingPolicy

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

func (*GroupKnockoutEditingPolicy) EditableMatches

func (e *GroupKnockoutEditingPolicy) EditableMatches() []*Match

func (*GroupKnockoutEditingPolicy) UpdateEditableMatches

func (e *GroupKnockoutEditingPolicy) UpdateEditableMatches()

type GroupKnockoutRanking

type GroupKnockoutRanking struct {
	BaseTieableRanking
	// contains filtered or unexported fields
}

func NewGroupKnockoutRanking

func NewGroupKnockoutRanking(groupPhase *GroupPhase, knockOut *BaseTournament[*EliminationRanking]) *GroupKnockoutRanking

type GroupKnockoutWithdrawalPolicy

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

func (*GroupKnockoutWithdrawalPolicy) ListReenterMatches

func (w *GroupKnockoutWithdrawalPolicy) ListReenterMatches(player Player) []*Match

func (*GroupKnockoutWithdrawalPolicy) ListWithdrawMatches

func (w *GroupKnockoutWithdrawalPolicy) ListWithdrawMatches(player Player) []*Match

func (*GroupKnockoutWithdrawalPolicy) ReenterPlayer

func (w *GroupKnockoutWithdrawalPolicy) ReenterPlayer(player Player) []*Match

Attempts to reenter the player into the tournament. On success the specific matches that the player was reentered into are returned.

func (*GroupKnockoutWithdrawalPolicy) WithdrawPlayer

func (w *GroupKnockoutWithdrawalPolicy) WithdrawPlayer(player Player) []*Match

Withdraws the given player from the tournament. The specific matches that the player was withdrawn from are returned.

type GroupPhase

type GroupPhase struct {
	BaseTournament[*GroupPhaseRanking]
	Groups []*RoundRobin
}

func (GroupPhase) MatchesComplete

func (l GroupPhase) MatchesComplete() bool

Returns true when all matches in the list are complete

func (GroupPhase) MatchesOfPlayer

func (l GroupPhase) MatchesOfPlayer(player Player) []*Match

func (GroupPhase) MatchesStarted

func (l GroupPhase) MatchesStarted() bool

Returns true when any of the matches have started

type GroupPhaseRanking

type GroupPhaseRanking struct {
	BaseTieableRanking

	GroupTies map[int][][]*Slot

	// Is true when all group matches are finished
	// and all blocking ties are broken
	QualificationComplete bool
	// contains filtered or unexported fields
}

func NewGroupPhaseRanking

func NewGroupPhaseRanking(
	groups []*RoundRobin,
	numQualifications int,
	crossGroupRanking TieableRanking,
	rankingGraph *RankingGraph,
) *GroupPhaseRanking

func (*GroupPhaseRanking) CrossGroupTies

func (r *GroupPhaseRanking) CrossGroupTies() [][]*Slot

The cross group ties are populated when there is a contested qualification between the occupants of one rank across different groups. They are always empty while the groups have blocking ties locally. Those are found in t.GroupTies.

type GroupQualificationRanking

type GroupQualificationRanking struct {
	BaseRanking
	// contains filtered or unexported fields
}

func NewGroupQualificationRanking

func NewGroupQualificationRanking(source *GroupPhaseRanking, rankingGraph *RankingGraph) *GroupQualificationRanking

type KnockOutTournament

type KnockOutTournament interface {
	// contains filtered or unexported methods
}

func NewGroupKnockoutDoubleElimination

func NewGroupKnockoutDoubleElimination(entries Ranking, rankingGraph *RankingGraph) (KnockOutTournament, error)

func NewGroupKnockoutSingleElimination

func NewGroupKnockoutSingleElimination(entries Ranking, rankingGraph *RankingGraph) (KnockOutTournament, error)

type KnockoutBuilder

type KnockoutBuilder func(entries Ranking, rankingGraph *RankingGraph) (KnockOutTournament, error)

func SingleEliminationWithConsolationBuilder

func SingleEliminationWithConsolationBuilder(
	numConsolationRounds, placesToPlayOut int,
) KnockoutBuilder

type Location

type Location interface {
	Id() string
}

A Location is a court or a field where a match is played on

type Match

type Match struct {
	// The first opponent slot
	Slot1 *Slot
	// The second opponent slot
	Slot2 *Slot

	// An iterator that goes over the two slots
	Slots iter.Seq[*Slot]

	// Score of the match or
	// nil when the match is not completed
	Score Score

	// The location where this match is played
	Location Location

	// The time when the match was started
	// If this is not zero and the EndTime
	// is zero it means the match is in progress
	StartTime time.Time

	// The time when the match concluded
	// When this is not zero the StartTime
	// and Score should also not be zero/nil
	EndTime time.Time

	// A list of players who withdrew from this
	// match
	WithdrawnPlayers []Player
	// contains filtered or unexported fields
}

A match with two slots for the opponents.

It also has information about the result of the match and some meta data.

func CreatePairedMatches

func CreatePairedMatches(entrySlots []*Slot) []*Match

Creates matches with the slots taken pair-wise from the entrySlots

func CreateSeededMatches

func CreateSeededMatches(entrySlots []*Slot) []*Match

Creates matches with the slots being arranged for a seeded elimination round

func NewMatch

func NewMatch(slot1, slot2 *Slot) *Match

func (*Match) ContainsPlayer

func (m *Match) ContainsPlayer(player Player) bool

func (*Match) EndMatch

func (m *Match) EndMatch(score Score) error

func (*Match) GetWinner

func (m *Match) GetWinner() (*Slot, error)

func (*Match) HasBye

func (m *Match) HasBye() bool

func (*Match) HasDrawnBye

func (m *Match) HasDrawnBye() bool

func (*Match) Id

func (m *Match) Id() int

func (*Match) IsPlayerWithdrawn

func (m *Match) IsPlayerWithdrawn(player Player) bool

Returns true when the given player has withdrawn and is occupying one of the slots

func (*Match) IsWalkover

func (m *Match) IsWalkover() bool

func (*Match) OtherSlot

func (m *Match) OtherSlot(slot *Slot) *Slot

func (*Match) StartMatch

func (m *Match) StartMatch() error

func (*Match) String

func (m *Match) String() string

func (*Match) ToMap

func (m *Match) ToMap() map[string]any

func (*Match) WithdrawnSlots

func (m *Match) WithdrawnSlots() []*Slot

Returns the slots that are occupied by withdrawn players

type MatchLister

type MatchLister interface {
	MatchList() *matchList
}

type MatchMetricRanking

type MatchMetricRanking struct {
	BaseTieableRanking

	// Each player's metrics which are the basis for the ranks.
	// The metrics are updated in the updateRanks call
	Metrics map[Player]*MatchMetrics
	// contains filtered or unexported fields
}

A MatchMetricRanking ranks the players who played a list of matches by their performance according to some metrics

func NewCrossGroupRanking

func NewCrossGroupRanking(
	entries Ranking,
	groups []*RoundRobin,
	matches []*Match,
	walkoverScore Score,
	numQualifications int,
) *MatchMetricRanking

func NewRoundRobinRanking

func NewRoundRobinRanking(
	entries Ranking,
	matches []*Match,
	walkoverScore Score,
	rankingGraph *RankingGraph,
) *MatchMetricRanking

type MatchMetrics

type MatchMetrics struct {
	NumMatches int `json:"numMatches"`
	Wins       int `json:"wins"`
	Losses     int `json:"losses"`

	NumSets   int `json:"numSets"`
	SetWins   int `json:"setWins"`
	SetLosses int `json:"setLosses"`

	PointWins   int `json:"pointWins"`
	PointLosses int `json:"pointLosses"`

	SetDifference   int `json:"-"`
	PointDifference int `json:"-"`

	Withdrawn bool `json:"-"`
}

func (*MatchMetrics) Add

func (m *MatchMetrics) Add(other *MatchMetrics)

Add the other match metrics to this one

func (*MatchMetrics) UpdateDifferences

func (m *MatchMetrics) UpdateDifferences()

type Placement

type Placement interface {
	Slot() *Slot
	Ranking() Ranking
}

type Player

type Player interface {
	// Returns an ID that is unique among the players of
	// a tournament
	Id() string
}

A Player is either a person or a team who is taking part in a tournament.

type Ranking

type Ranking interface {
	// Returns the current ranks
	Ranks() []*Slot

	// Returns the occupant of the ith place in the Ranking.
	// Returns nil if the place is unoccupied or out of bounds.
	At(i int) *Slot

	GraphNode
	// contains filtered or unexported methods
}

A Ranking orders a set of Slots according to an implementation specific metric.

type RankingGraph

type RankingGraph struct {
	DependencyGraph[Ranking]
}

A RankingGraph contains all rankings of a tournament as its nodes. The directed edges between the nodes model the dependencies between the rankings.

If a ranking resolves its slots from a placement in another ranking it will have an incoming edge from that ranking.

The graph is acyclic and forms a topological hierarchy which determines the order in which rankings have to be updated in order to properly propagate a change.

func NewRankingGraph

func NewRankingGraph(root Ranking) *RankingGraph

type RankingUpdater

type RankingUpdater interface {
	// Updates all rankings and slots going
	// from the start Ranking in the
	// dependecy graph
	Update(start Ranking)
}

type Round

type Round struct {
	// The matches that are played in this round
	Matches []*Match

	// Other Rounds that this Round is composed of
	// Is empty when no underlying rounds exist
	NestedRounds []*Round
}

A Round is a list of matches that can be played in parallel during a tournament. The matches of a round depend on the completion of all previous rounds.

type RoundRobin

type RoundRobin struct {
	BaseTournament[*MatchMetricRanking]
}

func NewRoundRobin

func NewRoundRobin(entries Ranking, passes int, walkoverScore Score) (*RoundRobin, error)

func (RoundRobin) MatchesComplete

func (l RoundRobin) MatchesComplete() bool

Returns true when all matches in the list are complete

func (RoundRobin) MatchesOfPlayer

func (l RoundRobin) MatchesOfPlayer(player Player) []*Match

func (RoundRobin) MatchesStarted

func (l RoundRobin) MatchesStarted() bool

Returns true when any of the matches have started

func (*RoundRobin) ToMap

func (t *RoundRobin) ToMap(getMatchId func(int) string) map[string]any

type RoundRobinEditingPolicy

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

func (*RoundRobinEditingPolicy) EditableMatches

func (e *RoundRobinEditingPolicy) EditableMatches() []*Match

Returns the comprehensive list of matches that are editable

func (*RoundRobinEditingPolicy) UpdateEditableMatches

func (e *RoundRobinEditingPolicy) UpdateEditableMatches()

Updates the return value of EditableMatches

type RoundRobinWithdrawalPolicy

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

func (*RoundRobinWithdrawalPolicy) ListReenterMatches

func (w *RoundRobinWithdrawalPolicy) ListReenterMatches(player Player) []*Match

Attempts to reenter the player into the tournament. On success the specific matches that the player was reentered into are returned.

func (*RoundRobinWithdrawalPolicy) ListWithdrawMatches

func (w *RoundRobinWithdrawalPolicy) ListWithdrawMatches(player Player) []*Match

func (*RoundRobinWithdrawalPolicy) ReenterPlayer

func (w *RoundRobinWithdrawalPolicy) ReenterPlayer(player Player) []*Match

Attempts to reenter the player into the tournament. On success the specific matches that the player was reentered into are returned.

func (*RoundRobinWithdrawalPolicy) WithdrawPlayer

func (w *RoundRobinWithdrawalPolicy) WithdrawPlayer(player Player) []*Match

Withdraws the given player from the tournament. The specific matches that the player was withdrawn from are returned.

type Score

type Score interface {
	// Points of first opponent
	Points1() []int

	// Points of second opponent
	Points2() []int

	// Returns either 0 or 1 whether the
	// first opponent won or the second.
	// Errors when no winner is determined.
	GetWinner() (int, error)

	// Returns a new Score that has Points1
	// and Points2 flipped
	Invert() Score
}

The result of a match.

The scores are slices to be able to model competitions where a match consists of multiple sets (e.g. Tennis)

type SingleElimination

type SingleElimination struct {
	BaseTournament[*EliminationRanking]
	EliminationGraph *EliminationGraph
	WinnerRankings   map[*Match]*WinnerRanking
}

func NewSingleElimination

func NewSingleElimination(entries Ranking) (*SingleElimination, error)

func (SingleElimination) MatchesComplete

func (l SingleElimination) MatchesComplete() bool

Returns true when all matches in the list are complete

func (SingleElimination) MatchesOfPlayer

func (l SingleElimination) MatchesOfPlayer(player Player) []*Match

func (SingleElimination) MatchesStarted

func (l SingleElimination) MatchesStarted() bool

Returns true when any of the matches have started

func (*SingleElimination) ToMap

func (t *SingleElimination) ToMap(getMatchId func(int) string) map[string]any

type SingleEliminationWithConsolation

type SingleEliminationWithConsolation struct {
	BaseTournament[*EliminationRanking]
	MainBracket      *ConsolationBracket
	Brackets         []*ConsolationBracket
	EliminationGraph *EliminationGraph
}

func NewSingleEliminationWithConsolation

func NewSingleEliminationWithConsolation(
	entries Ranking,
	numConsolationRounds, placesToPlayOut int,
) (*SingleEliminationWithConsolation, error)

func (SingleEliminationWithConsolation) MatchesComplete

func (l SingleEliminationWithConsolation) MatchesComplete() bool

Returns true when all matches in the list are complete

func (SingleEliminationWithConsolation) MatchesOfPlayer

func (l SingleEliminationWithConsolation) MatchesOfPlayer(player Player) []*Match

func (SingleEliminationWithConsolation) MatchesStarted

func (l SingleEliminationWithConsolation) MatchesStarted() bool

Returns true when any of the matches have started

func (*SingleEliminationWithConsolation) ToMap

func (t *SingleEliminationWithConsolation) ToMap(getMatchId func(int) string) map[string]any

type Slot

type Slot struct {
	Player    Player
	Placement Placement
	Bye       *Bye
	Id        int
}

A Slot is either a spot in a Ranking or one of two places in a Match.

A Slot can represent one of 3 things:

  • An actual player
  • A not yet determined qualification called a Placement. (e.g. the slots of a final match are the winners of the semi-finals)
  • A free win (bye) for the match opponent

The Slot changes what it is representing depending on the state of the tournament (e.g. when the results of the semi-finals become known the final slots go from undetermined qualifications to actual players or when a player withdraws from the tournament their slot goes from actual player to bye).

func NewByeSlot

func NewByeSlot(drawn bool) *Slot

func NewPlacementSlot

func NewPlacementSlot(placement Placement) *Slot

func NewPlayerSlot

func NewPlayerSlot(player Player) *Slot

func (*Slot) IsBye

func (s *Slot) IsBye() bool

Returns whether this slot is an effective bye.

Effective bye means it is also true when the slot inherits a bye slot via placement

func (*Slot) Update

func (s *Slot) Update()

Updates the return value of the Player method. This method is called when the ranking that this slot is dependant on updates. The dependency is stored in the ranking's list of dependant slots [Ranking.GetDependantSlots].

type TieableRanking

type TieableRanking interface {
	Ranking

	// Returns a slice of slices of slots.
	//
	// A slice with multiple slots in it means the rank
	// is tied between them.
	TiedRanks() [][]*Slot

	// Returns the same ranks as TiedRanks but
	// without the tie breakers applied
	UnbrokenTiedRanks() [][]*Slot

	// Tie breakers which are a set of
	// rankings. All ties that contain the same set
	// of players as one of the tie breakers are
	// broken using the order of the tie breaker ranking.
	AddTieBreaker(tieBreaker Ranking)
	RemoveTieBreaker(tieBreaker Ranking)

	// Returns the ties that are in the
	// given top n of ranks
	BlockingTies(topN int) [][]*Slot

	// Returns the same ties as BlockingTies
	// but without tie breakers applied
	BlockingUnbrokenTies(topN int) [][]*Slot
}

type TournamentMarshaller

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

type WinnerRanking

type WinnerRanking struct {
	BaseRanking

	Match *Match
}

A WinnerRanking ranks the two participants of a Match into winner and loser.

func NewWinnerRanking

func NewWinnerRanking(match *Match) *WinnerRanking

Creates a new WinnerRanking

func (*WinnerRanking) LinkRankingGraph

func (r *WinnerRanking) LinkRankingGraph(rankingGraph *RankingGraph, allowedLinks map[*Match]*WinnerRanking)

Adds this WinnerRanking as a dependant to the source rankings of the match's slots if they are both also WinnerRankings and the matches of those are keys in the allowedLinks

type WithdrawalPolicy

type WithdrawalPolicy interface {
	// Withdraws the given player from the tournament.
	// The specific matches that the player was withdrawn from
	// are returned.
	WithdrawPlayer(player Player) []*Match

	// Attempts to reenter the player into the tournament.
	// On success the specific matches that the player
	// was reentered into are returned.
	ReenterPlayer(player Player) []*Match

	// Lists the matches that a player would be withdrawn from
	// if WithdrawPlayer was called
	ListWithdrawMatches(player Player) []*Match

	// Lists the matches that a player would reenter into
	// if ReenterPlayer was called
	ListReenterMatches(player Player) []*Match
}

The WithdrawalPolicy dictates how a player can withdraw from a tournament and also if a player would be allowed to reenter.

Jump to

Keyboard shortcuts

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