aboutsummaryrefslogtreecommitdiff
path: root/internal/casino
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino')
-rw-r--r--internal/casino/craps_variants.go3
-rw-r--r--internal/casino/pai_gow.go24
-rw-r--r--internal/casino/table.go10
-rw-r--r--internal/casino/table_ux.go26
-rw-r--r--internal/casino/types.go2
-rw-r--r--internal/casino/video_poker.go19
6 files changed, 73 insertions, 11 deletions
diff --git a/internal/casino/craps_variants.go b/internal/casino/craps_variants.go
index 7d4d246..4818231 100644
--- a/internal/casino/craps_variants.go
+++ b/internal/casino/craps_variants.go
@@ -55,6 +55,9 @@ func (c CrapsConfig) title() string {
return "Bank Craps"
}
}
+
+// Title is the human-readable edition name shown by the look command.
+func (c CrapsConfig) Title() string { return c.title() }
func (c CrapsConfig) allows(kind string) bool {
switch c.variant() {
case "simplified", "high_point", "die_rich":
diff --git a/internal/casino/pai_gow.go b/internal/casino/pai_gow.go
index 21abf4b..17d8971 100644
--- a/internal/casino/pai_gow.go
+++ b/internal/casino/pai_gow.go
@@ -70,7 +70,21 @@ func (t *paiGowTable) hasParticipant(name string) bool {
func (t *paiGowTable) overview() string {
t.mu.Lock()
defer t.mu.Unlock()
- return fmt.Sprintf("%s | %s | %d/%d seats", t.Config.Label(), t.phase, len(t.players), t.Config.MaxPlayers)
+ return fmt.Sprintf("%s | %d/%d seated", t.Config.Label(), len(t.players), t.Config.MaxPlayers)
+}
+func (t *paiGowTable) seats() []string {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ names := make([]string, 0, len(t.players))
+ for _, p := range t.players {
+ names = append(names, p.name)
+ }
+ return names
+}
+func (t *paiGowTable) state() string {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ return t.phase
}
func (t *paiGowTable) hintsLocked(name string) []MenuCommand {
p := t.player(name)
@@ -145,7 +159,13 @@ func (t *paiGowTable) statusLocked(name string) []Event {
}
e := t.private(name, t.Config.Label())
e.Snapshot = s
- e.Menu = &MenuView{Heading: t.Config.Label() + " | " + t.phase, ShowBalance: true, Commands: t.hintsLocked(name)}
+ // Context-aware hints are attached as a live menu; the shared board
+ // renderer places them below the felt. Stand-ins (for example a watcher)
+ // get no menu, so they cannot be told how to bet a game they have not joined.
+ if commands := t.hintsLocked(name); len(commands) > 0 {
+ e.Color = "casino_menu"
+ e.Menu = &MenuView{Heading: t.Config.Label() + " | " + t.phase, ShowBalance: true, Commands: commands}
+ }
return []Event{e}
}
func (t *paiGowTable) status(name string) []Event {
diff --git a/internal/casino/table.go b/internal/casino/table.go
index 719bed3..88ffc62 100644
--- a/internal/casino/table.go
+++ b/internal/casino/table.go
@@ -21,6 +21,10 @@ type tableGame interface {
idle() bool
status(name string) []Event
overview() string
+ // seats and state expose the live occupancy and lifecycle phase for the
+ // look command's table-details view. They are read-only.
+ seats() []string
+ state() string
// wagers is the game's live list of bets the player could make right
// now (the "list" command's data; empty when nothing is worth naming,
// which also suppresses the "list" hint). hints is the full live hint
@@ -118,6 +122,12 @@ func (t *Table) idle() bool { return t.game.idle() }
func (t *Table) Status(name string) []Event { return t.game.status(name) }
func (t *Table) Overview() string { return t.game.overview() }
+// Seats lists the seated players in seat order for the look command.
+func (t *Table) Seats() []string { return t.game.seats() }
+
+// State is the table's live lifecycle phase for the look command.
+func (t *Table) State() string { return t.game.state() }
+
// RulesText is this table's full rule text (the "table rules" wording).
func (t *Table) RulesText() string { return rulesTextOnTable(t.Config) }
diff --git a/internal/casino/table_ux.go b/internal/casino/table_ux.go
index 55c491b..d0211f3 100644
--- a/internal/casino/table_ux.go
+++ b/internal/casino/table_ux.go
@@ -77,17 +77,27 @@ func (c *tableCore[P]) overview() string {
func (c *tableCore[P]) overviewLocked() string {
// Concise enough to sit beside a look minimap without wrapping into it.
- // The betting countdown lives in the menu heading and warning lines.
- return fmt.Sprintf("%s | Limits %s | %d/%d seated", c.Config.Label(), compactBetRange(c.Config.MinBet, c.Config.MaxBet), c.players.count(), c.Config.MaxPlayers)
+ // The betting countdown lives in the menu heading and warning lines; the
+ // wager range is shown in the betting menu and on the rule card instead.
+ return fmt.Sprintf("%s | %d/%d seated", c.Config.Label(), c.players.count(), c.Config.MaxPlayers)
}
-// compactBetRange renders the wager range in the short form used by the
-// one-line table overview (the verbose form stays in the betting menu).
-func compactBetRange(minBet, maxBet int) string {
- if maxBet == maxBetUnlimited {
- return fmt.Sprintf("%d+", minBet)
+// seats lists the seated players in seat order for the look details view.
+func (c *tableCore[P]) seats() []string {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ names := make([]string, 0, c.players.count())
+ for _, p := range c.players.ordered() {
+ names = append(names, p.participantPtr().Name)
}
- return fmt.Sprintf("%d-%d", minBet, maxBet)
+ return names
+}
+
+// state is the shared lifecycle phase for the look details view.
+func (c *tableCore[P]) state() string {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ return string(c.phase)
}
func (c *tableCore[P]) warning(name, text string) Event {
diff --git a/internal/casino/types.go b/internal/casino/types.go
index 1b0826a..9c000b5 100644
--- a/internal/casino/types.go
+++ b/internal/casino/types.go
@@ -14,7 +14,7 @@ func betRangeText(minBet, maxBet int) string {
type GameName string
const (
- GamePaiGow GameName = "pai_gow"
+ GamePaiGow GameName = "paigow"
GameVideoPoker GameName = "video_poker"
GameSlots GameName = "slots"
GameBlackjack GameName = "blackjack"
diff --git a/internal/casino/video_poker.go b/internal/casino/video_poker.go
index 8c9f66c..e5012f5 100644
--- a/internal/casino/video_poker.go
+++ b/internal/casino/video_poker.go
@@ -109,6 +109,25 @@ func (t *videoPokerTable) overview() string {
func (t *videoPokerTable) overviewLocked() string {
return t.settings.CabinetName() + " machine"
}
+func (t *videoPokerTable) seats() []string {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ names := make([]string, 0, len(t.players))
+ for name := range t.players {
+ names = append(names, name)
+ }
+ return names
+}
+func (t *videoPokerTable) state() string {
+ t.mu.Lock()
+ defer t.mu.Unlock()
+ for _, p := range t.players {
+ if p.active {
+ return "playing"
+ }
+ }
+ return "waiting"
+}
func (t *videoPokerTable) wagers(string) []WagerRow { return nil }
func (t *videoPokerTable) hints(name string) []MenuCommand {
t.mu.Lock()