aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/registry.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/registry.go')
-rw-r--r--internal/casino/registry.go66
1 files changed, 61 insertions, 5 deletions
diff --git a/internal/casino/registry.go b/internal/casino/registry.go
index c53fe53..049d9f1 100644
--- a/internal/casino/registry.go
+++ b/internal/casino/registry.go
@@ -6,11 +6,12 @@ import (
)
// tableGameDef is the single registration point for a multiplayer table game.
-// A game's validation, rule defaults, and constructor live together here, so
-// adding a game is one entry instead of edits to three independent switches
-// (TableConfig.Validate, TableConfig.Normalize, and newTable) that could
-// silently drift apart. The rule structs stay on TableConfig; this does not
-// introduce a config union.
+// A game's validation, rule defaults, constructor, help topic, and rule text
+// live together here, so adding a game is one entry instead of edits to
+// many independent switches (TableConfig.Validate, TableConfig.Normalize,
+// newTable, RulesText, and the presentation router) that could silently drift
+// apart. The rule structs stay on TableConfig; this does not introduce a
+// config union.
type tableGameDef struct {
// validate checks a raw (pre-Normalize) table config.
validate func(TableConfig) error
@@ -25,6 +26,12 @@ type tableGameDef struct {
// new builds the game. It is called only after validate passes and the
// shared table config has been normalized.
new func(roomID int, cfg TableConfig, rng *rand.Rand) tableGame
+ // ruleText names the shared rule text builder (TableConfig.RulesText
+ // dispatch, keeping the "rules" wording with the game's registration).
+ ruleText func(TableConfig) string
+ // helpTopic names the help page "rules" opens at this table. A game with
+ // per-edition pages derives them from its config (craps variants).
+ helpTopic func(TableConfig) string
}
// tableGames is populated in init, not in a var initializer: the constructors
@@ -40,6 +47,8 @@ func init() {
ruleBlockName: "craps",
hasRuleBlock: func(c TableConfig) bool { return c.Craps != (CrapsConfig{}) },
new: func(room int, c TableConfig, rng *rand.Rand) tableGame { return newCrapsTable(room, c, rng) },
+ ruleText: func(c TableConfig) string { return c.CrapsRulesText() },
+ helpTopic: func(c TableConfig) string { return c.Craps.helpTopic() },
},
GameRoulette: {
validate: func(c TableConfig) error {
@@ -60,6 +69,8 @@ func init() {
ruleBlockName: "roulette",
hasRuleBlock: func(c TableConfig) bool { return c.Roulette != (RouletteConfig{}) },
new: func(roomID int, cfg TableConfig, rng *rand.Rand) tableGame { return newRouletteTable(roomID, cfg, rng) },
+ ruleText: rouletteRulesText,
+ helpTopic: func(TableConfig) string { return "roulette" },
},
GameBlackjack: {
validate: validateBlackjackTable,
@@ -69,6 +80,8 @@ func init() {
new: func(roomID int, cfg TableConfig, rng *rand.Rand) tableGame {
return newBlackjackTable(roomID, cfg, rng)
},
+ ruleText: func(c TableConfig) string { return c.BlackjackRulesText() },
+ helpTopic: func(TableConfig) string { return "blackjack" },
},
GameBaccarat: {
validate: validateBaccaratTable,
@@ -78,6 +91,17 @@ func init() {
new: func(roomID int, cfg TableConfig, rng *rand.Rand) tableGame {
return newBaccaratTable(roomID, cfg, rng)
},
+ ruleText: func(c TableConfig) string { return c.BaccaratRulesText() },
+ helpTopic: func(c TableConfig) string {
+ switch c.Baccarat.Normalize().Variant {
+ case BaccaratSuper6:
+ return "super 6 baccarat"
+ case BaccaratEZ:
+ return "ez baccarat"
+ default:
+ return "baccarat"
+ }
+ },
},
}
}
@@ -97,3 +121,35 @@ func tableGameDefFor(game GameName) (tableGameDef, bool) {
var slotVariants = map[string]func() SlotProfile{
"huff_and_even_more_puff": DefaultHuffAndPuffProfile,
}
+
+// HelpTopic is the help page the "rules" command opens while seated at this
+// table: a variant's own short page where the game has one (Simplified Craps,
+// Super 6 …), the game's main page otherwise.
+func (c TableConfig) HelpTopic() string {
+ if def, ok := tableGameDefFor(c.Game); ok && def.helpTopic != nil {
+ return def.helpTopic(c)
+ }
+ return string(c.Game)
+}
+
+// rulesTextOnTable is the shared route from a table config to its rule text.
+func rulesTextOnTable(cfg TableConfig) string {
+ if def, ok := tableGameDefFor(cfg.Game); ok && def.ruleText != nil {
+ return def.ruleText(cfg)
+ }
+ return cfg.Label()
+}
+
+// rouletteRulesText is roulette's table rules text: the payout table is
+// drawn by the presentation layer (the payout reference needs the paying
+// game's felt), so the engine text covers the fixed odds and table facts.
+func rouletteRulesText(c TableConfig) string {
+ rules := c.Label() + "\nStraight numbers pay 35:1; splits 17:1; streets and trios 11:1; corners 8:1; lines 5:1.\n" +
+ "1to12/13to24/25to36 and rows 2:1; other outside bets 1:1; the American basket pays 6:1.\n" +
+ "Combos: bet 10 on split 1 2 | bet 10 on street 1 2 3 | bet 10 on corner 1 2 4 5 |\n" +
+ "bet 10 on line 1 2 3 4 5 6 | bet 10 on trio 0 1 2 | bet 10 on basket.\n"
+ if c.Roulette.Racetrack {
+ rules += "Racetrack (single zero): bet 10 on voisins | tiers | orphelins | jeu zero | neighbors 17.\n"
+ }
+ return rules + "Zero pockets lose all outside bets. One wager per spin. Use help roulette."
+}