Something went wrong. Try again.
bayes for days
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149"""What MegaMek permits a prone, damaged Mek, read back from the probe's table.
`sds stand-probe` asks MegaMek itself - a real scenario, real prone units, limbsremoved through `Entity.destroyLocation` - and writes `scenarios/stand/observed.txt`. These tests read that table rather than a rulebook, so what theypin is behaviour somebody observed on a named MegaMek release.
**MegaMek is the specification.** We play against it, so what it permits iswhat is legal and there is nothing else to check the answer against.`Observation.canStand` therefore asks `MovePath.isMoveLegal` and keeps no ruleof its own, and `test_we_answer_exactly_as_megamek_does` is the acceptance testfor that: every cell, both ways, no exceptions."""
import reimport unittestfrom pathlib import Path
OBSERVED = Path(__file__).resolve().parent.parent / "scenarios" / "stand" / "observed.txt"
def rows() -> list[dict]: """One dict per cell, plus the chassis, straight off the probe's lines.""" out = [] for line in OBSERVED.read_text().splitlines(): if not line.startswith("stand "): continue row = dict(re.findall(r"(\w+)=(\S+)", line)) row["chassis"] = line.split()[1] out.append(row) return out
class TestObservedStanding(unittest.TestCase): def setUp(self) -> None: self.rows = rows() self.assertTrue(self.rows, f"{OBSERVED} has no cells; run `sds stand-probe`")
def test_every_chassis_is_covered(self) -> None: """A quad and a tripod are the cases nobody can reason about from a biped.""" chassis = {row["chassis"] for row in self.rows} self.assertEqual(chassis, {"BipedMek", "QuadMek", "TripodMek", "LandAirMek"}, chassis)
def test_we_answer_exactly_as_megamek_does(self) -> None: """The acceptance test for deleting the hand-written rule.
Eighty cells, and `canStand` agrees with MegaMek in every one. It agreed in thirty-nine before the `LEGS` array went; the forty-one that moved are all stands MegaMek allows and the array refused. """ differ = [r for r in self.rows if r["agree"] == "NO"] self.assertEqual( [f"{r['chassis']} {r['damage']}" for r in differ], [], "canStand and MegaMek disagree; MegaMek is the specification", )
def test_we_are_never_more_permissive_than_megamek(self) -> None: """The direction that costs a match, not the one that costs a turn.
Stated separately from the equality above because it is the half that must hold even if the two ever drift: a stand MegaMek refuses takes the whole path down with it and the unit spends the turn on its face. """ looser = [r for r in self.rows if r["ours"] == "yes" and r["legal"] == "no"] self.assertEqual( looser, [], "canStand offers a stand MegaMek refuses; every candidate that " "opens with GET_UP would be thrown away", )
def test_the_move_gate_is_never_looser_than_the_roll(self) -> None: """`isMoveLegal` accepting a path is never contradicted by the roll.
Observed over every cell: there is no state where MegaMek accepts a `GET_UP` path and then calls the piloting roll impossible. That is what makes the move gate a safe oracle on its own - it can refuse a stand the roll would have allowed, but it never offers one the roll refuses. """ for row in self.rows: if row["legal"] == "yes": self.assertNotIn( row["psr"], {"IMPOSSIBLE", "AUTO_FAIL"}, f"{row['chassis']} {row['damage']}: the path was accepted " f"and the roll came back {row['psr']}", )
def test_a_tripods_two_gates_disagree(self) -> None: """`checkGetUp` is not the answer for a tripod, and reading it misleads.
Its impossible branch is reached only for a `BipedMek`, so a tripod is handed a rollable number in eighteen cells whose path MegaMek refuses outright. Anyone settling the tripod question by reading that method would conclude the stand is allowed. Pinned because it is the reason this matrix was measured instead of derived. """ split = [ r for r in self.rows if r["chassis"] == "TripodMek" and r["legal"] == "no" and r["psr"] not in {"IMPOSSIBLE", "AUTO_FAIL"} ] self.assertEqual(len(split), 18, [r["damage"] for r in split]) # And no other chassis does this: they are refused by the roll as well. for row in self.rows: if row["chassis"] == "TripodMek" or row["legal"] == "yes": continue self.assertIn(row["psr"], {"IMPOSSIBLE", "AUTO_FAIL"}, row)
def test_a_tripod_may_stand_with_both_arms_and_its_centre_leg_gone(self) -> None: """The cell MegaMek's own limb bar does not read.
The bar names `LOC_LEFT_LEG` and `LOC_RIGHT_LEG`. A tripod's centre leg is neither, so both arms and the centre leg is a stand MegaMek allows while both arms and an outer leg is not. Pinned because it is the one answer nobody would guess. """ by = {r["damage"]: r for r in self.rows if r["chassis"] == "TripodMek"} self.assertEqual(by["CL+LA+RA"]["legal"], "yes") self.assertEqual(by["RL+LA+RA"]["legal"], "no") self.assertEqual(by["LL+LA+RA"]["legal"], "no")
def test_a_quad_may_stand_on_two_legs(self) -> None: """Including the front legs, which live in the arm locations.
The deleted `LEGS` array named the right four locations for a quad, which was read as the quad case being accidentally correct. It was not: MegaMek allows a quad to stand with any one or any two of its four legs destroyed, and the array refused all of it. Ten of the sixteen quad cells moved when it went, more than moved on a biped. """ by = {r["damage"]: r for r in self.rows if r["chassis"] == "QuadMek"} for damage in ("FRL", "FLL", "RRL", "RLL", "FRL+FLL", "RRL+RLL"): self.assertEqual(by[damage]["legal"], "yes", damage) self.assertEqual(by[damage]["ours"], "yes", damage)
def test_a_lam_answers_exactly_as_a_biped(self) -> None: """`LandAirMek extends BipedMek`, and standing is where that shows.""" biped = {r["damage"]: r["legal"] for r in self.rows if r["chassis"] == "BipedMek"} lam = {r["damage"]: r["legal"] for r in self.rows if r["chassis"] == "LandAirMek"} self.assertEqual(biped, lam)
if __name__ == "__main__": unittest.main()