aboutsummaryrefslogtreecommitdiff
path: root/internal/casino/craps_wagers.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/casino/craps_wagers.go')
-rw-r--r--internal/casino/craps_wagers.go124
1 files changed, 65 insertions, 59 deletions
diff --git a/internal/casino/craps_wagers.go b/internal/casino/craps_wagers.go
index d9af87f..1c6da2f 100644
--- a/internal/casino/craps_wagers.go
+++ b/internal/casino/craps_wagers.go
@@ -2,15 +2,13 @@ package casino
import (
"fmt"
+ "strings"
)
-// Craps wager tables are built from the live table state: a come-out roll
-// offers the line bets, the one-roll props and (before the shooter's first
-// roll) the bonus bets; a point adds come, odds, place/buy/lay and the
-// hardways. The variants substitute their own single-bet lists. Every entry
-// pairs the bet wording with its payout and a one-line win condition, so the
-// list doubles as the game's brief rule reminder. Payouts are profit odds;
-// winning stakes return alongside the profit.
+// Craps wager tables are built from the live table state. Rows are grouped
+// where two bets share the same payout (pass/don't pass, the place numbers,
+// all free odds) so the list stays compact and the Win/action column rarely
+// wraps. Payouts are profit odds; winning stakes return alongside the profit.
func (t *crapsTable) wagerRows(name string) []WagerRow {
c := t.Config.Craps
rows := []WagerRow{}
@@ -18,31 +16,30 @@ func (t *crapsTable) wagerRows(name string) []WagerRow {
case "simplified":
// One automatic roll of two dice; pass is the only target.
rows = append(rows,
- WagerRow{"pass", "up to 5:1", "One roll: 2 pays 3:1; 3/4 pay 1:1; 10/11 pay 2:1; 12 pays 5:1; 5-9 lose"},
+ WagerRow{"pass", "up to 5:1", "One roll: 2 pays 3:1; 3/4 1:1; 10/11 2:1; 12 5:1; 5-9 lose"},
)
case "high_point":
rows = append(rows,
- WagerRow{"pass", "1:1", "Come-out 2/3 rolls again, 11/12 win; 4-10 make a point the next roll must EXCEED"},
+ WagerRow{"pass", "1:1", "2/3 roll again; 11/12 win; 4-10 must be beaten next roll"},
)
case "die_rich":
rows = append(rows,
- WagerRow{"pass", "1:1", "One die: come-out 6 wins, 1 loses; 2-5 make a point repeated before a 1"},
+ WagerRow{"pass", "1:1", "6 wins; 1 loses; 2-5 must repeat before a 1"},
)
case "new_york":
rows = append(rows,
- WagerRow{"pass", "1:1", "Come-out 7/11 wins; 2/3/12 loses; else the point repeats before a 7"},
+ WagerRow{"pass", "1:1", "7/11 win, 2/3/12 lose; opposite bars 12"},
WagerRow{"dontpass", "1:1", "Opposite side; come-out 12 pushes"},
)
if t.point != 0 {
rows = append(rows, crapsOddsRows(c)...)
rows = append(rows,
- WagerRow{"buy <n>", "true odds", "True-odds bet on 4/5/6/8/9/10; 5% stake commission, wins only"},
- WagerRow{"lay <n>", "true odds laid", "Bet AGAINST the number; 5% commission on winnings"},
+ WagerRow{"buy / lay <n>", "true", "4/5/6/8/9/10; 5% win commission"},
)
}
case "crapless":
rows = append(rows,
- WagerRow{"pass", "1:1", "Come-out only 7 wins; every other total becomes the point"},
+ WagerRow{"pass", "1:1", "Come-out 7 wins; every other total makes the point"},
)
if t.point != 0 {
rows = append(rows,
@@ -51,94 +48,103 @@ func (t *crapsTable) wagerRows(name string) []WagerRow {
rows = append(rows, crapsOddsRows(c)...)
rows = append(rows, crapsPlaceRows(c)...)
rows = append(rows,
- WagerRow{"buy <n>", "true odds", "True-odds place bet; 5% stake commission, wins only"},
- WagerRow{"lay <n>", "true odds laid", "Bet against the number; 5% commission on winnings"},
- WagerRow{"field", fmt.Sprintf("12 pays %d:1", c.Field12), "One roll: 2 pays 2:1; 3/4/9/10/11 pay 1:1; 5/6/7/8 lose"},
- WagerRow{"hard 4 / hard 10", "7:1", "The point arrives as an identical pair"},
- WagerRow{"hard 6 / hard 8", "9:1", "The point arrives as an identical pair"},
- WagerRow{"seven", "4:1", "Next roll totals 7"},
- WagerRow{"craps", "7:1", "Next roll is 2, 3 or 12"},
- WagerRow{"eleven / ace-deuce", "15:1", "Next roll totals 11 / 3"},
- WagerRow{"aces / boxcars", "30:1", "Next roll is 2 / 12"},
- WagerRow{"horn", "varies", "Splits the stake equally among 2/3/11/12"},
- WagerRow{"hop <a> <b>", "15:1/30:1", "One-roll dice combination; 30:1 when both dice equal"},
+ WagerRow{"buy / lay <n>", "true", "Place at true odds; 5% win commission"},
+ WagerRow{"hard 4/10", "7:1", "Point arrives as an identical pair"},
+ WagerRow{"hard 6/8", "9:1", "Point arrives as an identical pair"},
)
- } else {
- rows = append(rows, crapsComeOutRows(c, t.rolled)...)
}
+ rows = append(rows, crapsPropRows(c, false)...)
default: // bank and diceless
rows = append(rows,
- WagerRow{"pass", "1:1", "Come-out 7/11 wins; 2/3/12 loses; else the point repeats before a 7"},
+ WagerRow{"pass", "1:1", "7/11 win, 2/3/12 lose; opposite bars 12"},
WagerRow{"dontpass", "1:1", "Opposite side; come-out 12 pushes"},
)
if t.point != 0 {
rows = append(rows,
WagerRow{"come", "1:1", "A personal point with pass rules"},
- WagerRow{"dontcome", "1:1", "Don't come, same as don't pass; a 12 pushes"},
+ WagerRow{"dontcome", "1:1", "Don't come; a 12 pushes"},
)
rows = append(rows, crapsOddsRows(c)...)
rows = append(rows, crapsPlaceRows(c)...)
rows = append(rows,
- WagerRow{"buy <n>", "true odds", "True-odds place bet; 5% stake commission, wins only"},
- WagerRow{"lay <n>", "true odds laid", "Bet against the number; 5% commission on winnings"},
- WagerRow{"hard 4 / hard 10", "7:1", "The point arrives as an identical pair"},
- WagerRow{"hard 6 / hard 8", "9:1", "The point arrives as an identical pair"},
+ WagerRow{"buy / lay <n>", "true", "Place at true odds; 5% win commission"},
+ WagerRow{"hard 4/10", "7:1", "Point arrives as an identical pair"},
+ WagerRow{"hard 6/8", "9:1", "Point arrives as an identical pair"},
)
}
- rows = append(rows, crapsComeOutRows(c, t.rolled)...)
+ rows = append(rows, crapsPropRows(c, !t.rolled)...)
}
return rows
}
-// crapsComeOutRows is the one-roll part of the list, available in every
-// multi-bet variant during every phase; bonus wagers drop out once the
-// shooter has rolled.
-func crapsComeOutRows(c CrapsConfig, rolled bool) []WagerRow {
+// crapsPropRows is the one-roll section of the list: field, the proposition
+// bets and (when bonuses are allowed and still open) the Fire and ATS bets.
+func crapsPropRows(c CrapsConfig, bonuses bool) []WagerRow {
rows := []WagerRow{
- WagerRow{"field", fmt.Sprintf("12 pays %d:1", c.Field12), "One roll: 2 pays 2:1; 3/4/9/10/11 pay 1:1; 5/6/7/8 lose"},
- WagerRow{"seven", "4:1", "Next roll totals 7"},
- WagerRow{"craps", "7:1", "Next roll is 2, 3 or 12"},
- WagerRow{"eleven / ace-deuce", "15:1", "Next roll totals 11 / 3"},
- WagerRow{"aces / boxcars", "30:1", "Next roll is 2 / 12"},
- WagerRow{"horn", "27:4 on 2/12", "Splits the stake equally among 2/3/11/12"},
- WagerRow{"hop <a> <b>", "15:1/30:1", "One-roll dice combination; 30:1 when both dice equal"},
+ {"field", fmt.Sprintf("12 pays %d:1", c.Field12), "2 pays 2:1; 3/4/9/10/11 1:1; 5-8 lose"},
+ {"seven", "4:1", "Next roll totals 7"},
+ {"craps", "7:1", "Next roll is 2, 3 or 12"},
+ {"eleven / ace-deuce", "15:1", "Next roll totals 11 / 3"},
+ {"aces / boxcars", "30:1", "Next roll is 2 / 12"},
+ {"horn", "27:4", "Splits the stake over 2/3/11/12"},
+ {"hop <a> <b>", "15:1/30:1", "One-roll dice combination"},
}
- if !rolled {
- // Bonus bets close before the shooter's first roll.
+ if bonuses {
rows = append(rows,
- WagerRow{"fire", "24/249/999:1", "Shooter makes 4/5/6 distinct points before sevening out"},
- WagerRow{"small / tall", "34:1", "All of 2-6 (or 8-12) rolls before any 7"},
- WagerRow{"all", "175:1", "All of 2-6 AND 8-12 in the same hand before any 7"},
+ WagerRow{"fire", "24/249/999:1", "4/5/6 distinct points before a 7"},
+ WagerRow{"small / tall", "34:1", "All 2-6 or 8-12 before any 7"},
+ WagerRow{"all", "175:1", "All 2-6 and 8-12 before any 7"},
)
}
return rows
}
-// crapsPlaceRows lists one row per placeable number with its house payout.
-// Crapless tables also accept the "impossible" numbers at extended odds.
+// crapsPlaceRows lists one place row per distinct payout, so 4/10 share 9:5,
+// 5/9 share 7:5 and 6/8 share 7:6. Crapless tables also accept the
+// "impossible" numbers at extended odds.
func crapsPlaceRows(c CrapsConfig) []WagerRow {
numbers := []int{4, 5, 6, 8, 9, 10}
if c.variant() == "crapless" {
numbers = []int{2, 3, 4, 5, 6, 8, 9, 10, 11, 12}
}
- rows := []WagerRow{}
+ type group struct {
+ odds string
+ nums []int
+ }
+ var order []*group
+ byOdds := map[string]*group{}
for _, n := range numbers {
x, y := crapsPlaceOdds(n)
- rows = append(rows, WagerRow{fmt.Sprintf("place %d", n), fmt.Sprintf("%d:%d", x, y), fmt.Sprintf("Number %d repeats before a 7", n)})
+ key := fmt.Sprintf("%d:%d", x, y)
+ g := byOdds[key]
+ if g == nil {
+ g = &group{odds: key}
+ byOdds[key] = g
+ order = append(order, g)
+ }
+ g.nums = append(g.nums, n)
+ }
+ var rows []WagerRow
+ for _, g := range order {
+ names := make([]string, len(g.nums))
+ for i, n := range g.nums {
+ names[i] = fmt.Sprint(n)
+ }
+ rows = append(rows, WagerRow{"place " + strings.Join(names, "/"), g.odds, "Repeats before a 7"})
}
return rows
}
// crapsOddsRows describes the free-odds wagers with this table's odds cap.
+// Pass and come odds are one group and don't odds another; the list column
+// says simply "true" to keep the payout column narrow.
func crapsOddsRows(c CrapsConfig) []WagerRow {
- limit := "3-4-5x (don't 6x)"
+ limit := "3-4-5x"
if c.Odds > 0 {
limit = fmt.Sprintf("%dx", c.Odds)
}
return []WagerRow{
- {"odds pass", "true odds", "Extra stake behind your pass point, up to " + limit},
- {"odds come <n>", "true odds", "Extra stake behind a travelled come bet"},
- {"odds dontpass", "true odds laid", "Extra stake against the point, laid at inverse true odds"},
- {"odds dontcome <n>", "true odds laid", "Laid odds behind a don't come bet"},
+ {"odds pass / come", "true", "Free odds behind the point, up to " + limit},
+ {"odds dont <n>", "true", "Laid against the point at inverse odds"},
}
}