diff --git a/astro/services/Pool.go b/astro/services/Pool.go index 73eeaf08579c72de36b3012ed85a9be245b82a40..a625b9b9c8a408d726899d602f0d192ef9b9490a 100644 --- a/astro/services/Pool.go +++ b/astro/services/Pool.go @@ -6,8 +6,18 @@ type Pool struct { PoolID uint8 // 255 pools max PoolState State PoolMaxSize uint16 - PoolPlayers []Player - PoolReferee Referee + PoolSize uint16 + PoolPlayers map[uint16]*Player + PoolReferee *Referee +} + +type PoolStage struct { + PoolStageID uint8 + PoolStageSize uint16 + PoolPlayers map[uint16]*Player + PoolStagePools map[uint8]*Pool + PoolStageState State + PoolEnteringPlayerNumber uint16 } func (p Pool) String() string { @@ -22,60 +32,261 @@ func (p Pool) String() string { return s } -func CreateStage(poolID uint8, poolMaxSize uint16) Pool { - var p Pool +func CreatePoolStage(poolStageID uint8, enteringPlayerNumber uint16, leavingPlayerNumber uint16) PoolStage { + var s PoolStage - p.PoolID = poolID - p.PoolState = IDLE - p.PoolMaxSize = poolMaxSize - p.PoolPlayers = make([]Player, poolMaxSize) - p.PoolReferee = Referee{} + s.PoolStageID = poolStageID + s.PoolEnteringPlayerNumber = enteringPlayerNumber + s.PoolPlayers = make(map[uint16]*Player) + s.PoolStagePools = make(map[uint8]*Pool) + s.PoolStageState = IDLE + s.PoolStageSize = 0 - return p + return s } -func (p Pool) PlayerPosition(player Player) uint16 { - for i, poolPlayer := range p.PoolPlayers { - if poolPlayer.PlayerID == player.PlayerID { - return uint16(i) +// From interface +func (p *PoolStage) PlayerPosition(player *Player) uint16 { + for _, pool := range p.PoolStagePools { + if pool.PlayerPosition(player) != math.MaxInt16 { + return pool.PlayerPosition(player) } } return math.MaxInt16 } -func (p *Pool) AddPlayer(player Player) bool { - if p.PoolState != IDLE { +// From interface +func (p *PoolStage) AddPlayer(player *Player) bool { + if p.PoolStageState != REGISTERING { return false } - if len(p.PoolPlayers) >= int(p.PoolMaxSize) { + if p.PlayerPosition(player) != math.MaxInt16 { + return false + } + + for _, pool := range p.PoolStagePools { + if pool.AddPlayer(player) { + p.PoolPlayers[player.PlayerID] = player + p.PoolStageSize++ + + pool.PoolSize++ + return true + } + } + + // Add pool + pool := &Pool{ + PoolID: uint8(len(p.PoolStagePools)), + PoolState: REGISTERING, + PoolMaxSize: 7, + PoolSize: 0, + PoolPlayers: make(map[uint16]*Player), + PoolReferee: nil, + } + + pool.AddPlayer(player) + + p.AddPool(pool) + p.PoolPlayers[player.PlayerID] = player + + return true +} + +// From interface +func (p *PoolStage) RemovePlayer(player *Player) bool { + if p.PoolStageState != REGISTERING { return false } if p.PlayerPosition(player) == math.MaxInt16 { - p.PoolPlayers = append(p.PoolPlayers, player) - return true + return false + } + + for _, pool := range p.PoolStagePools { + if pool.RemovePlayer(player) { + delete(p.PoolPlayers, player.PlayerID) + p.PoolStageSize-- + + pool.PoolSize-- + + if pool.PoolSize == 0 { + p.RemovePool(pool) + } + + return true + } } return false } -func (p *Pool) RemovePlayer(player Player) bool { - if p.PoolState != IDLE { +// From interface +func (p *PoolStage) GetID() uint8 { + return p.PoolStageID +} + +// From interface +func (p *PoolStage) GetState() State { + return p.PoolStageState +} + +// From interface +func (p *PoolStage) GetPlayers() []*Player { + players := []*Player{} + + for _, player := range p.PoolPlayers { + players = append(players, player) + } + + return players +} + +// From interface +func (p *PoolStage) Register() bool { + if p.PoolStageState != IDLE { return false } - pos := p.PlayerPosition(player) + p.PoolStageState = REGISTERING + + return true +} + +// From interface +func (p *PoolStage) Start() bool { + if p.PoolStageState != REGISTERING { + return false + } - if pos != math.MaxInt16 { - p.PoolPlayers = append(p.PoolPlayers[:pos], p.PoolPlayers[pos+1:]...) - return true + if p.PoolStageSize < p.PoolEnteringPlayerNumber { + return false } + p.PoolStageState = STARTED + + return true +} + +// From interface +func (p *PoolStage) End() bool { + if p.PoolStageState != STARTED { + return false + } + + p.PoolStageState = FINISHED + + return true +} + +// From interface +func (p *PoolStage) Lock() bool { + if p.PoolStageState != FINISHED { + return false + } + + p.PoolStageState = LOCKED + + return true +} + +// From interface +func (p *PoolStage) Build() bool { + // TODO: Implement return false } -func (p *Pool) SetReferee(referee Referee) { +func (p *PoolStage) AddPool(pool *Pool) bool { + if p.PoolStageState != REGISTERING { + return false + } + + if pool == nil { + return false + } + + p.PoolStagePools[pool.PoolID] = pool + + return true +} + +func (p *PoolStage) RemovePool(pool *Pool) bool { + if p.PoolStageState != REGISTERING { + return false + } + + if pool == nil { + return false + } + + if pool.PoolSize > 0 { + return false + } + + delete(p.PoolStagePools, pool.PoolID) + + return true +} + +func (p *PoolStage) GetPool(poolID uint8) *Pool { + pool, ok := p.PoolStagePools[poolID] + if ok { + return pool + } + + return nil +} + +// ------------------------------ Pool ------------------------------ +func (p Pool) PlayerPosition(player *Player) uint16 { + _, ok := p.PoolPlayers[player.PlayerID] + if ok { + return p.PoolPlayers[player.PlayerID].PlayerID + } + + return math.MaxInt16 +} + +func (p *Pool) AddPlayer(player *Player) bool { + if p.PoolState != REGISTERING { + return false + } + + if p.PoolSize >= p.PoolMaxSize { + return false + } + + if p.PlayerPosition(player) != math.MaxInt16 { + return false + } + + p.PoolPlayers[p.PoolSize] = player + p.PoolSize++ + + return true +} + +func (p *Pool) RemovePlayer(player *Player) bool { + if p.PoolState != REGISTERING { + return false + } + + if p.PlayerPosition(player) == math.MaxInt16 { + return false + } + + delete(p.PoolPlayers, player.PlayerID) + + return true +} + +func (p *Pool) SetReferee(referee *Referee) bool { + if p.PoolState != REGISTERING { + return false + } + p.PoolReferee = referee + + return true } diff --git a/astro/services/Seeding.go b/astro/services/Seeding.go new file mode 100644 index 0000000000000000000000000000000000000000..d1b7815f0366508dab29f1805f78da8f1a3ef75f --- /dev/null +++ b/astro/services/Seeding.go @@ -0,0 +1,163 @@ +package services + +// Seeding : Seeding details +type Seeding struct { + SeedingPosition uint16 + SeedingPlayer *Player +} + +type SeedingStage struct { + SeedingStageID uint8 + SeedingSize uint16 + SeedingSeedings map[uint16]*Seeding + SeedingState State + SeedingEnteringPlayerNumber uint16 +} + +func (s *SeedingStage) String() string { + var str string + + str = string(s.SeedingStageID) + " - " + s.SeedingState.String() + + for _, seeding := range s.SeedingSeedings { + str = str + "\n" + seeding.SeedingPlayer.String() + } + + return str +} + +func CreateSeedingStage(seedingStageID uint8, enteringPlayerNumber uint16, leavingPlayerNumber uint16) SeedingStage { + var s SeedingStage + + s.SeedingStageID = seedingStageID + s.SeedingEnteringPlayerNumber = enteringPlayerNumber + s.SeedingSeedings = make(map[uint16]*Seeding) + s.SeedingState = IDLE + s.SeedingSize = 0 + + return s +} + +// From interface +func (s *SeedingStage) PlayerPosition(player Player) uint16 { + return s.SeedingSeedings[player.PlayerID].SeedingPosition +} + +// From interface +func (s *SeedingStage) AddPlayer(player Player) bool { + if s.SeedingState != REGISTERING { + return false + } + + if s.SeedingSeedings[player.PlayerID] != nil { + return false + } + + s.SeedingSeedings[player.PlayerID] = &Seeding{ + SeedingPosition: s.SeedingSize, + SeedingPlayer: &player, + } + + s.SeedingSize++ + + return true +} + +// From interface +func (s *SeedingStage) RemovePlayer(player Player) bool { + if s.SeedingState != REGISTERING { + return false + } + + if s.SeedingSeedings[player.PlayerID] == nil { + return false + } + + delete(s.SeedingSeedings, player.PlayerID) + + s.SeedingSize-- + + return true +} + +// From interface +func (s *SeedingStage) GetID() uint8 { + return s.SeedingStageID +} + +// From interface +func (s *SeedingStage) GetState() State { + return s.SeedingState +} + +// From interface +func (s *SeedingStage) GetPlayers() []Player { + players := []Player{} + + for _, seeding := range s.SeedingSeedings { + players = append(players, *seeding.SeedingPlayer) + } + + return players +} + +// From interface +func (s *SeedingStage) Register() bool { + if s.SeedingState != IDLE { + return false + } + + s.SeedingState = REGISTERING + + return true +} + +// From interface +func (s *SeedingStage) Start() bool { + if s.SeedingState != REGISTERING { + return false + } + + if s.SeedingSize != s.SeedingEnteringPlayerNumber { + return false + } + + s.SeedingState = STARTED + + return true +} + +// From interface +func (s *SeedingStage) End() bool { + if s.SeedingState != STARTED { + return false + } + + s.SeedingState = FINISHED + + return true +} + +// From interface +func (s *SeedingStage) Lock() bool { + if s.SeedingState != FINISHED { + return false + } + + s.SeedingState = LOCKED + + return true +} + +// From interface +func (s *SeedingStage) Build() bool { + if s.SeedingState != REGISTERING { + return false + } + + if s.SeedingSize != s.SeedingEnteringPlayerNumber { + return false + } + + return true +} diff --git a/astro/services/Stage.go b/astro/services/Stage.go index 13601244637b9ac12b65115f136b3ffcef48fd93..0be18200824ee8acee6dc19080f1e39643442fd4 100644 --- a/astro/services/Stage.go +++ b/astro/services/Stage.go @@ -2,9 +2,15 @@ package services // Stage : Stage details type Stage interface { - CreateStage(stageID uint8, stageMaxSize uint16) Stage PlayerPosition(player Player) uint16 AddPlayer(player Player) bool RemovePlayer(player Player) bool GetID() uint8 + GetState() State + GetPlayers() []Player + Register() bool + Start() bool + End() bool + Lock() bool + Build() bool } diff --git a/astro/services/Util.go b/astro/services/Util.go index b357fed01a2e3ac93a318a74d6dd006b4608f1f6..91d12d8408f9e12c529cc84689376e4b5ebf225f 100644 --- a/astro/services/Util.go +++ b/astro/services/Util.go @@ -107,7 +107,8 @@ const ( REGISTERING State = iota // 0 STARTED // 1 FINISHED // 2 - IDLE // 3 + LOCKED // 3 + IDLE // 4 ) func (s State) String() string { @@ -118,6 +119,8 @@ func (s State) String() string { return "Started" case FINISHED: return "Finished" + case LOCKED: + return "Locked" case IDLE: return "Idle" default: