cup/ui.nim

121 lines
3.0 KiB
Nim
Raw Normal View History

import os, math, strutils, strformat
import fixedseq, game, simulation
2021-07-12 22:46:06 +00:00
const help =
"""cup - Probability calculator for the board game CamelUp
Usage:
cup [-i] SPACE:STACK [...SPACE:STACK] [DICE]
SPACE refers to a numbered board space (1-16).
STACK refers to a stack of camel colors from bottom to top, e.g.
YBR (Yellow, Blue, Red, with Red on top).
DICE refers to the set of dice that have already been rolled,
e.g. GPR (Green, Purple, Red)
Options:
-i Interactive mode (currently unimplemented)
-h Show this message and exit
"""
# =============================
# User input parsing/validation
# =============================
2021-07-12 22:46:06 +00:00
type
CmdConfig* = object
state*: seq[tuple[c: Color, p: int]]
interactive*: bool
diceRolled*: array[Color, bool]
proc parseColor(c: char): Color =
case c:
of 'R', 'r':
return cRed
of 'G', 'g':
return cGreen
of 'B', 'b':
return cBlue
of 'Y', 'y':
return cYellow
of 'P', 'p':
return cPurple
else:
raise newException(ValueError, "Invalid camel color specified.")
proc parseArgs*(): CmdConfig =
for p in os.commandLineParams():
if p == "-h":
echo help
quit 0
elif p == "-i":
result.interactive = true
elif result.state.len < 5:
let splat = p.split(':')
let sq = splat[0]
let square = sq.parseInt
let colors = splat[1]
for c in colors:
let color = parseColor(c)
result.state.add((color, square))
else:
for c in p:
let color = parseColor(c)
result.diceRolled[color] = true
# ==========================
# Game state representations
# ==========================
proc showSpaces*(b: Board; start, stop: Natural): string =
let numSpaces = stop - start + 1
let width = 4 * numSpaces - 1
var lines: array[7, string]
# start by building up an empty board
for i in 0 .. 6: # gotta initialize the strings
lines[i] = newString(width)
for c in lines[i].mitems:
c = ' '
# fill in the dividers
lines[5] = repeat("=== ", numSpaces - 1)
lines[5].add("===")
# now populate the board
for sp in 0 ..< numSpaces:
# fill in the square numbers
let squareNum = sp + start
let cellMid = 4 * sp + 1
for i, chr in $squareNum:
lines[6][cellMid + i] = chr
# fill in the camel stacks
for i, color in b.squares[squareNum].camels:
let lineNum = 4 - i # lines go to 6, but bottom 2 are reserved
let repr = '|' & color.abbrev & '|'
for j, chr in repr:
lines[lineNum][cellMid - 1 + j] = chr
result = lines.join("\n")
proc showPercents*(scores: ScoreSet): string =
var lines: array[5, string]
for color, pct in scores.percents:
let label = align($color, 7) # e.g. " Green"
var bar = repeat(" ", 20)
let percentage = round(pct * 100, 2)
# populate the progress bar
2021-10-22 17:34:43 +00:00
let barFill = int(round(pct * 20))
for i in 0 ..< barFill:
bar[i] = '='
lines[int(color)] = fmt"{label}: [{bar}] {percentage}%"
result = lines.join("\n")