103 lines
2.3 KiB
Nim
103 lines
2.3 KiB
Nim
import math, random, strformat, strutils, times, std/monotimes
|
|
import fixedseq, game, simulation
|
|
|
|
|
|
type
|
|
TestResults = object
|
|
ops: int
|
|
time: Duration
|
|
|
|
|
|
proc formatNum(n: SomeNumber, decimals = 0): string =
|
|
when n is SomeFloat:
|
|
let s = $n.round(decimals)
|
|
else:
|
|
let s = $n
|
|
var parts = s.split('.')
|
|
result = parts[0].insertSep(',')
|
|
if decimals > 0:
|
|
result = result & '.' & parts[1]
|
|
|
|
|
|
proc summarize(tr: TestResults, opname = "operations") =
|
|
let secs = tr.time.inMilliseconds.float / 1000
|
|
stdout.write("Test completed:\n")
|
|
stdout.write(&" {tr.ops.formatNum} {opname} in {secs.formatNum} seconds\n")
|
|
stdout.write(&" {(tr.ops.float / secs).formatNum} {opname} per second")
|
|
stdout.flushFile()
|
|
|
|
|
|
template executionTime(body: untyped): Duration =
|
|
let start = getMonoTime()
|
|
body
|
|
getMonoTime() - start
|
|
|
|
|
|
proc getRand(): Rand =
|
|
randomize()
|
|
result = initRand(rand(int64))
|
|
|
|
|
|
proc randomDice(r: var Rand): seq[tuple[c: Color, p: int]] =
|
|
for c in Color:
|
|
let v = r.rand(1..3)
|
|
result.add((c, v))
|
|
result.shuffle
|
|
|
|
|
|
proc newRandomGame(r: var Rand): Board =
|
|
var dice: array[5, tuple[c: Color, p: int]]
|
|
for i in 0 .. 4:
|
|
dice[i] = (Color(i), r.rand(1..3))
|
|
|
|
result.init
|
|
result.setState(dice, [])
|
|
|
|
|
|
proc games(nTests, nSamples: Natural, parallel = true) =
|
|
var r = getRand()
|
|
var scores: ScoreSet
|
|
var res: TestResults
|
|
for i in 1 .. nTests:
|
|
let b = newRandomGame(r)
|
|
let dur = executionTime:
|
|
let s = b.randomGames(nSamples, parallel = parallel)
|
|
scores.update(s)
|
|
res.ops += s.sum()
|
|
res.time += dur
|
|
res.summarize("games")
|
|
|
|
|
|
proc legs(nTests: Natural) =
|
|
var r = getRand()
|
|
var scores: ScoreSet
|
|
var res: TestResults
|
|
for i in 1 .. nTests:
|
|
let b = newRandomGame(r)
|
|
let dur = executionTime:
|
|
let s = b.getLegScores
|
|
scores.update(s)
|
|
res.ops += s.sum
|
|
res.time += dur
|
|
res.summarize("legs")
|
|
|
|
|
|
proc spread(nTests, nSamples: Natural) =
|
|
var r = getRand()
|
|
let b = newRandomGame(r)
|
|
let spread = randomSpread(b, nTests, nSamples)
|
|
|
|
stdout.writeLine("Variance:")
|
|
for c in Color:
|
|
let variance = 100 * (spread.hi[c] - spread.lo[c])
|
|
stdout.writeLine(fmt"{c}: {round(variance, 2):.2f}%")
|
|
|
|
let diff = 100 * (max(spread.hi) - min(spread.lo))
|
|
stdout.writeLine(fmt"Win percentage differential: {round(diff, 2):.2f}%")
|
|
|
|
stdout.flushFile()
|
|
|
|
|
|
when isMainModule:
|
|
legs(3000)
|