elgo

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: May 6, 2023 License: BSD-3-Clause Imports: 5 Imported by: 0

README

Elgo - Elo matchmaking module in Go

Go Reference codecov Go Report Card Workflow Status

Elgo is a relatively small package that provides a matchmaking pool and a simple calculator for ELO-like rating with configurable K-factor.

Why?

The main idea is to implement some sort of a basic matchmaking tool for 3rd party apps to use. There are plans to release it as a CLI, a Docker container and provide a server API for developers to use it as a package.

How it works?

TLDR version:

How it works diagram

TODO list

  • Add example explanation
  • Add d2lang diagrams
  • Add a git tag/version
  • Add other pool types (non-elo based)
    • LIFO (Stack)
    • FIFO (Queue)
    • Other ...?
  • Add an option to use this as a service
    • gRPC (does it even support channel-like streaming data type?)
    • as a docker container with sockets/grpc

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrAlreadyExists = errors.New("player already exists")
	ErrPoolClosed    = errors.New("pool is closed")
)

Functions

This section is empty.

Types

type CalcOpt added in v1.0.0

type CalcOpt func(*Calculator)

func WithKFactor added in v1.0.0

func WithKFactor(startsAt float64, k float64) CalcOpt

WithKFactor adds one more range that uses a different K-factor.

type Calculator added in v1.0.0

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

Calculator holds options for calculations. Use

elgo.NewCalc(...)

to create a new calculator.

func NewCalc added in v1.0.0

func NewCalc(k float64, opts ...CalcOpt) *Calculator

NewCalc creates a new calculator for rating changes. k is used as a default option and you can pass multiple k factors that will be applied depending on players' rating. Thus:

NewCalc(5, WithKFactor(1000, 20), WithKFactor(1500, 30))

will be used as:

rating > 0 && rating < 1000, k = 5
rating >= 1000 && rating < 1500, k = 20
rating >= 1500, k = 30

There's no option to add max value for rating ranges, it's either infinite or next factor's min value.

func (*Calculator) Draw added in v1.0.0

func (c *Calculator) Draw(p1, p2 Ratinger) (float64, float64)

Draw calculates rating for both players using a 0.5 co-efficient. The order of players in returned values is the same.

func (*Calculator) Win added in v1.0.0

func (c *Calculator) Win(winner, loser Ratinger) (float64, float64)

Win calculates rating for winner and loser. The order of players in returned values is the same.

type Identifier

type Identifier interface {
	// Identify should returns any kind of a unique identifier between players.
	Identify() string
}

Identifier is an interface that helps identify players.

type Match

type Match struct {
	Player1 Player
	Player2 Player
}

Match is a struct that holds 2 players who should be matched.

type Player

type Player interface {
	Identifier
	Ratinger
}

Player is an interface that implements Identifier and Ratinger.

type Pool

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

Pool is a main struct for matchmaking pool. Use NewPool(options...) to create a new pool.

func NewPool

func NewPool(opts ...PoolOpt) *Pool

NewPool creates a new pool for players. Pools aren't connected to each other so creating multiple of them is safe. To close a pool use pool.Close().

func (*Pool) AddPlayer

func (p *Pool) AddPlayer(player Player) error

AddPlayer returns a queue channel to send new players to. ErrAlreadyExists is returned if identifier is already taken. ErrPoolClosed is returned if the pool is closed.

func (*Pool) Close

func (p *Pool) Close() map[string]Player

Close closes the pool and return players that are still in the queue. It's safe to call Close() multiple times, but in that case nil will be returned.

func (*Pool) Matches

func (p *Pool) Matches() <-chan Match

Matches returns a channel that sends found matches between players.

func (*Pool) Run

func (p *Pool) Run()

Run start an infinite loop for matchmaking. Usually it's a good idea to use it as a goroutine:

go pool.Run()

And when you need to close it, use:

playersInQueue := pool.Close()

func (*Pool) Size

func (p *Pool) Size() int

Size returns current amount of players in queue. It's concurrent-safe.

type PoolOpt

type PoolOpt func(*Pool)

func WithGlobalRetryInterval

func WithGlobalRetryInterval(d time.Duration) PoolOpt

WithGlobalRetryInterval sets a duration of how much time a pool should wait between iterations if not a single match was found.

func WithIncreasePlayerBorderBy

func WithIncreasePlayerBorderBy(interval float64) PoolOpt

WithIncreasePlayerBorderBy sets an amount of points that will be added on a new search, if no opponent was found previously.

func WithPlayerRetryInterval

func WithPlayerRetryInterval(d time.Duration) PoolOpt

WithPlayerRetryInterval sets a duration of how much time a player should wait before a pool would try and find a match for them again.

type Ratinger

type Ratinger interface {
	// Rating should return player's rating.
	Rating() float64
}

Ratinger is an interface to receive and change player's rating.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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