121 lines
3.0 KiB
Nim
121 lines
3.0 KiB
Nim
import os, math, strutils, strformat
|
|
import fixedseq, game, simulation
|
|
|
|
|
|
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
|
|
# =============================
|
|
|
|
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
|
|
let barFill = int(round(pct * 20))
|
|
for i in 0 ..< barFill:
|
|
bar[i] = '='
|
|
|
|
lines[int(color)] = fmt"{label}: [{bar}] {percentage}%"
|
|
result = lines.join("\n")
|