1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
package casino
import (
"fmt"
"strings"
)
// 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{}
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 1:1; 10/11 2:1; 12 5:1; 5-9 lose"},
)
case "high_point":
rows = append(rows,
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", "6 wins; 1 loses; 2-5 must repeat before a 1"},
)
case "new_york":
rows = append(rows,
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 / lay <n>", "true", "4/5/6/8/9/10; 5% win commission"},
)
}
case "crapless":
rows = append(rows,
WagerRow{"pass", "1:1", "Come-out 7 wins; every other total makes 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 / 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, crapsPropRows(c, false)...)
default: // bank and diceless
rows = append(rows,
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; a 12 pushes"},
)
rows = append(rows, crapsOddsRows(c)...)
rows = append(rows, crapsPlaceRows(c)...)
rows = append(rows,
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, crapsPropRows(c, !t.rolled)...)
}
return rows
}
// 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{
{"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 bonuses {
rows = append(rows,
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 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}
}
type group struct {
odds string
nums []int
}
var order []*group
byOdds := map[string]*group{}
for _, n := range numbers {
x, y := crapsPlaceOdds(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"
if c.Odds > 0 {
limit = fmt.Sprintf("%dx", c.Odds)
}
return []WagerRow{
{"odds pass / come", "true", "Free odds behind the point, up to " + limit},
{"odds dont <n>", "true", "Laid against the point at inverse odds"},
}
}
|