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 * 100 / 20)) for i in 0 ..< barFill: bar[i] = '=' lines[int(color)] = fmt"{label}: [{bar}] {percentage}%" result = lines.join("\n")