From a5b9c1052c4640ba519e608e0c97e603ce6aa5ef Mon Sep 17 00:00:00 2001 From: historia <[not public]> Date: Wed, 30 Sep 2026 18:57:30 -0400 Subject: feat: blackjack and baccarat rules felt added, casino layout simplified --- internal/casino/baccarat.go | 6 +++++- internal/casino/baccarat_variants_test.go | 13 +++++++++++-- internal/casino/blackjack.go | 6 +++++- internal/casino/blackjack_rules_test.go | 4 ++-- internal/casino/types.go | 16 ++++++++++++++++ 5 files changed, 39 insertions(+), 6 deletions(-) (limited to 'internal/casino') diff --git a/internal/casino/baccarat.go b/internal/casino/baccarat.go index 0890d59..50ac111 100644 --- a/internal/casino/baccarat.go +++ b/internal/casino/baccarat.go @@ -72,7 +72,11 @@ func (t *baccaratTable) join(name string) []Event { return []Event{t.private(name, "That baccarat table is full.")} } events := []Event{t.addSeatLocked(name, &baccaratPlayer{Participant: Participant{Name: name, Connected: true}})} - events = append(events, t.private(name, t.Config.BaccaratRulesText()), t.menuEvent(name)) + // The rules board is a rendered felt (presentation layer); the engine + // only ships the configuration. + rules := t.private(name, "") + rules.Snapshot = &BaccaratRulesView{Config: t.Config} + events = append(events, rules, t.menuEvent(name)) return events } diff --git a/internal/casino/baccarat_variants_test.go b/internal/casino/baccarat_variants_test.go index 4f88227..094412e 100644 --- a/internal/casino/baccarat_variants_test.go +++ b/internal/casino/baccarat_variants_test.go @@ -89,8 +89,17 @@ func TestBaccaratEZLiveSettlementAndOptionalMenus(t *testing.T) { cfg := TableConfig{ID: "ez", Game: GameBaccarat, Baccarat: BaccaratConfig{Variant: BaccaratEZ, Dragon7: true}} table := newBaccaratTestTable(cfg) events := table.join("alice") - if !hasMessage(events, "Variant: EZ Baccarat") || !hasMessage(events, "dragon_7") { - t.Fatal("join missing rules/optional wager") + rulesView := false + for _, e := range events { + if view, ok := e.Snapshot.(*BaccaratRulesView); ok { + rulesView = true + if !view.Config.Baccarat.Dragon7 { + t.Fatal("rules felt missing the enabled Dragon 7 wager") + } + } + } + if !rulesView { + t.Fatal("join missing rules felt") } table.join("bob") forceShoe(table, baccaratCards("A A A A 2 5")...) diff --git a/internal/casino/blackjack.go b/internal/casino/blackjack.go index 53bee6c..bd5b86b 100644 --- a/internal/casino/blackjack.go +++ b/internal/casino/blackjack.go @@ -139,7 +139,11 @@ func (t *blackjackTable) join(name string) []Event { return []Event{t.private(name, "That blackjack table is full.")} } events := []Event{t.addSeatLocked(name, &blackjackPlayer{Participant: Participant{Name: name, Connected: true}})} - events = append(events, t.private(name, t.Config.BlackjackRulesText()), t.menuEvent(name)) + // The rules board is a rendered felt (presentation layer); the engine + // only ships the configuration. + rules := t.private(name, "") + rules.Snapshot = &BlackjackRulesView{Config: t.Config} + events = append(events, rules, t.menuEvent(name)) return events } diff --git a/internal/casino/blackjack_rules_test.go b/internal/casino/blackjack_rules_test.go index 62f4d0a..b0c9459 100644 --- a/internal/casino/blackjack_rules_test.go +++ b/internal/casino/blackjack_rules_test.go @@ -27,7 +27,7 @@ func TestBlackjackRuleCardDefaultsAndOverrides(t *testing.T) { events := table.join("alice") found := false for _, e := range events { - if e.Message == text { + if view, ok := e.Snapshot.(*BlackjackRulesView); ok && view.Config.Blackjack == table.Config.Blackjack { found = true if e.Public { t.Error("rules broadcast to bystanders") @@ -35,7 +35,7 @@ func TestBlackjackRuleCardDefaultsAndOverrides(t *testing.T) { } } if !found { - t.Fatal("joining did not display effective rules") + t.Fatal("joining did not ship the rules view") } } } diff --git a/internal/casino/types.go b/internal/casino/types.go index 62a8f34..ecded85 100644 --- a/internal/casino/types.go +++ b/internal/casino/types.go @@ -323,6 +323,14 @@ type BlackjackSnapshot struct { func (*BlackjackSnapshot) snapshot() {} +// BlackjackRulesView ships a table's configuration so the presentation layer +// can draw the house-rule felt instead of a raw rules dump. +type BlackjackRulesView struct { + Config TableConfig +} + +func (*BlackjackRulesView) snapshot() {} + // BaccaratBetView lists one participant's wager on a baccarat outcome. type BaccaratBetView struct { Name string @@ -340,6 +348,14 @@ type BaccaratSnapshot struct { func (*BaccaratSnapshot) snapshot() {} +// BaccaratRulesView ships a table's configuration so the presentation layer +// can draw the house-rule felt instead of a raw rules dump. +type BaccaratRulesView struct { + Config TableConfig +} + +func (*BaccaratRulesView) snapshot() {} + type Participant struct { Name string Connected bool -- cgit v1.2.3