go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/experiments/matchmaker/pkg/sim/player.go (about) 1 /* 2 3 Copyright (c) 2024 - Present. Will Charczuk. All rights reserved. 4 Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 5 6 */ 7 8 package sim 9 10 import ( 11 "slices" 12 "time" 13 14 c9s "go.charczuk.com/sdk/collections" 15 "go.charczuk.com/sdk/mathutil" 16 "go.charczuk.com/sdk/uuid" 17 ) 18 19 type Player struct { 20 ID uuid.UUID 21 IdleAt time.Time 22 QueuedAt time.Time 23 TimedOutAt time.Time 24 25 Rating int 26 NaturalSkill int 27 28 Games int 29 Wins int 30 31 QueuedElapsed []time.Duration 32 Recent *c9s.Queue[*Game] 33 } 34 35 func (p Player) Key() uuid.UUID { return p.ID } 36 37 func (p Player) IsIdle(ts time.Time) bool { 38 return p.IdleAt.Before(ts) 39 } 40 41 func (p Player) IsTimedOut(ts time.Time) bool { 42 return p.TimedOutAt.Before(ts) 43 } 44 45 func (p Player) QueuedElapsedStats() (min, mean, max, p50, p75, p95 time.Duration) { 46 if len(p.QueuedElapsed) == 0 { 47 return 48 } 49 min, max = mathutil.MinMax(p.QueuedElapsed) 50 mean = mathutil.MeanDuration(p.QueuedElapsed) 51 slices.Sort(p.QueuedElapsed) 52 p50 = mathutil.PercentileSorted(p.QueuedElapsed, 50.0) 53 p75 = mathutil.PercentileSorted(p.QueuedElapsed, 75.0) 54 p95 = mathutil.PercentileSorted(p.QueuedElapsed, 95.0) 55 return 56 } 57 58 func (p Player) Winrate() float64 { 59 if p.Games == 0 { 60 return 0 61 } 62 return float64(p.Wins) / float64(p.Games) 63 } 64 65 func (p Player) WinrateRecent() float64 { 66 var wins, total int 67 p.Recent.ReverseEach(func(g *Game) { 68 playerTeam := g.PlayerTeam(p.ID) 69 total++ 70 if playerTeam == g.Outcome { 71 wins++ 72 } 73 }) 74 return float64(wins) / float64(total) 75 }