glicko2

package
v0.0.11-otel Latest Latest
Warning

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

Go to latest
Published: Nov 11, 2024 License: MIT Imports: 7 Imported by: 0

README

Glicko-2 Matcher

This project implements a matcher for glicko-2 algorithm.

Run Example

  1. Download the code and enter the root directory of the glicko2.
  2. Run matcher
     go test ./example -v -run Test_Matcher
    

Hou To Use

go get -u github.com/hedon954/go-matcher/pkg/algorithm/glicko2
  1. Implement Player, Group, Team and Room interfaces according to your business needs.
  2. Create a Matcher by NewMatcher(), and run matcher.Start() to start matching.
  3. When the Group starts to match, call matcher.AddGroups(groups...) to add the group to the matching queue and wait for the matching result.

Documentation

Index

Constants

View Source
const (
	TeamQueue   = "TeamQueue"
	NormalQueue = "NormalQueue"
)
View Source
const (
	CancelMatchByServerStop = "Failed to match. Please try again later"
	CancelMatchByTimeout    = "No team found, please try again later"
)

Variables

View Source
var (
	ErrQueueClosed      = errors.New("Match queue has been closed")
	ErrNilGetArgsFunc   = errors.New("the func getQueueArgs is nil")
	ErrNilGetArgsReturn = errors.New("getQueueArgs() == nil")
)

Functions

This section is empty.

Types

type Args

type Args struct {

	// Player rating, which is a direct measure of a player's ability.
	MMR float64 `json:"mmr"`

	// Rating deviation, which is a measure of the accuracy of the rating.
	// If you're a new player or haven't played in a while, your RD will be high, indicating that your true skill may be far from your rating.
	// If you frequently play, your RD will decrease, indicating that your rating is getting closer to your true skill.
	RD float64 `json:"rd"`

	// Volatility; this is a measure of the fluctuation in a player's rating.
	V float64 `json:"v"`
}

Args encapsulates the three core parameters of the Glicko-2 algorithm.

type Group

type Group interface {
	// GetID returns the team ID
	GetID() string

	// QueueKey returns the unique match queue ID
	QueueKey() string

	// GetPlayers returns the list of players in the team
	GetPlayers() []Player

	// PlayerCount returns the number of players in the team
	PlayerCount() int

	// GetMMR returns the MMR value of the team
	GetMMR() float64

	// GetStar returns the team's rank value
	GetStar() int

	// GetState returns the team's state
	GetState() GroupState
	SetState(state GroupState)

	// GetStartMatchTimeSec returns the start time of the match, which is the earliest start time of the player
	GetStartMatchTimeSec() int64
	SetStartMatchTimeSec(t int64)

	// GetFinishMatchTimeSec returns the end time of the match
	GetFinishMatchTimeSec() int64
	SetFinishMatchTimeSec(t int64)

	// Type returns the team type
	Type() GroupType

	// CanFillAi returns true if the team will be filled with AI and the second return value is the AI team to be filled
	CanFillAi() bool

	// ForceCancelMatch is the logic for handling player cancellation when forced to exit
	ForceCancelMatch(reason string, waitSec int64)

	// IsNewer checks if the team is identified as a newcomer
	IsNewer() bool
}

Group represents a team, players can form teams on their own or a single player will be assigned a team when they start matching, the team before and after the match will not be broken up.

type GroupState

type GroupState uint8
const (
	GroupStateUnready GroupState = iota // Unready state
	GroupStateQueuing                   // Matching state
	GroupStateMatched                   // Matched state
)

type GroupType

type GroupType uint8

GroupType is the type of team

const (
	// GroupTypeNotTeam represents no team
	GroupTypeNotTeam GroupType = iota
	// GroupTypeNormalTeam represents a normal team
	GroupTypeNormalTeam
	// GroupTypeUnfriendlyTeam represents an unfriendly team
	GroupTypeUnfriendlyTeam
	// GroupTypeMaliciousTeam represents a malicious team
	GroupTypeMaliciousTeam
)

type MatchRange

type MatchRange struct {
	// Maximum match duration in seconds (exclusive)
	MaxMatchSec int64 `json:"max_match_sec" yaml:"max_match_sec"`
	// Allowed MMR difference percentage (0-100) (inclusive), 0 means no restriction
	MMRGapPercent int `json:"mmr_gap_percent" yaml:"mmr_gap_percent"`
	// Whether to join full teams
	CanJoinTeam bool `json:"can_join_team" yaml:"can_join_team"`
	// Allowed rank difference (inclusive), 0 means no restriction
	StarGap int `json:"star_gap" yaml:"star_gap"`
}

type Matcher

type Matcher struct {
	NormalQueue *Queue
	TeamQueue   *Queue
	// contains filtered or unexported fields
}

func NewMatcher

func NewMatcher(
	errChan chan error,
	roomChan chan Room,
	getQueueArgs func() *QueueArgs,
	newTeamFunc func(group Group) Team,
	newRoomFunc func(team Team) Room,
	newRoomWithAiFunc func(team Team) Room,
) (*Matcher, error)

NewMatcher is a matcher, which contains both normal queue and team queue.

func (*Matcher) AddGroups

func (qm *Matcher) AddGroups(gs ...Group) error

AddGroups adds groups to the queue.

func (*Matcher) Match

func (qm *Matcher) Match(interval time.Duration)

