diff options
Diffstat (limited to 'internal/casino/table.go')
| -rw-r--r-- | internal/casino/table.go | 115 |
1 files changed, 68 insertions, 47 deletions
diff --git a/internal/casino/table.go b/internal/casino/table.go index 1b9d0b5..e993cb8 100644 --- a/internal/casino/table.go +++ b/internal/casino/table.go @@ -21,22 +21,39 @@ type Table struct { participants map[string]*Participant order []string phase tablePhase - deadline int - clock int + timer countdown rng *rand.Rand + blackjack *blackjackTable } func newTable(roomID int, cfg TableConfig, rng *rand.Rand) *Table { - return &Table{ + t := &Table{ RoomID: roomID, Config: cfg, phase: phaseWaiting, participants: make(map[string]*Participant), rng: rng, } + if cfg.Game == GameBlackjack { + t.blackjack = newBlackjackTable(roomID, cfg, rng) + } + return t +} + +func (t *Table) seats() []*Participant { + seats := make([]*Participant, 0, len(t.order)) + for _, name := range t.order { + if p := t.participants[name]; p != nil { + seats = append(seats, p) + } + } + return seats } func (t *Table) join(name string) []Event { + if t.blackjack != nil { + return t.blackjack.join(name) + } t.mu.Lock() defer t.mu.Unlock() if p := t.participants[name]; p != nil { @@ -52,6 +69,9 @@ func (t *Table) join(name string) []Event { } func (t *Table) leave(name string) []Event { + if t.blackjack != nil { + return t.blackjack.leave(name) + } t.mu.Lock() defer t.mu.Unlock() p := t.participants[name] @@ -76,6 +96,9 @@ func (t *Table) leave(name string) []Event { } func (t *Table) bet(name string, amount int, wallet Wallet) []Event { + if t.blackjack != nil { + return t.blackjack.bet(name, amount, wallet) + } t.mu.Lock() defer t.mu.Unlock() p := t.participants[name] @@ -85,12 +108,12 @@ func (t *Table) bet(name string, amount int, wallet Wallet) []Event { if t.phase != phaseWaiting && t.phase != phaseBetting { return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, Player: name, PrivateTo: name, Message: "That table isn't accepting bets."}} } - if amount < t.Config.MinBet || amount > t.Config.MaxBet { - return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, Player: name, PrivateTo: name, Message: fmt.Sprintf("Bets must be between %d and %d.", t.Config.MinBet, t.Config.MaxBet)}} - } if p.HasBet { return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, Player: name, PrivateTo: name, Message: "You have already bet this round."}} } + if amount < t.Config.MinBet || amount > t.Config.MaxBet { + return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, Player: name, PrivateTo: name, Message: fmt.Sprintf("Bets must be between %d and %d.", t.Config.MinBet, t.Config.MaxBet)}} + } wager, ok := wallet.Wager(amount) if !ok { return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, Player: name, PrivateTo: name, Message: "You don't have enough chips and credits for that bet."}} @@ -100,40 +123,39 @@ func (t *Table) bet(name string, amount int, wallet Wallet) []Event { p.Wallet = wallet if t.phase == phaseWaiting && len(t.participants) > 1 { t.phase = phaseBetting - t.clock = 0 - t.deadline = t.Config.BettingTicks + t.timer.start(t.Config.BettingTicks) } events := []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventBetPlaced, Player: name, Message: fmt.Sprintf("%s bets %d credits at the %s table.", name, amount, t.Config.ID), Public: true}} - if t.phase == phaseBetting && t.clock == 0 { - events = append(events, Event{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventBetting, Message: fmt.Sprintf("Betting is open at the %s table for %d ticks.", t.Config.ID, t.deadline), Public: true}) + if t.phase == phaseBetting && t.timer.clock == 0 { + events = append(events, Event{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventBetting, Message: fmt.Sprintf("Betting is open at the %s table for %d ticks.", t.Config.ID, t.Config.BettingTicks), Public: true}) } - if len(t.participants) == 1 || t.allBet() { + if len(t.participants) == 1 || allBet(t.seats()) { events = append(events, t.resolveRound()...) } return events } func (t *Table) tick() []Event { + if t.blackjack != nil { + return t.blackjack.tick() + } t.mu.Lock() defer t.mu.Unlock() if t.phase != phaseBetting { return nil } - t.clock++ - if t.allBet() { + t.timer.tick() + if allBet(t.seats()) { return t.resolveRound() } - if t.clock < t.deadline { + if !t.timer.expired() { return nil } var events []Event - for _, name := range t.order { - p := t.participants[name] - if p != nil && !p.HasBet { - events = append(events, Event{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventTimedOut, Player: name, Message: fmt.Sprintf("%s sits out this round.", name), Public: true}) - } + for _, name := range sitOutNames(t.seats()) { + events = append(events, Event{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventTimedOut, Player: name, Message: fmt.Sprintf("%s sits out this round.", name), Public: true}) } - if t.anyBet() { + if anyBet(t.seats()) { events = append(events, t.resolveRound()...) } else { t.resetRound() @@ -164,36 +186,14 @@ func (t *Table) resolveRound() []Event { func (t *Table) resetRound() { t.phase = phaseWaiting - t.clock = 0 - t.deadline = 0 - for _, p := range t.participants { - p.HasBet = false - p.Wager = Wager{} - } -} - -func (t *Table) allBet() bool { - if len(t.participants) == 0 { - return false - } - for _, p := range t.participants { - if !p.HasBet { - return false - } - } - return true -} - -func (t *Table) anyBet() bool { - for _, p := range t.participants { - if p.HasBet { - return true - } - } - return false + t.timer.stop() + clearBets(t.seats()) } func (t *Table) markDisconnected(name string) []Event { + if t.blackjack != nil { + return t.blackjack.markDisconnected(name) + } t.mu.Lock() defer t.mu.Unlock() if p := t.participants[name]; p != nil { @@ -203,6 +203,10 @@ func (t *Table) markDisconnected(name string) []Event { } func (t *Table) markConnected(name string) { + if t.blackjack != nil { + t.blackjack.markConnected(name) + return + } t.mu.Lock() defer t.mu.Unlock() if p := t.participants[name]; p != nil { @@ -211,7 +215,24 @@ func (t *Table) markConnected(name string) { } func (t *Table) hasParticipant(name string) bool { + if t.blackjack != nil { + return t.blackjack.hasParticipant(name) + } t.mu.Lock() defer t.mu.Unlock() return t.participants[name] != nil } + +func (t *Table) action(name, action string) []Event { + if t.blackjack == nil { + return []Event{{RoomID: t.RoomID, TableID: t.Config.ID, Type: EventResult, PrivateTo: name, Message: "That game has no player actions."}} + } + return t.blackjack.action(name, action) +} + +func (t *Table) rebetAmount(name string) int { + if t.blackjack != nil { + return t.blackjack.rebetAmount(name) + } + return t.Config.MinBet +} |
