diff options
| author | historia <[not public]> | 2026-09-24 19:31:05 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-09-24 19:31:05 -0400 |
| commit | d114c747a7672c7e4daab3a5b5f1b2f066ebc912 (patch) | |
| tree | 81cc03354561f2f631d68f0de28bc742b1f49114 /internal/casino/blackjack_rules.go | |
| parent | f606db40c3290fd9ce40b53ef9bbe135b1e6f6e2 (diff) | |
| download | thehouseoficarus-d114c747a7672c7e4daab3a5b5f1b2f066ebc912.tar.gz | |
feat: additional baca and bj rules variants
Diffstat (limited to 'internal/casino/blackjack_rules.go')
| -rw-r--r-- | internal/casino/blackjack_rules.go | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/internal/casino/blackjack_rules.go b/internal/casino/blackjack_rules.go new file mode 100644 index 0000000..8bf63a8 --- /dev/null +++ b/internal/casino/blackjack_rules.go @@ -0,0 +1,66 @@ +package casino + +import ( + "fmt" + "strings" +) + +// BlackjackRulesText is the table's rule card, built from effective defaults. +// Keep fixed engine rules here too: players should not have to guess them. +func (c TableConfig) BlackjackRulesText() string { + c = c.Normalize() + b := c.Blackjack + yesNo := func(v bool) string { + if v { + return "Yes" + } + return "No" + } + dealer := "stands on" + if b.DealerHitsSoft17() { + dealer = "hits" + } + surrender := "Not offered" + if b.AllowsSurrender() { + surrender = "Late (original two-card hand only)" + } + split := "Identical ranks only" + if b.AllowsUnlikeTenSplit() { + split = "Identical ranks or any two ten-valued cards" + } + return strings.Join([]string{ + fmt.Sprintf("Blackjack table %s — rules", c.ID), + fmt.Sprintf("Number of decks: %d", b.Decks), + "Blackjack pays " + payoutRatio(b.BlackjackPayout), + "Dealer " + dealer + " soft 17", + "Dealer hole card / peek: Yes; blackjack checked before player actions (after insurance)", + "Ordinary wins pay 1:1; ties push; player and dealer blackjack push", + "Double down: Any initial two cards; one additional card only", + "Double after split: " + yesNo(b.AllowsDoubleAfterSplit()), + fmt.Sprintf("Maximum split hands: %d (including original hand)", b.MaxSplitHands), + "Re-splitting: " + yesNo(b.MaxSplitHands > 2) + " (within maximum hands)", + "Re-splitting aces: " + yesNo(b.AllowsResplitAces()) + " (within maximum hands)", + "Split pairs: " + split, + "Split aces: One card per ace; no hitting or doubling", + "Split-hand 21 pays 1:1, except the optional bonus below", + "Split-and-doubled 21 receives blackjack payout: " + yesNo(b.CountsDoubleSplitBlackjack()), + "Surrender: " + surrender, + "Insurance: Offered against an ace; costs half the original bet; pays " + payoutRatio(b.InsurancePayout), + "Fractional credits: Rounded down (including insurance stake and surrender return)", + fmt.Sprintf("Shuffle threshold: %g%% of shoe remaining; may shuffle earlier for round coverage", b.ShuffleAt*100), + "Shoe exhaustion: Reshuffle mid-round if necessary", + "Bet limits: " + betRangeText(c.MinBet, c.MaxBet) + " credits", + fmt.Sprintf("Seats: %d; betting window: %d ticks; action window: %d ticks", c.MaxPlayers, c.BettingTicks, b.ActionTicks), + }, "\n") +} + +func payoutRatio(p float64) string { + switch p { + case 1.5: + return "3:2" + case 1.2: + return "6:5" + default: + return fmt.Sprintf("%g:1", p) + } +} |