func (*Matcher) Stop

func (qm *Matcher) Stop() ([]Group, []Group)

type Player

type Player interface {

	// Player ID
	GetID() string

	// Is the player an AI?
	IsAi() bool

	// Get the player's MMR value
	GetMMR() float64

	// Get the player's rank value
	GetStar() int

	// Get the time the player started matching
	GetStartMatchTimeSec() int64
	SetStartMatchTimeSec(t int64)

	// Get the time the player finished matching
	GetFinishMatchTimeSec() int64
	SetFinishMatchTimeSec(t int64)

	// Get the player's rank within their team after the match
	GetRank() int
}

Player is an abstract representation of a player

type Queue

type Queue struct {
	Name     string           // Queue name
	Groups   map[string]Group // Groups in the queue, all operations on Groups need to be locked
	FullTeam []Team           // Fully formed temporary teams during matching, called only in Match, not thread-safe
	TmpTeam  []Team           // Temporary teams during matching, called only in Match, not thread-safe
	TmpRoom  []Room           // Temporary rooms during matching, called only in Match, not thread-safe

	*QueueArgs // Queue parameters
	// contains filtered or unexported fields
}

Queue is a match queue

func NewQueue

func NewQueue(
	name string, roomChan chan Room,
	getQueueArgs func() *QueueArgs,
	newTeamFunc func(group Group) Team,
	newRoomFunc func(team Team) Room,
	newRoomWithAiFunc func(team Team) Room,
	nowUnixFunc func() int64,
) (*Queue, error)

func (*Queue) AddGroups

func (q *Queue) AddGroups(gs ...Group) error

AddGroups adds groups to the queue

func (*Queue) AllGroups

func (q *Queue) AllGroups() []Group

func (*Queue) GetAndClearGroups

func (q *Queue) GetAndClearGroups() []Group

GetAndClearGroups retrieves and clears the current groups list

func (*Queue) Lock

func (q *Queue) Lock()

func (*Queue) Match

func (q *Queue) Match(groups []Group) []Group

Match queue matching logic

func (*Queue) SortedGroups

func (q *Queue) SortedGroups() []Group

func (*Queue) StopMatch

func (q *Queue) StopMatch() []Group

StopMatch cancels the match

func (*Queue) Unlock

func (q *Queue) Unlock()

type QueueArgs

type QueueArgs struct {
	MatchTimeoutSec int64 `json:"match_timeout_sec" yaml:"match_timeout_sec"` // Match timeout duration

	TeamPlayerLimit int `json:"team_player_limit" yaml:"team_player_limit"` // Team player limit
	RoomTeamLimit   int `json:"room_team_limit" yaml:"room_team_limit"`     // Room team limit

	// Whether beginners can only match with beginners
	NewerWithNewer bool `json:"newer_with_newer" yaml:"newer_with_newer"`

	// Minimum MMR variance for unfriendly teams
	UnfriendlyTeamMMRVarianceMin int `json:"unfriendly_team_mmr_variance_min" yaml:"unfriendly_team_mmr_variance_min"`

	// Minimum MMR variance for malicious teams
	MaliciousTeamMMRVarianceMin int `json:"malicious_team_mmr_variance_min" yaml:"malicious_team_mmr_variance_min"`

	// Matching duration for normal teams in exclusive queue
	NormalTeamWaitTimeSec int64 `json:"normal_team_wait_time_sec" yaml:"normal_team_wait_time_sec"`
	// Matching duration for unfriendly teams in exclusive queue
	UnfriendlyTeamWaitTimeSec int64 `json:"unfriendly_team_wait_time_sec" yaml:"unfriendly_team_wait_time_sec"`
	// Matching duration for malicious teams in exclusive queue
	MaliciousTeamWaitTimeSec int64 `json:"malicious_team_wait_time_sec" yaml:"malicious_team_wait_time_sec"`

	// Match range strategies
	MatchRanges []MatchRange `json:"match_ranges" yaml:"match_ranges"`
}

type Room

type Room interface {
	// Get the teams in the room
	GetTeams() []Team

	// Add a team to the room
	AddTeam(t Team)

	// Get the MMR (Match Market Rating) value of the room
	GetMMR() float64

	// Get the start time of the match, which is the earliest start time of the player
	GetStartMatchTimeSec() int64

	// Check if the room contains an AI
	HasAi() bool
}

Room is an abstract representation of a room, composed of multiple teams

type Team

type Team interface {
	// Get the list of groups
	GetGroups() []Group

	// Add a group to the team
	AddGroup(group Group)

	// Get the number of players in the team
	PlayerCount() int

	// Get the MMR (Match Market Rating) value of the team
	GetMMR() float64

	// Get the rank value of the team
	GetStar() int

	// Get the start time of the match, which is the earliest start time of the player
	GetStartMatchTimeSec() int64

	// Get the end time of the match
	GetFinishMatchTimeSec() int64
	SetFinishMatchTimeSec(t int64)

	// Check if the team is an AI team
	IsAi() bool

	// Check if the team can be filled with AI
	CanFillAi() bool

	// Check if the team is full
	IsFull(teamPlayerLimit int) bool

	// Check if the team is considered a newcomer
	IsNewer() bool
}

Team is an abstract representation of a team, composed of 1-n Groups

Jump to

Keyboard shortcuts

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