111 lines
2.8 KiB
Nim
111 lines
2.8 KiB
Nim
import os, math, strutils, strformat
|
|
import fixedseq, game, simulation
|
|
|
|
|
|
const help = block:
|
|
# can't use regex, fortunately we are looking for a straightforward separator
|
|
let readme = slurp("./README.md")
|
|
let endPos = rfind(readme, "```") - 1
|
|
let startPos = rfind(readme, "```", last = endPos) + 4
|
|
readme[startPos..endPos]
|
|
|
|
|
|
# =============================
|
|
# 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")
|