package casino import ( "fmt" ) // 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. func (t *crapsTable) wagerRows(name string) []WagerRow { c := t.Config.Craps rows := []WagerRow{} switch c.variant() { 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"}, ) 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"}, ) 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"}, ) 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{"dontpass", "1:1", "Opposite side; come-out 12 pushes"}, ) if t.point != 0 { rows = append(rows, crapsOddsRows(c)...) rows = append(rows, WagerRow{"buy ", "true odds", "True-odds bet on 4/5/6/8/9/10; 5% stake commission, wins only"}, WagerRow{"lay ", "true odds laid", "Bet AGAINST the number; 5% commission on winnings"}, ) } case "crapless": rows = append(rows, WagerRow{"pass", "1:1", "Come-out only 7 wins; every other total becomes the point"}, ) if t.point != 0 { rows = append(rows, WagerRow{"come", "1:1", "A personal point with pass rules"}, ) rows = append(rows, crapsOddsRows(c)...) rows = append(rows, crapsPlaceRows(c)...) rows = append(rows, WagerRow{"buy ", "true odds", "True-odds place bet; 5% stake commission, wins only"}, WagerRow{"lay ", "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 ", "15:1/30:1", "One-roll dice combination; 30:1 when both dice equal"}, ) } else { rows = append(rows, crapsComeOutRows(c, t.rolled)...) } 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{"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"}, ) rows = append(rows, crapsOddsRows(c)...) rows = append(rows, crapsPlaceRows(c)...) rows = append(rows, WagerRow{"buy ", "true odds", "True-odds place bet; 5% stake commission, wins only"}, WagerRow{"lay ", "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"}, ) } rows = append(rows, crapsComeOutRows(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 { 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 ", "15:1/30:1", "One-roll dice combination; 30:1 when both dice equal"}, } if !rolled { // Bonus bets close before the shooter's first roll. 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"}, ) } return rows } // crapsPlaceRows lists one row per placeable number with its house payout. // 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{} 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)}) } return rows } // crapsOddsRows describes the free-odds wagers with this table's odds cap. func crapsOddsRows(c CrapsConfig) []WagerRow { limit := "3-4-5x (don't 6x)" 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 ", "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 ", "true odds laid", "Laid odds behind a don't come bet"}, } }