aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/seats.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-08-07 05:02:39 -0400
committerhistoria <[not public]>2026-08-07 05:02:39 -0400
commit9a716a7d2ce514f452b425caedc1a9a15cde09f0 (patch)
treede980f16c4af93512a1616e6521275fd62aca542 /internal/casino/seats.go
parent0f008790f192a491ac3901d54b506b756f57fef8 (diff)
downloadthehouseoficarus-9a716a7d2ce514f452b425caedc1a9a15cde09f0.tar.gz
feat: disconnect forfeits bet and frees up seat
Diffstat (limited to 'internal/casino/seats.go')
-rw-r--r--internal/casino/seats.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/internal/casino/seats.go b/internal/casino/seats.go
new file mode 100644
index 0000000..6f44d6b
--- /dev/null
+++ b/internal/casino/seats.go
@@ -0,0 +1,83 @@
+package casino
+
+// seatedPlayer is implemented by every table-game player type; they all embed
+// Participant and expose it here so the seat set can manage shared state
+// (connection, wagers) without knowing game-specific fields.
+type seatedPlayer interface {
+ participantPtr() *Participant
+}
+
+// seatSet tracks the ordered occupants of a multiplayer table. It owns the
+// participant map and seat-order slice every table game used to maintain by
+// hand; game structs keep their own player type and delegate the plumbing.
+type seatSet[P seatedPlayer] struct {
+ order []string
+ players map[string]P
+}
+
+func newSeatSet[P seatedPlayer]() seatSet[P] {
+ return seatSet[P]{players: make(map[string]P)}
+}
+
+func (s *seatSet[P]) get(name string) P { return s.players[name] }
+
+func (s *seatSet[P]) has(name string) bool {
+ _, ok := s.players[name]
+ return ok
+}
+
+// count reports the number of seated players.
+func (s *seatSet[P]) count() int { return len(s.order) }
+
+// nameAt returns the player name at a seat index, or "" when out of range.
+func (s *seatSet[P]) nameAt(i int) string {
+ if i < 0 || i >= len(s.order) {
+ return ""
+ }
+ return s.order[i]
+}
+
+// indexOf returns the seat index of a player, or -1 when not seated.
+func (s *seatSet[P]) indexOf(name string) int {
+ for i, n := range s.order {
+ if n == name {
+ return i
+ }
+ }
+ return -1
+}
+
+func (s *seatSet[P]) add(name string, p P) {
+ s.players[name] = p
+ s.order = append(s.order, name)
+}
+
+func (s *seatSet[P]) remove(name string) {
+ delete(s.players, name)
+ for i, n := range s.order {
+ if n == name {
+ s.order = append(s.order[:i], s.order[i+1:]...)
+ break
+ }
+ }
+}
+
+// ordered lists the seated players in seat order.
+func (s *seatSet[P]) ordered() []P {
+ out := make([]P, 0, len(s.order))
+ for _, name := range s.order {
+ if p, ok := s.players[name]; ok {
+ out = append(out, p)
+ }
+ }
+ return out
+}
+
+// participants is the seat-ordered shared view used by the betting helpers.
+func (s *seatSet[P]) participants() []*Participant {
+ out := make([]*Participant, 0, len(s.order))
+ for _, p := range s.ordered() {
+ out = append(out, p.participantPtr())
+ }
+ return out
+}