Something went wrong. Try again.
bayes for days
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162"""Reading MegaMek's board files, and finding the right one.
The parts worth pinning are the ones that can be wrong silently. A coordinatesplit in the wrong place puts every hex in the wrong column and the map stilldraws. A board that cannot be found must not stop the viewer opening, becausethe reason it is opened is that a match is being played right now.
Fixtures are written here rather than copied from an install: this repositoryships none of MegaMek's data, and a test that needs a MegaMek release to run isa test that does not run."""
import tempfileimport unittestfrom pathlib import Path
from sds.board import ( Board, BoardError, blank, board_names, find_board_file, load_for, parse_board, scenario_for,)
BOARD = """# a comment, and the licence header a real one carriessize 4 3tag "Woods (Auto)"hex 0101 0 "" "desert"hex 0201 2 "rough:1" "desert"hex 0301 0 "woods:1;foliage_elev:2" "desert"hex 0401 -1 "water:2" "desert"hex 0102 1 "" "desert"hex 0202 0 "" "desert"hex 0302 0 "building:3:12" "desert"hex 0402 0 "" "desert"hex 0103 0 "" "desert"hex 0203 0 "" "desert"hex 0303 0 "" "desert"hex 0403 0 "" "desert""""
def write(tmp: Path, name: str, text: str) -> Path: path = tmp / name path.parent.mkdir(parents=True, exist_ok=True) path.write_text(text) return path
class TestParsing(unittest.TestCase): def board(self, tmp: Path) -> Board: return parse_board(write(tmp, "b.board", BOARD))
def test_size_and_hex_count(self): with tempfile.TemporaryDirectory() as tmp: board = self.board(Path(tmp)) self.assertEqual((board.width, board.height), (4, 3)) self.assertEqual(len(board.hexes), 12)
def test_coordinates_are_one_based_in_the_file_and_zero_based_here(self): # `end: {x, y}` in a decision log is a zero-based MegaMek Coords, and # the whole point of this module is that the two meet without an # off-by-one that nothing would report. with tempfile.TemporaryDirectory() as tmp: board = self.board(Path(tmp)) self.assertEqual(board.hexes[(0, 0)].elevation, 0) self.assertEqual(board.hexes[(1, 0)].elevation, 2) self.assertEqual(board.hexes[(0, 1)].elevation, 1)
def test_a_wide_board_splits_its_coordinates_down_the_middle(self): # Three digits a side once a board passes 99 hexes. A fixed `[:2]` # reads 100120 as column 10, which is a plausible hex on the same # board - so nothing raises and every glyph lands somewhere wrong. with tempfile.TemporaryDirectory() as tmp: path = write(Path(tmp), "wide.board", 'size 120 120\nhex 100120 3 "" "x"\n') board = parse_board(path) self.assertIn((99, 119), board.hexes)
def test_terrain_keeps_its_level_and_drops_the_third_field(self): with tempfile.TemporaryDirectory() as tmp: board = self.board(Path(tmp)) self.assertEqual(board.hexes[(2, 0)].terrain, {"woods": 1, "foliage_elev": 2}) self.assertEqual(board.hexes[(3, 0)].terrain, {"water": 2}) self.assertEqual(board.hexes[(2, 1)].terrain, {"building": 3})
def test_only_drawn_terrain_reaches_the_page(self): # `foliage_elev` is bookkeeping. It is kept in the model and left out # of the payload, because a glyph for it would mean nothing. with tempfile.TemporaryDirectory() as tmp: payload = self.board(Path(tmp)).as_json() hexes = {(h["x"], h["y"]): h for h in payload["hexes"]} self.assertEqual(hexes[(2, 0)]["t"], {"woods": 1})
def test_negative_elevation_survives(self): with tempfile.TemporaryDirectory() as tmp: self.assertEqual(self.board(Path(tmp)).hexes[(3, 0)].elevation, -1)
def test_a_file_with_no_hexes_is_refused(self): with tempfile.TemporaryDirectory() as tmp: path = write(Path(tmp), "empty.board", "size 4 3\n") with self.assertRaises(BoardError): parse_board(path)
class TestFinding(unittest.TestCase): def test_maps_key_is_read_and_random_entries_ignored(self): with tempfile.TemporaryDirectory() as tmp: path = write(Path(tmp), "s.mms", "Name=x\nMaps=Map Set 5/Deep Canyon 1,RANDOM\n") self.assertEqual(board_names(path), ["Map Set 5/Deep Canyon 1"])
def test_a_board_is_found_by_basename_when_the_set_moved(self): # Boards get reorganised between MegaMek releases. Failing on that # would be failing on the common case, so the basename is the fallback. with tempfile.TemporaryDirectory() as tmp: home = Path(tmp) write(home / "data" / "boards" / "Elsewhere", "Deep Canyon 1.board", BOARD) found = find_board_file("Map Set 5/Deep Canyon 1", home) self.assertIsNotNone(found) self.assertEqual(found.name, "Deep Canyon 1.board")
def test_the_scenario_comes_from_the_host_log_before_the_result_exists(self): # The live case. The result document is written when the match ends; # the host prints its banner before round 0. with tempfile.TemporaryDirectory() as tmp: repo = Path(tmp) / "repo" write(repo / "scenarios", "s.mms", "Maps=x\n") runs = repo / "runs" write(runs, "tag.log", " seed : 1\n scenario : /work/scenarios/s.mms\n") self.assertEqual(scenario_for("tag", runs, repo), repo / "scenarios" / "s.mms")
def test_the_tag_names_the_scenario_when_nothing_else_does(self): with tempfile.TemporaryDirectory() as tmp: repo = Path(tmp) / "repo" write(repo / "scenarios" / "suite", "2v2-clan-s1.mms", "Maps=x\n") runs = repo / "runs" runs.mkdir(parents=True) found = scenario_for("2v2-clan-s1-seed30-e9fa54a0", runs, repo) self.assertEqual(found, repo / "scenarios" / "suite" / "2v2-clan-s1.mms")
def test_a_missing_board_gives_a_blank_one_rather_than_an_error(self): # A viewer that refuses to open because an install moved is a viewer # nobody opens during a match. with tempfile.TemporaryDirectory() as tmp: repo = Path(tmp) / "repo" runs = repo / "runs" runs.mkdir(parents=True) board = load_for("tag", runs, repo, Path(tmp) / "nowhere") self.assertEqual(board.name, "(no board found)") self.assertTrue(board.source) self.assertEqual(len(board.hexes), board.width * board.height)
def test_blank_covers_every_hex(self): board = blank(3, 2) self.assertEqual(sorted(board.hexes), sorted((x, y) for y in range(2) for x in range(3)))
if __name__ == "__main__": unittest.main()