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*: GameState 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: " & c) proc parseArgs*(): CmdConfig = result.state.init() for p in os.commandLineParams(): if p == "-h": echo help quit 0 elif p == "-i": result.interactive = true elif result.state.camels.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.camels.add((c: color, p: square)) else: for c in p: let color = parseColor(c) result.state.dice[color] = true if result.state.camels.len != 5: raise newException(ValueError, "Please specify positions for all camels.") # ========================== # 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: 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"{color:>7}: [{bar}] {percentage:5.2f}%" result = lines.join("\n")