aboutsummaryrefslogtreecommitdiff
path: root/internal/game/render_roulette.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/render_roulette.go')
-rw-r--r--internal/game/render_roulette.go88
1 files changed, 69 insertions, 19 deletions
diff --git a/internal/game/render_roulette.go b/internal/game/render_roulette.go
index 95e91ff..4861939 100644
--- a/internal/game/render_roulette.go
+++ b/internal/game/render_roulette.go
@@ -80,26 +80,56 @@ func renderRouletteLayout(double bool, mode string, unicode bool) string {
title = "ROULETTE / DOUBLE ZERO"
}
lines = append(lines, rouletteInk(mode, title))
- // Five columns for the zero lane, twelve four-column pockets. Four
- // adjacent pockets line up exactly over each 19-column dozen.
+ // Five columns for the zero lane, twelve four-column pockets, and a
+ // six-column 2:1 lane on the right holding the row bets. Four adjacent
+ // pockets line up exactly over each 19-column dozen.
+ const rowCell = 6
gridRule := func(left, joint, right string) string {
- return left + strings.Repeat(b.h, 5) + joint + strings.Join(repeatRoulette(strings.Repeat(b.h, 4), 12), joint) + right
+ return left + strings.Repeat(b.h, 5) + joint +
+ strings.Join(repeatRoulette(strings.Repeat(b.h, 4), 12), joint) +
+ joint + strings.Repeat(b.h, rowCell) + right
+ }
+ // The numbered grid's bottom edge closes the row-bet cells and carries the
+ // dozen-row dividers as downward stubs: crosses at the inner dozen
+ // boundaries and where the grid meets the row lane, an upward tee
+ // everywhere else.
+ gridBottom := func() string {
+ var sb strings.Builder
+ sb.WriteString(b.bl)
+ for col := 6; col <= 66; col += 5 {
+ if col == 6 {
+ sb.WriteString(strings.Repeat(b.h, 5))
+ } else {
+ sb.WriteString(strings.Repeat(b.h, 4))
+ }
+ switch col {
+ case 6, 26, 46, 66:
+ sb.WriteString(b.cross)
+ default:
+ sb.WriteString(b.teeBottom)
+ }
+ }
+ sb.WriteString(strings.Repeat(b.h, rowCell))
+ sb.WriteString(b.br)
+ return sb.String()
}
lines = append(lines, rouletteInk(mode, gridRule(b.tl, b.teeTop, b.tr)))
for row := 3; row >= 1; row-- {
- zero, zeroBg := "", -1
+ zero := ""
switch {
case double && row == 3:
- zero, zeroBg = "0", 2
+ zero = "0"
case double && row == 1:
- zero, zeroBg = "00", 2
+ zero = "00"
case !double && row == 2:
- zero, zeroBg = "0", 2
+ zero = "0"
}
- if zeroBg == 2 && (mode == "none" || mode == "") {
+ if mode == "none" || mode == "" {
zero += "G"
}
- line := rouletteInk(mode, b.v) + roulettePaint(mode, rouletteCenter(zero, 5), zeroBg) + rouletteInk(mode, b.v)
+ // The 0/00 lane is one green rectangle, so its blank cells above and
+ // below the zeros are painted to match the pockets beside them.
+ line := rouletteInk(mode, b.v) + roulettePaint(mode, rouletteCenter(zero, 5), 2) + rouletteInk(mode, b.v)
for n := row; n <= 36; n += 3 {
pocket := strconv.Itoa(n)
bg, name := roulettePocketColor(pocket)
@@ -108,22 +138,32 @@ func renderRouletteLayout(double bool, mode string, unicode bool) string {
}
line += roulettePaint(mode, rouletteCenter(pocket, 4), bg) + rouletteInk(mode, b.v)
}
- line += rouletteInk(mode, fmt.Sprintf(" column%d", row))
+ // row1 is the top numbered line (3,6,...36) and row3 the bottom.
+ line += rouletteInk(mode, rouletteCenter(fmt.Sprintf("row%d", 4-row), rowCell)+b.v)
lines = append(lines, line)
if row > 1 {
- // The zero lane spans the grid height; only its labeled cell is green.
- line = rouletteInk(mode, b.v+" "+b.teeLeft+strings.Join(repeatRoulette(strings.Repeat(b.h, 4), 12), b.cross)+b.teeRight)
+ line = rouletteInk(mode, b.v+" "+b.teeLeft+
+ strings.Join(repeatRoulette(strings.Repeat(b.h, 4), 12), b.cross)+
+ b.cross+strings.Repeat(b.h, rowCell)+b.teeRight)
lines = append(lines, line)
}
}
- lines = append(lines, rouletteInk(mode, gridRule(b.bl, b.teeBottom, b.br)))
- // Outside bets share the exact 60-column numbered-grid footprint.
+ lines = append(lines, rouletteInk(mode, gridBottom()))
+ // Outside bets share the exact 60-column numbered-grid footprint. The
+ // dozen row gets its own bottom rule so the 1to12/13to24/25to36 boxes are
+ // closed and do not run into the even-money spaces below them.
indent := " "
dozen := indent + rouletteInk(mode, b.v)
- for i := 1; i <= 3; i++ {
- dozen += rouletteInk(mode, rouletteCenter(fmt.Sprintf("dozen%d", i), 19)) + rouletteInk(mode, b.v)
+ for _, label := range []string{"1to12", "13to24", "25to36"} {
+ dozen += rouletteInk(mode, rouletteCenter(label, 19)) + rouletteInk(mode, b.v)
}
lines = append(lines, dozen)
+ dozenBottom := indent + b.teeLeft
+ dozenJoints := []string{b.teeTop, b.cross, b.teeTop, b.cross, b.teeTop, b.teeRight}
+ for i := 0; i < 6; i++ {
+ dozenBottom += strings.Repeat(b.h, 9) + dozenJoints[i]
+ }
+ lines = append(lines, rouletteInk(mode, dozenBottom))
line := indent + rouletteInk(mode, b.v)
for _, bet := range []string{"low", "even", "red", "black", "odd", "high"} {
bg := -1
@@ -135,7 +175,17 @@ func renderRouletteLayout(double bool, mode string, unicode bool) string {
}
line += roulettePaint(mode, rouletteCenter(bet, 9), bg) + rouletteInk(mode, b.v)
}
- lines = append(lines, line, rouletteInk(mode, indent+b.bl+strings.Repeat(b.h, 59)+b.br))
+ // The bottom rule tees upward under each outside-bet divider so the
+ // vertical lines below the dozens meet the table's bottom edge.
+ bottom := indent + b.bl
+ for i := 0; i < 6; i++ {
+ bottom += strings.Repeat(b.h, 9)
+ if i < 5 {
+ bottom += b.teeBottom
+ }
+ }
+ bottom += b.br
+ lines = append(lines, line, rouletteInk(mode, bottom))
if mode == "none" || mode == "" {
lines = append(lines, "R = red, B = black, G = green")
}
@@ -317,9 +367,9 @@ func renderRouletteResult(pockets [3]string, mode string, unicode bool, size int
// rouletteReminder is the odds/cheat-sheet block, shown only by "table" (and
// "table rules"), never with the ambient betting board.
func (g *Game) rouletteReminder(sess *net.Session) string {
- text := "Numbers 35:1 | Dozens / columns 2:1 | Other outside bets 1:1\n" +
+ text := "Numbers 35:1 | 1to12 / 13to24 / 25to36 and rows 2:1 | Other outside bets 1:1\n" +
"Low: 1-18 | High: 19-36 | Zero loses all outside bets\n" +
- "bet 10 on 17 / bet 10 on red / bet 10 on dozen2"
+ "bet 10 on 17 / bet 10 on red / bet 10 on 13to24"
return g.colorize(sess, "casino_action", text)
}