feat(runner): Monte Carlo runner, closed-form metrics and balance CLI
Adds the S6 layer on top of the deterministic combat engine: - metrics.py: closed-form binomial statistics (win rate, standard error, 3-sigma confidence band) with clamped degenerate proportions. - runner.py: EncounterSpec/Side definitions, per-run SeededRng streams, global duplicate-id disambiguation, attrition averages per combatant. - cli.py: pf1e-sim entry point producing a French balance report with win rates, 3-sigma bands, draws, rounds, and attrition. - Movement fix: greedy straight-line heuristic could oscillate at walls; _step_toward now follows the true shortest path via an unbounded Dijkstra cost field from the target (Grid.reachable budget=None). - Regression tests: melee unit routes around a wall and engages; grid unbounded-budget coverage.
This commit is contained in:
@@ -7,6 +7,9 @@ dependencies = [
|
||||
"pyyaml",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
pf1e-sim = "pf1e_simulator.cli:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
@@ -38,6 +41,8 @@ ignore = [
|
||||
# CPY001: missing copyright notice — we don't use copyright headers
|
||||
"CPY001",
|
||||
]
|
||||
# RUF001: sigma in the CLI balance report is intentional, not a confusable
|
||||
allowed-confusables = ["σ"]
|
||||
|
||||
[tool.ruff.lint.per-file-ignores]
|
||||
# Tests: assert is expected, magic numbers are fine, annotations are noisy,
|
||||
@@ -45,6 +50,8 @@ ignore = [
|
||||
"tests/**" = ["S101", "PLR2004", "ANN", "PLR0913", "PLR0917"]
|
||||
# rng.py: `random.Random` is used for reproducible Monte Carlo streams, not cryptography
|
||||
"src/pf1e_simulator/rng.py" = ["S311"]
|
||||
# cli.py: stdout printing is the point of a CLI
|
||||
"src/pf1e_simulator/cli.py" = ["T201"]
|
||||
|
||||
# ── Basedpyright ──────────────────────────────────────────────────────────────
|
||||
[tool.basedpyright]
|
||||
|
||||
Reference in New Issue
Block a user