summaryrefslogtreecommitdiff
path: root/src/LivingVillage.Headless/Program.fs
diff options
context:
space:
mode:
Diffstat (limited to 'src/LivingVillage.Headless/Program.fs')
-rw-r--r--src/LivingVillage.Headless/Program.fs19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/LivingVillage.Headless/Program.fs b/src/LivingVillage.Headless/Program.fs
index 23434d0..4bd6424 100644
--- a/src/LivingVillage.Headless/Program.fs
+++ b/src/LivingVillage.Headless/Program.fs
@@ -71,7 +71,7 @@ type RunStats =
OutOfBounds: int64
World: World }
-let runSimulation (verbose: bool) (days: int64) (seed: uint64) (npcCount: int) : RunStats =
+let runSimulationCore (verbose: bool) (days: int64) (seed: uint64) (npcCount: int) (onSimDay: int64 -> unit) : RunStats =
let totalTicks = days * ticksPerDay
if verbose then
printfn "living-village headless days=%d seed=%d npcs=%d ticks=%d tickrate=%d" days seed npcCount totalTicks ticksPerSecond
@@ -102,6 +102,7 @@ let runSimulation (verbose: bool) (days: int64) (seed: uint64) (npcCount: int) :
driver <- d
world <- Sim.step { Input = input } world
t <- t + 1L
+ if t % ticksPerDay = 0L then onSimDay (t / ticksPerDay)
let nightNow = Sim.isNightTick t
if nightNow then nightTicks <- nightTicks + 1L else dayTicks <- dayTicks + 1L
for npc in world.Npcs do
@@ -152,6 +153,9 @@ let runSimulation (verbose: bool) (days: int64) (seed: uint64) (npcCount: int) :
OutOfBounds = outOfBounds
World = world }
+let runSimulation (verbose: bool) (days: int64) (seed: uint64) (npcCount: int) : RunStats =
+ runSimulationCore verbose days seed npcCount ignore
+
let dumpRelations (world: World) : unit =
let m = Sim.relationMatrix world
let n = Array2D.length1 m
@@ -405,9 +409,9 @@ type WorldVerdict =
Ratio: float
Gini: float }
-let evalWorld (days: int64) (k: int) : WorldVerdict =
+let evalWorld (days: int64) (k: int) (onSimDay: int64 -> unit) : WorldVerdict =
let seed = 42UL + uint64 k
- let stats = runSimulation false days seed Sim.npcCount
+ let stats = runSimulationCore false days seed Sim.npcCount onSimDay
let m = Sim.relationMatrix stats.World
let n = Array2D.length1 m
let mutable hasNonFinite = stats.NonFinite > 0L
@@ -461,11 +465,18 @@ let runBatch (worlds: int) (days: int64) : int =
let wall = System.Diagnostics.Stopwatch.StartNew()
// 逐世界流式:每个世界一完成立刻打印该行(行尾追加 elapsed_s),再打印一行
// [done k/N] 进度,并 flush,使长批次不再整轮零进度。结果仍按 world 序号落数组。
+ let progressGate = obj ()
+ let progressEvery = if days <= 5L then 1L else (days + 4L) / 5L
let results =
LivingVillage.Headless.BatchOutput.runStreaming worlds workers
(fun k ->
let sw = System.Diagnostics.Stopwatch.StartNew()
- let verdict = evalWorld days k
+ let verdict =
+ evalWorld days k (fun day ->
+ if day % progressEvery = 0L then
+ lock progressGate (fun () ->
+ printfn "%s" (LivingVillage.Headless.BatchOutput.progressLine k day days sw.Elapsed.TotalSeconds)
+ Console.Out.Flush()))
sw.Stop()
(verdict, sw.Elapsed.TotalSeconds))
(fun k (verdict, seconds) doneCount ->