diff options
| author | historia <[not public]> | 2026-10-03 00:51:41 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-10-03 00:51:41 -0400 |
| commit | 82e571d227feeafd0af4011e701ce26b99c5e3d9 (patch) | |
| tree | ab4d56ddf94c3bf3b42fff5dfc2ff9a339f09113 /internal/casino/craps_rules.go | |
| parent | cac16d1725c46c82a2e62b84c93f7090b2ce0746 (diff) | |
| download | thehouseoficarus-82e571d227feeafd0af4011e701ce26b99c5e3d9.tar.gz | |
fix: craps felt and wager description cleanup
Diffstat (limited to 'internal/casino/craps_rules.go')
| -rw-r--r-- | internal/casino/craps_rules.go | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/internal/casino/craps_rules.go b/internal/casino/craps_rules.go index a9e52af..60a7c0f 100644 --- a/internal/casino/craps_rules.go +++ b/internal/casino/craps_rules.go @@ -47,6 +47,36 @@ func crapsTrueOdds(n int) (int, int) { return 6, 5 } } + +// crapsVigUnit is the smallest stake whose true-odds profit AND 5% commission +// are both whole credits. Buy bets pay 5% of the stake, so 20 is the base; +// lay bets pay 5% of the profit, so the unit scales with the lay odds. +func crapsVigUnit(kind string, n int) int { + if kind == "buy" { + return 20 + } + num, den := crapsTrueOdds(n) + // Lay profit is stake*den/num; commission is stake*den/(20*num). + d := 20 * num + return d / gcd(den, d) +} + +func gcd(a, b int) int { + for b != 0 { + a, b = b, a%b + } + return a +} + +// roundUpTo returns the smallest multiple of unit that is at least n. A stake +// that misses the exact payout/commission unit is nudged up rather than +// rejected, since single-credit differences are noise at table stakes. +func roundUpTo(n, unit int) int { + if unit <= 1 { + return n + } + return ((n + unit - 1) / unit) * unit +} func (c CrapsConfig) oddsLimit(n int, against bool) int { if c.Odds > 0 { return c.Odds @@ -66,6 +96,15 @@ func (c CrapsConfig) oddsLimit(n int, against bool) int { return 5 } } + +// oddsDisplay is the felt label for the free-odds cap: a uniform Nx cap, or +// the classic 3-4-5x schedule when the config leaves Odds unset. +func (c CrapsConfig) oddsDisplay() string { + if c.Odds > 0 { + return fmt.Sprintf("%dx", c.Odds) + } + return "3x-4x-5x" +} func (c TableConfig) CrapsRulesText() string { r := c.Craps.Normalize() if r.variant() != "bank" && r.variant() != "diceless" { @@ -80,19 +119,19 @@ func (c TableConfig) CrapsRulesText() string { odds = fmt.Sprintf("%dx", r.Odds) } return prefix + fmt.Sprintf("Bank Craps | Free odds %s | Field 12 pays %d:1\n"+ - "bet <amount> on pass / dontpass / come / dontcome / field\n"+ - "bet <amount> on place 6 / buy 4 / lay 10 / hard 8 / hop 2 3\n"+ - "bet <amount> on seven / craps / eleven / ace-deuce / aces / boxcars / horn\n"+ - "bet <amount> on odds pass / odds come 6 (also dontpass/dontcome)\n"+ - "bet <amount> on fire / small / tall / all (before shooter's first roll only)\n"+ + "bet <n> on pass / dontpass / come / dontcome / field\n"+ + "bet <n> on place 6 / buy 4 / lay 10 / hard 8 / hop 2 3\n"+ + "bet <n> on seven / craps / eleven / ace-deuce / aces / boxcars / horn\n"+ + "bet <n> on odds pass / odds come 6 (also dontpass/dontcome)\n"+ + "bet <n> on fire / small / tall / all (before shooter's first roll only)\n"+ "Pass/come 1:1; don't bars 12. Place 4/10 9:5, 5/9 7:5, 6/8 7:6.\n"+ - "Buy/lay true odds; 5%% commission on buy STAKE / lay WIN, rounded up, wins only.\n"+ + "Buy/lay true odds; 5%% commission on buy STAKE / lay WIN, rounded down, wins only.\n"+ "Field 2 pays 2:1; 3/4/9/10/11 pay 1:1. Hard 4/10 7:1; 6/8 9:1.\n"+ "Seven 4:1; craps 7:1; 11/3 15:1; 2/12 30:1; hop easy 15:1, hard 30:1.\n"+ "Horn splits equally across 2/3/11/12. Fire: 4/5/6 distinct made points pay 24/249/999:1.\n"+ "Small (2-6) / Tall (8-12) pay 34:1; All pays 175:1. Any 7 resets ATS.\n"+ "Place/buy/hard and come odds are OFF on come-out; lay and don't odds work.\n"+ - "Exact payout units required; no fractional-credit rounding except commission.\n"+ + "Stakes round up to the next exact payout/vig unit; commission never rounds up.\n"+ "Solo: roll anytime. Multiplayer: 10 ticks to bet, then 60 ticks for the shooter.\n"+ "Bets remain open until the roll. Dice rotate on seven-out.\n"+ "autoroll: repeat every 3 ticks on your turn (multiplayer waits 10 ticks).\n"+ |
