diff options
Diffstat (limited to 'internal/game/casino_commands.go')
| -rw-r--r-- | internal/game/casino_commands.go | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/internal/game/casino_commands.go b/internal/game/casino_commands.go index f4ca79f..b6deb21 100644 --- a/internal/game/casino_commands.go +++ b/internal/game/casino_commands.go @@ -1,6 +1,7 @@ package game import ( + "regexp" "strings" "unicode/utf8" @@ -8,6 +9,34 @@ import ( "thehouseoficarus/internal/net" ) +// casinoCommandVariable matches a command variable: an uppercase run such as +// N in "bet N on BET" or MAX in "bet [1-4|MAX]". Literal command text is +// lowercase, so every uppercase run is a placeholder the player replaces. +var casinoCommandVariable = regexp.MustCompile(`[A-Z]+`) + +// colorizeCommand paints literal command text in the command color and each +// uppercase variable in the distinct variable color. Mode "none" collapses to +// plain text, and text without variables gets a single color wrapper. +func (g *Game) colorizeCommand(sess *net.Session, text string) string { + matches := casinoCommandVariable.FindAllStringIndex(text, -1) + if len(matches) == 0 { + return g.colorize(sess, "command", text) + } + var sb strings.Builder + last := 0 + for _, m := range matches { + if m[0] > last { + sb.WriteString(g.colorize(sess, "command", text[last:m[0]])) + } + sb.WriteString(g.colorize(sess, "command_variable", text[m[0]:m[1]])) + last = m[1] + } + if last < len(text) { + sb.WriteString(g.colorize(sess, "command", text[last:])) + } + return sb.String() +} + // Wrap before Session.WriteLine: generic prose wrapping strips alignment from // overlong lines. Every casino menu uses the same two-space command indent and // hanging description column, capped at 80 even when prose wrapping is off. @@ -35,7 +64,7 @@ func (g *Game) casinoCommandColumns(sess *net.Session, commands []casino.MenuCom n := utf8.RuneCountInString(c.Command) if n > limit/2 { for _, line := range casinoWrapWords(c.Command, max(1, limit-2)) { - lines = append(lines, " "+g.colorize(sess, "command", line)) + lines = append(lines, " "+g.colorizeCommand(sess, line)) } for _, line := range casinoWrapWords(c.Desc, max(1, limit-4)) { lines = append(lines, " "+line) @@ -43,13 +72,13 @@ func (g *Game) casinoCommandColumns(sess *net.Session, commands []casino.MenuCom continue } if strings.TrimSpace(c.Desc) == "" { - lines = append(lines, " "+g.colorize(sess, "command", c.Command)) + lines = append(lines, " "+g.colorizeCommand(sess, c.Command)) continue } indent := width + 4 desc := casinoWrapWords(c.Desc, max(1, limit-indent)) cmd := c.Command + strings.Repeat(" ", width-n) - lines = append(lines, " "+g.colorize(sess, "command", cmd)+" "+desc[0]) + lines = append(lines, " "+g.colorizeCommand(sess, cmd)+" "+desc[0]) for _, line := range desc[1:] { lines = append(lines, strings.Repeat(" ", indent)+line) } |
