go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/experiments/matchmaker/pkg/sim/simple_mm.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  	"math/rand"
    12  
    13  	c9s "go.charczuk.com/sdk/collections"
    14  )
    15  
    16  var _ Matchmaker = (*SimpleMatchmaker)(nil)
    17  
    18  // SimpleMatchmaker randomly assigns players once
    19  // there are enough players to fill both teams.
    20  //
    21  // This can be used as a "control" for how effective more
    22  // sophisticated mm algorithms might work.
    23  type SimpleMatchmaker struct {
    24  	q *c9s.Queue[*Player]
    25  }
    26  
    27  func (sm *SimpleMatchmaker) Init(_ *rand.Rand) {
    28  	sm.q = new(c9s.Queue[*Player])
    29  }
    30  
    31  func (sm *SimpleMatchmaker) Queue(players ...*Player) {
    32  	for _, p := range players {
    33  		sm.q.Push(p)
    34  	}
    35  }
    36  
    37  func (sm *SimpleMatchmaker) QueueLen() int {
    38  	return sm.q.Len()
    39  }
    40  
    41  func (sm *SimpleMatchmaker) FormGames(cfg MatchmakerConfig) (out []MatchmakerGame) {
    42  	playersPerGame := cfg.TeamSize * 2
    43  	if sm.q.Len() < playersPerGame {
    44  		return
    45  	}
    46  	if cfg.MaxGames == 0 {
    47  		return
    48  	}
    49  	for sm.q.Len() >= playersPerGame && len(out) < cfg.MaxGames {
    50  		var g MatchmakerGame
    51  		var alt bool
    52  		for x := 0; x < playersPerGame; x++ {
    53  			p, _ := sm.q.Pop()
    54  			if alt {
    55  				g.TeamA = append(g.TeamA, p)
    56  			} else {
    57  				g.TeamB = append(g.TeamB, p)
    58  			}
    59  			alt = !alt
    60  		}
    61  		out = append(out, g)
    62  	}
    63  	return
    64  }