package casino import ( "math/rand" ) // tableGame is a multiplayer table game implementation. Table routes every // player interaction through this interface so new games plug in without // changing the dispatch layer. type tableGame interface { join(name string) []Event leave(name string) []Event bet(name, spot string, amount int, wallet Wallet) []Event tick() []Event action(name, action string) []Event rebet(name string) (spot string, amount int) markDisconnected(name string) []Event hasParticipant(name string) bool } // tableBase carries the identity every table game needs to build events. type tableBase struct { RoomID int Config TableConfig } func (b tableBase) event(message string, public bool) Event { return Event{RoomID: b.RoomID, TableID: b.Config.ID, Type: EventResult, Message: message, Public: public, Color: "casino_action"} } func (b tableBase) private(name, message string) Event { e := b.event(message, false) e.PrivateTo = name return e } func (b tableBase) playerAction(name, publicMessage, privateMessage string) Event { e := b.event(publicMessage, true) e.PrivateTo = name e.PrivateMessage = privateMessage return e } // Table is the manager-facing handle for a multiplayer table. It only holds // routing state; all game logic lives in the tableGame implementation. type Table struct { RoomID int Config TableConfig game tableGame } // newTable builds the table game for cfg.Game, or nil when the game has no // multiplayer table implementation. func newTable(roomID int, cfg TableConfig, rng *rand.Rand) *Table { cfg = cfg.Normalize() t := &Table{RoomID: roomID, Config: cfg} switch cfg.Game { case GameBlackjack: t.game = newBlackjackTable(roomID, cfg, rng) case GameBaccarat: t.game = newBaccaratTable(roomID, cfg, rng) default: return nil } return t } func (t *Table) join(name string) []Event { return t.game.join(name) } func (t *Table) leave(name string) []Event { return t.game.leave(name) } func (t *Table) bet(name, spot string, amount int, wallet Wallet) []Event { return t.game.bet(name, spot, amount, wallet) } func (t *Table) tick() []Event { return t.game.tick() } func (t *Table) action(name, action string) []Event { return t.game.action(name, action) } func (t *Table) rebet(name string) (string, int) { return t.game.rebet(name) } func (t *Table) markDisconnected(name string) []Event { return t.game.markDisconnected(name) } func (t *Table) hasParticipant(name string) bool { return t.game.hasParticipant(name) }