diff --git a/README.md b/README.md index c7524b9..a2a4ec7 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ or is dice. ./sds.sh view runs/ # what the bot thought ./sds.sh los-dump scenarios/suite/*.mms \ --out crates/sds-core/tests/corpus/los.jsonl # regenerate the LOS corpus + ./sds.sh pathfind-dump # regenerate the movement corpus ./sds.sh arc-dump # the arc corpus, which is NOT committed A 4v4 on one map sheet takes about 90 seconds. diff --git a/bridge/sds/SdsPathfind.java b/bridge/sds/SdsPathfind.java new file mode 100644 index 0000000..c9b1464 --- /dev/null +++ b/bridge/sds/SdsPathfind.java @@ -0,0 +1,275 @@ +package sds; + +import java.io.BufferedWriter; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.TreeMap; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import megamek.common.board.Board; +import megamek.common.board.Coords; +import megamek.common.enums.MoveStepType; +import megamek.common.game.Game; +import megamek.common.game.IGame; +import megamek.common.loaders.MekSummaryCache; +import megamek.common.moves.MovePath; +import megamek.common.scenario.Scenario; +import megamek.common.scenario.ScenarioLoader; +import megamek.common.units.Entity; + +/** + * Dump MegaMek's own legal ground movement end states, as the corpus the Rust + * reachability search is tested against. + * + *

The bot proposes positions, so it has to know which {@code (hex, facing)} + * states a unit can actually reach and what each one costs. MegaMek will not + * answer that in bulk - it answers "is this path legal" one path at a time, + * through {@link MovePath#isMoveLegal()} - so the bot runs its own search. A + * search that disagrees does not throw: it proposes hexes the server rejects, + * the unit stands still, and that arrives as a bad bot rather than a bug. + * + *

The search here is deliberately the dumb one. It walks {@link MovePath} + * itself, adding {@code FORWARDS}, {@code TURN_LEFT} and {@code TURN_RIGHT} + * one step at a time and keeping whatever {@code isMoveLegal} accepts, in + * order of MP spent. Nothing about terrain cost, elevation limits, or what a + * turn costs is written down here; all of it comes back out of MegaMek. That + * is the whole point - a corpus that shared an assumption with the port under + * test would validate nothing. + * + *

Ties are broken on hexes moved, so a state's {@code hexes} is the fewest + * hexes among the cheapest paths to it. Both numbers are recorded because they + * are different questions: terrain burns MP without moving you, and the target + * movement modifier keys on hexes rather than on MP. + * + *

Bound. An offline fixture, committed once. Nothing dumps during a + * match. The cases are given on the command line, and the committed set is in + * {@code sds/match.py}: two boards, three starts each, two facings and two MP + * budgets. Two boards because open ground and heavy forest are the two + * regimes - 6 MP reaches forty-odd hexes on one and ten on the other, and a + * cost model that is wrong shows up in only one of them. Three starts because + * hex geometry in MegaMek is column-parity dependent, so an even column and an + * odd column are different tests, and a start beside an elevation change is a + * third. Two MP budgets because the state set for {@code n} must be a subset + * of the set for {@code n + 1}, which is a property the corpus can be asked + * for directly. Twenty-four cases regenerate in well under a minute and commit + * to about a hundred kilobytes; a whole board's worth of starts would be + * megabytes and would test the same three things. + * + *

Output is JSON Lines. A {@code board} line in the wire form + * {@link Observation#board(Board)} produces, then one {@code case} line per + * case, so a test needs this file and nothing else. + */ +public final class SdsPathfind { + + /** The move steps a walking or running ground unit has. */ + private static final MoveStepType[] STEPS = { + MoveStepType.FORWARDS, MoveStepType.TURN_LEFT, MoveStepType.TURN_RIGHT, + }; + + /** + * A refusal to expand a path that has gone somewhere absurd. + * + *

{@code isMoveLegal} is the authority on legality and this is not a + * second opinion on it - it is a guard against an unbounded frontier if a + * step is somehow both legal and free. + */ + private static final int MAX_STEPS = 64; + + public static void main(String[] argv) throws Exception { + Path out = null; + List cases = new ArrayList<>(); + String scenario = null; + // Board key -> scenario path, in the order they were named. + Map boards = new TreeMap<>(); + for (int i = 0; i < argv.length; i++) { + switch (argv[i]) { + case "--out" -> out = Path.of(argv[++i]); + case "--board" -> { + String[] parts = argv[++i].split("=", 2); + if (parts.length != 2) { + throw new IllegalArgumentException("--board wants ="); + } + boards.put(parts[0], parts[1]); + scenario = parts[0]; + } + case "--case" -> { + if (scenario == null) { + throw new IllegalArgumentException("--case before any --board"); + } + cases.add(scenario + ":" + argv[++i]); + } + default -> throw new IllegalArgumentException("unknown argument " + argv[i]); + } + } + if (out == null || cases.isEmpty()) { + System.err.println( + "usage: sds.SdsPathfind --out corpus.jsonl" + + " --board = --case ,,, ..."); + System.exit(2); + } + + MekSummaryCache cache = MekSummaryCache.getInstance(); + while (!cache.isInitialized()) { + Thread.sleep(250L); + } + + ObjectMapper mapper = new ObjectMapper(); + Observation observation = new Observation(mapper); + Files.createDirectories(out.toAbsolutePath().getParent()); + + int states = 0; + long nanos = 0L; + try (BufferedWriter writer = Files.newBufferedWriter(out)) { + for (Map.Entry entry : boards.entrySet()) { + String key = entry.getKey(); + Game game = load(entry.getValue()); + Entity unit = game.getEntitiesVector().get(0); + unit.setDeployed(true); + Board board = game.getBoard(unit); + + ObjectNode header = observation.board(board); + header.put("board", key); + header.put("scenario", new File(entry.getValue()).getName()); + header.put("unit", unit.getShortName()); + header.put("walkMp", unit.getWalkMP()); + header.put("runMp", unit.getRunMP()); + writer.write(mapper.writeValueAsString(header)); + writer.newLine(); + + for (String spec : cases) { + if (!spec.startsWith(key + ":")) { + continue; + } + String[] parts = spec.substring(key.length() + 1).split(","); + int x = Integer.parseInt(parts[0]); + int y = Integer.parseInt(parts[1]); + int facing = Integer.parseInt(parts[2]); + int mp = Integer.parseInt(parts[3]); + + long started = System.nanoTime(); + ObjectNode node = search(mapper, game, board, unit, x, y, facing, mp); + nanos += System.nanoTime() - started; + node.put("board", key); + states += node.withArray("states").size(); + writer.write(mapper.writeValueAsString(node)); + writer.newLine(); + } + } + } + + System.out.printf("%d cases, %d states -> %s%n", cases.size(), states, out); + System.out.printf("search: %.1f ms mean over %d cases%n", + nanos / 1_000_000.0 / cases.size(), cases.size()); + } + + private static Game load(String scenario) throws Exception { + Scenario parsed = new ScenarioLoader(new File(scenario)).load(); + IGame igame = parsed.createGame(); + if (!(igame instanceof Game game)) { + throw new IllegalStateException(scenario + ": not a Total Warfare game"); + } + if (game.getEntitiesVector().isEmpty()) { + throw new IllegalStateException(scenario + ": no units"); + } + return game; + } + + /** + * Every {@code (hex, facing)} the unit can stand in, and the cheapest way + * to each. + * + *

Dijkstra over {@link MovePath}, ordered by MP spent and then by hexes + * moved. A state is settled once, so what comes out is the minimum MP to + * reach it and the fewest hexes among the paths that spend that much. + */ + private static ObjectNode search(ObjectMapper mapper, Game game, Board board, Entity unit, + int x, int y, int facing, int mp) { + unit.setPosition(new Coords(x, y)); + unit.setFacing(facing); + unit.setSecondaryFacing(facing); + unit.setElevation(0); + unit.setProne(false); + unit.setHullDown(false); + unit.setDone(false); + + Comparator cheapest = Comparator + .comparingInt(MovePath::getMpUsed) + .thenComparingInt(MovePath::getHexesMoved) + .thenComparingInt(MovePath::length); + PriorityQueue frontier = new PriorityQueue<>(cheapest); + frontier.add(new MovePath(game, unit)); + + Map settled = new HashMap<>(); + // What the search cost, next to what it found: a port that reaches the + // same states through ten times the paths is a different algorithm. + int considered = 0; + int legal = 0; + while (!frontier.isEmpty()) { + MovePath path = frontier.poll(); + String key = path.getFinalCoords().getX() + + "," + path.getFinalCoords().getY() + + "," + path.getFinalFacing(); + if (settled.containsKey(key)) { + continue; + } + settled.put(key, path); + if (path.length() >= MAX_STEPS) { + continue; + } + for (MoveStepType step : STEPS) { + considered++; + MovePath next = path.clone().addStep(step); + if (next.getMpUsed() > mp || !next.isMoveLegal()) { + continue; + } + if (!board.contains(next.getFinalCoords())) { + continue; + } + legal++; + frontier.add(next); + } + } + + ObjectNode node = mapper.createObjectNode(); + node.put("type", "case"); + node.put("x", x); + node.put("y", y); + node.put("facing", facing); + node.put("mp", mp); + node.put("considered", considered); + node.put("legal", legal); + ArrayNode states = node.putArray("states"); + // Sorted on the coordinates themselves, so the file is a function of + // the case and not of the order the heap happened to settle in. + List ordered = new ArrayList<>(settled.values()); + ordered.sort(Comparator + .comparingInt((MovePath path) -> path.getFinalCoords().getX()) + .thenComparingInt(path -> path.getFinalCoords().getY()) + .thenComparingInt(MovePath::getFinalFacing)); + for (MovePath path : ordered) { + ArrayNode state = states.addArray(); + state.add(path.getFinalCoords().getX()); + state.add(path.getFinalCoords().getY()); + state.add(path.getFinalFacing()); + state.add(path.getMpUsed()); + state.add(path.getHexesMoved()); + state.add(path.getFinalElevation()); + // The zero-step path has no last step, and so no movement type. + state.add(path.length() == 0 ? "NONE" : path.getLastStepMovementType().name()); + } + return node; + } + + private SdsPathfind() { + } +} diff --git a/crates/sds-core/tests/corpus/pathfind.jsonl b/crates/sds-core/tests/corpus/pathfind.jsonl new file mode 100644 index 0000000..76c492b --- /dev/null +++ b/crates/sds-core/tests/corpus/pathfind.jsonl @@ -0,0 +1,26 @@ +{"type":"board","width":16,"height":17,"hexes":[{"x":1,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":6,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":7,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":11,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":12,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":0,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":5,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":6,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":7,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":8,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":10,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":11,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":12,"y":1,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":14,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":15,"y":1,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":1,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":6,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":7,"y":2,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":8,"y":2,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":9,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":10,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":11,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":12,"y":2,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":14,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":15,"y":2,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":1,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":4,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":5,"y":3,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":6,"y":3,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":7,"y":3,"level":2,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":8,"y":3,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":9,"y":3,"level":1,"terrain":{"woods":2,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":10,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":11,"y":3,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":12,"y":3,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":14,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":15,"y":3,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":0,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":4,"y":4,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":5,"y":4,"level":2,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":6,"y":4,"level":2,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":7,"y":4,"level":3,"terrain":{"incline_top":1}},{"x":8,"y":4,"level":2,"terrain":{"woods":2,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":9,"y":4,"level":2,"terrain":{"woods":2,"foliage_elev":2,"incline_top":1}},{"x":10,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":11,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":12,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":14,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":15,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":5,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":4,"y":5,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":5,"y":5,"level":2,"terrain":{"incline_top":1,"incline_bottom":1}},{"x":6,"y":5,"level":3,"terrain":{"incline_top":1}},{"x":7,"y":5,"level":3,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":8,"y":5,"level":2,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":9,"y":5,"level":2,"terrain":{"woods":2,"foliage_elev":2,"incline_top":1}},{"x":10,"y":5,"level":1,"terrain":{"woods":2,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":11,"y":5,"level":1,"terrain":{"woods":2,"foliage_elev":2,"incline_top":1}},{"x":12,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":13,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":0,"y":6,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":6,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":6,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":6,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":4,"y":6,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":5,"y":6,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":6,"y":6,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":7,"y":6,"level":2,"terrain":{"incline_top":1,"incline_bottom":1}},{"x":8,"y":6,"level":2,"terrain":{"incline_bottom":1}},{"x":9,"y":6,"level":2,"terrain":{"incline_top":1}},{"x":10,"y":6,"level":1,"terrain":{"incline_bottom":1}},{"x":11,"y":6,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":12,"y":6,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":13,"y":6,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":14,"y":6,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":7,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":7,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":5,"y":7,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":6,"y":7,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":7,"y":7,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":8,"y":7,"level":2,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":9,"y":7,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":10,"y":7,"level":1,"terrain":{"woods":1,"incline_top":1,"incline_bottom":1,"foliage_elev":2}},{"x":11,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":12,"y":7,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":13,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":14,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":4,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":6,"y":8,"level":0,"terrain":{"incline_bottom":1}},{"x":7,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":8,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":9,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":10,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":11,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":12,"y":8,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":6,"y":9,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":7,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":8,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":9,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":10,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":11,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":12,"y":9,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":13,"y":9,"level":0,"terrain":{"incline_bottom":1}},{"x":2,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":6,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":7,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":8,"y":10,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":9,"y":10,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":10,"y":10,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":11,"y":10,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":12,"y":10,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":13,"y":10,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":14,"y":10,"level":0,"terrain":{"incline_bottom":1}},{"x":1,"y":11,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":11,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":11,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":11,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":11,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":6,"y":11,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":7,"y":11,"level":1,"terrain":{"woods":2,"foliage_elev":2,"incline_top":1}},{"x":8,"y":11,"level":1,"terrain":{"woods":2,"foliage_elev":2,"incline_top":1}},{"x":9,"y":11,"level":1,"terrain":{"woods":2,"foliage_elev":2}},{"x":10,"y":11,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":11,"y":11,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":12,"y":11,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":11,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":14,"y":11,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":15,"y":11,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":12,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":12,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":12,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":12,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":12,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":12,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":6,"y":12,"level":0,"terrain":{"woods":2,"foliage_elev":2,"incline_bottom":1}},{"x":7,"y":12,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":8,"y":12,"level":1,"terrain":{"woods":2,"foliage_elev":2}},{"x":9,"y":12,"level":1,"terrain":{"woods":2,"foliage_elev":2}},{"x":10,"y":12,"level":1,"terrain":{"woods":2,"foliage_elev":2}},{"x":11,"y":12,"level":1},{"x":12,"y":12,"level":1},{"x":13,"y":12,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":14,"y":12,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":0,"y":13,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":13,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":13,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":13,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":4,"y":13,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":13,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":6,"y":13,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":7,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":8,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":10,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":11,"y":13,"level":1},{"x":12,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":13,"y":13,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":14,"y":13,"level":0,"terrain":{"incline_bottom":1}},{"x":0,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":14,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":4,"y":14,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":5,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":6,"y":14,"level":0,"terrain":{"incline_bottom":1}},{"x":7,"y":14,"level":0,"terrain":{"incline_bottom":1}},{"x":8,"y":14,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":9,"y":14,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":10,"y":14,"level":1,"terrain":{"woods":1,"foliage_elev":2}},{"x":11,"y":14,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":12,"y":14,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":13,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":14,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":15,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":0,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":4,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":5,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":7,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":8,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":9,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":10,"y":15,"level":1,"terrain":{"woods":1,"foliage_elev":2,"incline_top":1}},{"x":11,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":12,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}},{"x":14,"y":15,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":4,"y":16,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":6,"y":16,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":8,"y":16,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":10,"y":16,"level":0,"terrain":{"woods":1,"foliage_elev":2,"incline_bottom":1}}],"board":"forest","scenario":"pathfind-forest.mms","unit":"Phoenix Hawk PXH-1","walkMp":6,"runMp":9} +{"type":"case","x":6,"y":5,"facing":0,"mp":4,"considered":51,"legal":25,"states":[[5,4,5,4,1,0,"MOVE_WALK"],[5,5,4,4,1,0,"MOVE_WALK"],[6,4,0,3,1,0,"MOVE_WALK"],[6,4,1,4,1,0,"MOVE_WALK"],[6,4,5,4,1,0,"MOVE_WALK"],[6,5,0,0,0,0,"NONE"],[6,5,1,1,0,0,"MOVE_WALK"],[6,5,2,2,0,0,"MOVE_WALK"],[6,5,3,3,0,0,"MOVE_WALK"],[6,5,4,2,0,0,"MOVE_WALK"],[6,5,5,1,0,0,"MOVE_WALK"],[7,4,0,3,1,0,"MOVE_WALK"],[7,4,1,2,1,0,"MOVE_WALK"],[7,4,2,3,1,0,"MOVE_WALK"],[7,4,3,4,1,0,"MOVE_WALK"],[7,4,5,4,1,0,"MOVE_WALK"],[7,5,2,4,1,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":6,"y":5,"facing":0,"mp":6,"considered":114,"legal":64,"states":[[5,4,0,5,1,0,"MOVE_WALK"],[5,4,1,6,1,0,"MOVE_WALK"],[5,4,3,6,1,0,"MOVE_WALK"],[5,4,4,5,1,0,"MOVE_WALK"],[5,4,5,4,1,0,"MOVE_WALK"],[5,5,0,6,1,0,"MOVE_WALK"],[5,5,2,6,1,0,"MOVE_WALK"],[5,5,3,5,1,0,"MOVE_WALK"],[5,5,4,4,1,0,"MOVE_WALK"],[5,5,5,5,1,0,"MOVE_WALK"],[6,3,0,6,2,0,"MOVE_WALK"],[6,4,0,3,1,0,"MOVE_WALK"],[6,4,1,4,1,0,"MOVE_WALK"],[6,4,2,5,1,0,"MOVE_WALK"],[6,4,3,6,1,0,"MOVE_WALK"],[6,4,4,5,1,0,"MOVE_WALK"],[6,4,5,4,1,0,"MOVE_WALK"],[6,5,0,0,0,0,"NONE"],[6,5,1,1,0,0,"MOVE_WALK"],[6,5,2,2,0,0,"MOVE_WALK"],[6,5,3,3,0,0,"MOVE_WALK"],[6,5,4,2,0,0,"MOVE_WALK"],[6,5,5,1,0,0,"MOVE_WALK"],[7,3,0,6,2,0,"MOVE_WALK"],[7,3,1,6,2,0,"MOVE_WALK"],[7,4,0,3,1,0,"MOVE_WALK"],[7,4,1,2,1,0,"MOVE_WALK"],[7,4,2,3,1,0,"MOVE_WALK"],[7,4,3,4,1,0,"MOVE_WALK"],[7,4,4,5,1,0,"MOVE_WALK"],[7,4,5,4,1,0,"MOVE_WALK"],[7,5,0,6,1,0,"MOVE_WALK"],[7,5,1,5,1,0,"MOVE_WALK"],[7,5,2,4,1,0,"MOVE_WALK"],[7,5,3,5,1,0,"MOVE_WALK"],[7,5,4,6,1,0,"MOVE_WALK"],[8,4,1,6,2,0,"MOVE_WALK"],[8,6,2,6,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":6,"y":5,"facing":1,"mp":4,"considered":48,"legal":27,"states":[[6,4,0,4,1,0,"MOVE_WALK"],[6,5,0,1,0,0,"MOVE_WALK"],[6,5,1,0,0,0,"NONE"],[6,5,2,1,0,0,"MOVE_WALK"],[6,5,3,2,0,0,"MOVE_WALK"],[6,5,4,3,0,0,"MOVE_WALK"],[6,5,5,2,0,0,"MOVE_WALK"],[7,4,0,2,1,0,"MOVE_WALK"],[7,4,1,1,1,0,"MOVE_WALK"],[7,4,2,2,1,0,"MOVE_WALK"],[7,4,3,3,1,0,"MOVE_WALK"],[7,4,4,4,1,0,"MOVE_WALK"],[7,4,5,3,1,0,"MOVE_WALK"],[7,5,1,4,1,0,"MOVE_WALK"],[7,5,2,3,1,0,"MOVE_WALK"],[7,5,3,4,1,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":6,"y":5,"facing":1,"mp":6,"considered":126,"legal":66,"states":[[5,4,0,6,1,0,"MOVE_WALK"],[5,4,4,6,1,0,"MOVE_WALK"],[5,4,5,5,1,0,"MOVE_WALK"],[5,5,3,6,1,0,"MOVE_WALK"],[5,5,4,5,1,0,"MOVE_WALK"],[5,5,5,6,1,0,"MOVE_WALK"],[6,4,0,4,1,0,"MOVE_WALK"],[6,4,1,5,1,0,"MOVE_WALK"],[6,4,2,6,1,0,"MOVE_WALK"],[6,4,4,6,1,0,"MOVE_WALK"],[6,4,5,5,1,0,"MOVE_WALK"],[6,5,0,1,0,0,"MOVE_WALK"],[6,5,1,0,0,0,"NONE"],[6,5,2,1,0,0,"MOVE_WALK"],[6,5,3,2,0,0,"MOVE_WALK"],[6,5,4,3,0,0,"MOVE_WALK"],[6,5,5,2,0,0,"MOVE_WALK"],[6,6,3,6,1,0,"MOVE_WALK"],[7,3,0,5,2,0,"MOVE_WALK"],[7,3,1,6,2,0,"MOVE_WALK"],[7,3,5,6,2,0,"MOVE_WALK"],[7,4,0,2,1,0,"MOVE_WALK"],[7,4,1,1,1,0,"MOVE_WALK"],[7,4,2,2,1,0,"MOVE_WALK"],[7,4,3,3,1,0,"MOVE_WALK"],[7,4,4,4,1,0,"MOVE_WALK"],[7,4,5,3,1,0,"MOVE_WALK"],[7,5,0,5,1,0,"MOVE_WALK"],[7,5,1,4,1,0,"MOVE_WALK"],[7,5,2,3,1,0,"MOVE_WALK"],[7,5,3,4,1,0,"MOVE_WALK"],[7,5,4,5,1,0,"MOVE_WALK"],[7,5,5,6,1,0,"MOVE_WALK"],[7,6,3,6,2,0,"MOVE_WALK"],[8,4,0,6,2,0,"MOVE_WALK"],[8,4,1,5,2,0,"MOVE_WALK"],[8,4,2,6,2,0,"MOVE_WALK"],[8,5,2,6,2,0,"MOVE_WALK"],[8,6,1,6,2,0,"MOVE_WALK"],[8,6,2,5,2,0,"MOVE_WALK"],[8,6,3,6,2,0,"MOVE_WALK"],[9,6,2,6,3,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":7,"y":5,"facing":0,"mp":4,"considered":57,"legal":33,"states":[[6,5,0,3,1,0,"MOVE_WALK"],[6,5,1,4,1,0,"MOVE_WALK"],[6,5,3,4,1,0,"MOVE_WALK"],[6,5,4,3,1,0,"MOVE_WALK"],[6,5,5,2,1,0,"MOVE_WALK"],[7,3,0,4,2,0,"MOVE_WALK"],[7,4,0,1,1,0,"MOVE_WALK"],[7,4,1,2,1,0,"MOVE_WALK"],[7,4,2,3,1,0,"MOVE_WALK"],[7,4,3,4,1,0,"MOVE_WALK"],[7,4,4,3,1,0,"MOVE_WALK"],[7,4,5,2,1,0,"MOVE_WALK"],[7,5,0,0,0,0,"NONE"],[7,5,1,1,0,0,"MOVE_WALK"],[7,5,2,2,0,0,"MOVE_WALK"],[7,5,3,3,0,0,"MOVE_WALK"],[7,5,4,2,0,0,"MOVE_WALK"],[7,5,5,1,0,0,"MOVE_WALK"],[8,6,2,4,1,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":7,"y":5,"facing":0,"mp":6,"considered":144,"legal":76,"states":[[5,4,0,6,2,0,"MOVE_WALK"],[5,4,4,6,2,0,"MOVE_WALK"],[5,4,5,5,2,0,"MOVE_WALK"],[5,5,3,6,2,0,"MOVE_WALK"],[5,5,4,5,2,0,"MOVE_WALK"],[5,5,5,6,2,0,"MOVE_WALK"],[6,4,0,6,2,0,"MOVE_WALK"],[6,4,4,6,2,0,"MOVE_WALK"],[6,4,5,5,2,0,"MOVE_WALK"],[6,5,0,3,1,0,"MOVE_WALK"],[6,5,1,4,1,0,"MOVE_WALK"],[6,5,2,5,1,0,"MOVE_WALK"],[6,5,3,4,1,0,"MOVE_WALK"],[6,5,4,3,1,0,"MOVE_WALK"],[6,5,5,2,1,0,"MOVE_WALK"],[6,6,4,6,1,0,"MOVE_WALK"],[7,3,0,4,2,0,"MOVE_WALK"],[7,3,1,5,2,0,"MOVE_WALK"],[7,3,2,6,2,0,"MOVE_WALK"],[7,3,4,6,2,0,"MOVE_WALK"],[7,3,5,5,2,0,"MOVE_WALK"],[7,4,0,1,1,0,"MOVE_WALK"],[7,4,1,2,1,0,"MOVE_WALK"],[7,4,2,3,1,0,"MOVE_WALK"],[7,4,3,4,1,0,"MOVE_WALK"],[7,4,4,3,1,0,"MOVE_WALK"],[7,4,5,2,1,0,"MOVE_WALK"],[7,5,0,0,0,0,"NONE"],[7,5,1,1,0,0,"MOVE_WALK"],[7,5,2,2,0,0,"MOVE_WALK"],[7,5,3,3,0,0,"MOVE_WALK"],[7,5,4,2,0,0,"MOVE_WALK"],[7,5,5,1,0,0,"MOVE_WALK"],[7,6,2,6,1,0,"MOVE_WALK"],[7,6,3,5,1,0,"MOVE_WALK"],[7,6,4,6,1,0,"MOVE_WALK"],[8,4,1,6,2,0,"MOVE_WALK"],[8,5,0,6,1,0,"MOVE_WALK"],[8,5,1,5,1,0,"MOVE_WALK"],[8,5,2,6,1,0,"MOVE_WALK"],[8,6,0,6,1,0,"MOVE_WALK"],[8,6,1,5,1,0,"MOVE_WALK"],[8,6,2,4,1,0,"MOVE_WALK"],[8,6,3,5,1,0,"MOVE_WALK"],[8,6,4,6,1,0,"MOVE_WALK"],[9,6,1,6,2,0,"MOVE_WALK"],[9,6,2,5,2,0,"MOVE_WALK"],[9,6,3,6,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":7,"y":5,"facing":1,"mp":4,"considered":60,"legal":28,"states":[[6,5,0,4,1,0,"MOVE_WALK"],[6,5,4,4,1,0,"MOVE_WALK"],[6,5,5,3,1,0,"MOVE_WALK"],[7,4,0,2,1,0,"MOVE_WALK"],[7,4,1,3,1,0,"MOVE_WALK"],[7,4,2,4,1,0,"MOVE_WALK"],[7,4,4,4,1,0,"MOVE_WALK"],[7,4,5,3,1,0,"MOVE_WALK"],[7,5,0,1,0,0,"MOVE_WALK"],[7,5,1,0,0,0,"NONE"],[7,5,2,1,0,0,"MOVE_WALK"],[7,5,3,2,0,0,"MOVE_WALK"],[7,5,4,3,0,0,"MOVE_WALK"],[7,5,5,2,0,0,"MOVE_WALK"],[7,6,3,4,1,0,"MOVE_WALK"],[8,5,1,4,1,0,"MOVE_WALK"],[8,6,1,4,1,0,"MOVE_WALK"],[8,6,2,3,1,0,"MOVE_WALK"],[8,6,3,4,1,0,"MOVE_WALK"],[9,6,2,4,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":7,"y":5,"facing":1,"mp":6,"considered":138,"legal":78,"states":[[5,4,5,6,2,0,"MOVE_WALK"],[5,5,4,6,2,0,"MOVE_WALK"],[6,4,5,6,2,0,"MOVE_WALK"],[6,5,0,4,1,0,"MOVE_WALK"],[6,5,1,5,1,0,"MOVE_WALK"],[6,5,2,6,1,0,"MOVE_WALK"],[6,5,3,5,1,0,"MOVE_WALK"],[6,5,4,4,1,0,"MOVE_WALK"],[6,5,5,3,1,0,"MOVE_WALK"],[7,3,0,5,2,0,"MOVE_WALK"],[7,3,1,6,2,0,"MOVE_WALK"],[7,3,5,6,2,0,"MOVE_WALK"],[7,4,0,2,1,0,"MOVE_WALK"],[7,4,1,3,1,0,"MOVE_WALK"],[7,4,2,4,1,0,"MOVE_WALK"],[7,4,3,5,1,0,"MOVE_WALK"],[7,4,4,4,1,0,"MOVE_WALK"],[7,4,5,3,1,0,"MOVE_WALK"],[7,5,0,1,0,0,"MOVE_WALK"],[7,5,1,0,0,0,"NONE"],[7,5,2,1,0,0,"MOVE_WALK"],[7,5,3,2,0,0,"MOVE_WALK"],[7,5,4,3,0,0,"MOVE_WALK"],[7,5,5,2,0,0,"MOVE_WALK"],[7,6,1,6,1,0,"MOVE_WALK"],[7,6,2,5,1,0,"MOVE_WALK"],[7,6,3,4,1,0,"MOVE_WALK"],[7,6,4,5,1,0,"MOVE_WALK"],[7,6,5,6,1,0,"MOVE_WALK"],[8,5,0,5,1,0,"MOVE_WALK"],[8,5,1,4,1,0,"MOVE_WALK"],[8,5,2,5,1,0,"MOVE_WALK"],[8,5,3,6,1,0,"MOVE_WALK"],[8,5,5,6,1,0,"MOVE_WALK"],[8,6,0,5,1,0,"MOVE_WALK"],[8,6,1,4,1,0,"MOVE_WALK"],[8,6,2,3,1,0,"MOVE_WALK"],[8,6,3,4,1,0,"MOVE_WALK"],[8,6,4,5,1,0,"MOVE_WALK"],[8,6,5,6,1,0,"MOVE_WALK"],[8,7,3,6,2,0,"MOVE_WALK"],[9,6,0,6,2,0,"MOVE_WALK"],[9,6,1,5,2,0,"MOVE_WALK"],[9,6,2,4,2,0,"MOVE_WALK"],[9,6,3,5,2,0,"MOVE_WALK"],[9,6,4,6,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":4,"y":8,"facing":0,"mp":4,"considered":36,"legal":18,"states":[[3,7,5,4,1,0,"MOVE_WALK"],[3,8,4,4,1,0,"MOVE_WALK"],[4,7,0,3,1,0,"MOVE_WALK"],[4,7,1,4,1,0,"MOVE_WALK"],[4,7,5,4,1,0,"MOVE_WALK"],[4,8,0,0,0,0,"NONE"],[4,8,1,1,0,0,"MOVE_WALK"],[4,8,2,2,0,0,"MOVE_WALK"],[4,8,3,3,0,0,"MOVE_WALK"],[4,8,4,2,0,0,"MOVE_WALK"],[4,8,5,1,0,0,"MOVE_WALK"],[5,7,1,4,1,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":4,"y":8,"facing":0,"mp":6,"considered":102,"legal":51,"states":[[2,7,5,6,2,0,"MOVE_WALK"],[3,7,0,5,1,0,"MOVE_WALK"],[3,7,1,6,1,0,"MOVE_WALK"],[3,7,3,6,1,0,"MOVE_WALK"],[3,7,4,5,1,0,"MOVE_WALK"],[3,7,5,4,1,0,"MOVE_WALK"],[3,8,0,6,1,0,"MOVE_WALK"],[3,8,2,6,1,0,"MOVE_WALK"],[3,8,3,5,1,0,"MOVE_WALK"],[3,8,4,4,1,0,"MOVE_WALK"],[3,8,5,5,1,0,"MOVE_WALK"],[4,6,0,6,2,0,"MOVE_WALK"],[4,7,0,3,1,0,"MOVE_WALK"],[4,7,1,4,1,0,"MOVE_WALK"],[4,7,2,5,1,0,"MOVE_WALK"],[4,7,3,6,1,0,"MOVE_WALK"],[4,7,4,5,1,0,"MOVE_WALK"],[4,7,5,4,1,0,"MOVE_WALK"],[4,8,0,0,0,0,"NONE"],[4,8,1,1,0,0,"MOVE_WALK"],[4,8,2,2,0,0,"MOVE_WALK"],[4,8,3,3,0,0,"MOVE_WALK"],[4,8,4,2,0,0,"MOVE_WALK"],[4,8,5,1,0,0,"MOVE_WALK"],[4,9,3,6,1,0,"MOVE_WALK"],[5,7,0,5,1,0,"MOVE_WALK"],[5,7,1,4,1,0,"MOVE_WALK"],[5,7,2,5,1,0,"MOVE_WALK"],[5,7,3,6,1,0,"MOVE_WALK"],[5,7,5,6,1,0,"MOVE_WALK"],[5,8,1,6,1,0,"MOVE_WALK"],[5,8,2,5,1,0,"MOVE_WALK"],[5,8,3,6,1,0,"MOVE_WALK"],[6,8,2,6,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":4,"y":8,"facing":1,"mp":4,"considered":33,"legal":17,"states":[[4,7,0,4,1,0,"MOVE_WALK"],[4,8,0,1,0,0,"MOVE_WALK"],[4,8,1,0,0,0,"NONE"],[4,8,2,1,0,0,"MOVE_WALK"],[4,8,3,2,0,0,"MOVE_WALK"],[4,8,4,3,0,0,"MOVE_WALK"],[4,8,5,2,0,0,"MOVE_WALK"],[5,7,0,4,1,0,"MOVE_WALK"],[5,7,1,3,1,0,"MOVE_WALK"],[5,7,2,4,1,0,"MOVE_WALK"],[5,8,2,4,1,0,"MOVE_WALK"]],"board":"forest"} +{"type":"case","x":4,"y":8,"facing":1,"mp":6,"considered":108,"legal":52,"states":[[3,7,0,6,1,0,"MOVE_WALK"],[3,7,4,6,1,0,"MOVE_WALK"],[3,7,5,5,1,0,"MOVE_WALK"],[3,8,3,6,1,0,"MOVE_WALK"],[3,8,4,5,1,0,"MOVE_WALK"],[3,8,5,6,1,0,"MOVE_WALK"],[4,7,0,4,1,0,"MOVE_WALK"],[4,7,1,5,1,0,"MOVE_WALK"],[4,7,2,6,1,0,"MOVE_WALK"],[4,7,4,6,1,0,"MOVE_WALK"],[4,7,5,5,1,0,"MOVE_WALK"],[4,8,0,1,0,0,"MOVE_WALK"],[4,8,1,0,0,0,"NONE"],[4,8,2,1,0,0,"MOVE_WALK"],[4,8,3,2,0,0,"MOVE_WALK"],[4,8,4,3,0,0,"MOVE_WALK"],[4,8,5,2,0,0,"MOVE_WALK"],[4,9,2,6,1,0,"MOVE_WALK"],[4,9,3,5,1,0,"MOVE_WALK"],[4,9,4,6,1,0,"MOVE_WALK"],[5,7,0,4,1,0,"MOVE_WALK"],[5,7,1,3,1,0,"MOVE_WALK"],[5,7,2,4,1,0,"MOVE_WALK"],[5,7,3,5,1,0,"MOVE_WALK"],[5,7,4,6,1,0,"MOVE_WALK"],[5,7,5,5,1,0,"MOVE_WALK"],[5,8,0,6,1,0,"MOVE_WALK"],[5,8,1,5,1,0,"MOVE_WALK"],[5,8,2,4,1,0,"MOVE_WALK"],[5,8,3,5,1,0,"MOVE_WALK"],[5,8,4,6,1,0,"MOVE_WALK"],[6,7,1,6,2,0,"MOVE_WALK"],[6,8,1,6,2,0,"MOVE_WALK"],[6,8,2,5,2,0,"MOVE_WALK"],[6,8,3,6,2,0,"MOVE_WALK"],[6,9,2,6,2,0,"MOVE_WALK"]],"board":"forest"} +{"type":"board","width":16,"height":17,"hexes":[{"x":1,"y":3,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":3,"y":3,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":2,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":3,"y":4,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":4,"y":4,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":1,"y":5,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":5,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":7,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":8,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":8,"y":9,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":9,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":10,"y":9,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":11,"y":9,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":8,"y":10,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":10,"y":10,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":10,"y":11,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":13,"level":0,"terrain":{"woods":1,"foliage_elev":2}},{"x":1,"y":14,"level":0,"terrain":{"woods":2,"foliage_elev":2}},{"x":2,"y":14,"level":0,"terrain":{"woods":1,"foliage_elev":2}}],"board":"open","scenario":"pathfind-open.mms","unit":"Phoenix Hawk PXH-1","walkMp":6,"runMp":9} +{"type":"case","x":8,"y":8,"facing":0,"mp":4,"considered":147,"legal":66,"states":[[5,6,5,4,3,0,"MOVE_WALK"],[6,6,5,4,3,0,"MOVE_WALK"],[6,7,0,4,2,0,"MOVE_WALK"],[6,7,4,4,2,0,"MOVE_WALK"],[6,7,5,3,2,0,"MOVE_WALK"],[6,8,4,4,2,0,"MOVE_WALK"],[6,9,4,4,2,0,"MOVE_WALK"],[7,5,5,4,3,0,"MOVE_WALK"],[7,6,0,4,2,0,"MOVE_WALK"],[7,6,4,4,2,0,"MOVE_WALK"],[7,6,5,3,2,0,"MOVE_WALK"],[7,7,0,3,1,0,"MOVE_WALK"],[7,7,1,4,1,0,"MOVE_WALK"],[7,7,3,4,1,0,"MOVE_WALK"],[7,7,4,3,1,0,"MOVE_WALK"],[7,7,5,2,1,0,"MOVE_WALK"],[7,8,3,4,1,0,"MOVE_WALK"],[7,8,4,3,1,0,"MOVE_WALK"],[7,8,5,4,1,0,"MOVE_WALK"],[8,4,0,4,4,0,"MOVE_WALK"],[8,5,0,3,3,0,"MOVE_WALK"],[8,5,1,4,3,0,"MOVE_WALK"],[8,5,5,4,3,0,"MOVE_WALK"],[8,6,0,2,2,0,"MOVE_WALK"],[8,6,1,3,2,0,"MOVE_WALK"],[8,6,2,4,2,0,"MOVE_WALK"],[8,6,4,4,2,0,"MOVE_WALK"],[8,6,5,3,2,0,"MOVE_WALK"],[8,7,0,1,1,0,"MOVE_WALK"],[8,7,1,2,1,0,"MOVE_WALK"],[8,7,2,3,1,0,"MOVE_WALK"],[8,7,3,4,1,0,"MOVE_WALK"],[8,7,4,3,1,0,"MOVE_WALK"],[8,7,5,2,1,0,"MOVE_WALK"],[8,8,0,0,0,0,"NONE"],[8,8,1,1,0,0,"MOVE_WALK"],[8,8,2,2,0,0,"MOVE_WALK"],[8,8,3,3,0,0,"MOVE_WALK"],[8,8,4,2,0,0,"MOVE_WALK"],[8,8,5,1,0,0,"MOVE_WALK"],[9,5,1,4,3,0,"MOVE_WALK"],[9,6,0,4,2,0,"MOVE_WALK"],[9,6,1,3,2,0,"MOVE_WALK"],[9,6,2,4,2,0,"MOVE_WALK"],[9,7,0,4,1,0,"MOVE_WALK"],[9,7,1,3,1,0,"MOVE_WALK"],[9,7,2,4,1,0,"MOVE_WALK"],[10,6,1,4,3,0,"MOVE_WALK"],[10,7,1,4,2,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":8,"y":8,"facing":0,"mp":6,"considered":516,"legal":286,"states":[[3,5,5,6,5,0,"MOVE_WALK"],[4,5,5,6,5,0,"MOVE_WALK"],[4,6,0,6,4,0,"MOVE_WALK"],[4,6,4,6,4,0,"MOVE_WALK"],[4,6,5,5,4,0,"MOVE_WALK"],[4,7,4,6,4,0,"MOVE_WALK"],[4,8,4,6,4,0,"MOVE_WALK"],[4,9,4,6,4,0,"MOVE_WALK"],[4,10,4,6,4,0,"MOVE_WALK"],[5,4,5,6,5,0,"MOVE_WALK"],[5,5,0,6,4,0,"MOVE_WALK"],[5,5,4,6,4,0,"MOVE_WALK"],[5,5,5,5,4,0,"MOVE_WALK"],[5,6,0,5,3,0,"MOVE_WALK"],[5,6,1,6,3,0,"MOVE_WALK"],[5,6,3,6,3,0,"MOVE_WALK"],[5,6,4,5,3,0,"MOVE_WALK"],[5,6,5,4,3,0,"MOVE_WALK"],[5,7,3,6,3,0,"MOVE_WALK"],[5,7,4,5,3,0,"MOVE_WALK"],[5,7,5,6,3,0,"MOVE_WALK"],[5,8,3,6,3,0,"MOVE_WALK"],[5,8,4,5,3,0,"MOVE_WALK"],[5,8,5,6,3,0,"MOVE_WALK"],[5,9,3,6,3,0,"MOVE_WALK"],[5,9,4,5,3,0,"MOVE_WALK"],[5,9,5,6,3,0,"MOVE_WALK"],[6,4,5,6,5,0,"MOVE_WALK"],[6,5,0,6,4,0,"MOVE_WALK"],[6,5,4,6,4,0,"MOVE_WALK"],[6,5,5,5,4,0,"MOVE_WALK"],[6,6,0,5,3,0,"MOVE_WALK"],[6,6,1,6,3,0,"MOVE_WALK"],[6,6,3,6,3,0,"MOVE_WALK"],[6,6,4,5,3,0,"MOVE_WALK"],[6,6,5,4,3,0,"MOVE_WALK"],[6,7,0,4,2,0,"MOVE_WALK"],[6,7,1,5,2,0,"MOVE_WALK"],[6,7,2,6,2,0,"MOVE_WALK"],[6,7,3,5,2,0,"MOVE_WALK"],[6,7,4,4,2,0,"MOVE_WALK"],[6,7,5,3,2,0,"MOVE_WALK"],[6,8,0,6,2,0,"MOVE_WALK"],[6,8,2,6,2,0,"MOVE_WALK"],[6,8,3,5,2,0,"MOVE_WALK"],[6,8,4,4,2,0,"MOVE_WALK"],[6,8,5,5,2,0,"MOVE_WALK"],[6,9,0,6,2,0,"MOVE_WALK"],[6,9,2,6,2,0,"MOVE_WALK"],[6,9,3,5,2,0,"MOVE_WALK"],[6,9,4,4,2,0,"MOVE_WALK"],[6,9,5,5,2,0,"MOVE_WALK"],[6,10,3,6,3,0,"MOVE_WALK"],[7,3,5,6,5,0,"MOVE_WALK"],[7,4,0,6,4,0,"MOVE_WALK"],[7,4,4,6,4,0,"MOVE_WALK"],[7,4,5,5,4,0,"MOVE_WALK"],[7,5,0,5,3,0,"MOVE_WALK"],[7,5,1,6,3,0,"MOVE_WALK"],[7,5,3,6,3,0,"MOVE_WALK"],[7,5,4,5,3,0,"MOVE_WALK"],[7,5,5,4,3,0,"MOVE_WALK"],[7,6,0,4,2,0,"MOVE_WALK"],[7,6,1,5,2,0,"MOVE_WALK"],[7,6,2,6,2,0,"MOVE_WALK"],[7,6,3,5,2,0,"MOVE_WALK"],[7,6,4,4,2,0,"MOVE_WALK"],[7,6,5,3,2,0,"MOVE_WALK"],[7,7,0,3,1,0,"MOVE_WALK"],[7,7,1,4,1,0,"MOVE_WALK"],[7,7,2,5,1,0,"MOVE_WALK"],[7,7,3,4,1,0,"MOVE_WALK"],[7,7,4,3,1,0,"MOVE_WALK"],[7,7,5,2,1,0,"MOVE_WALK"],[7,8,0,5,1,0,"MOVE_WALK"],[7,8,1,6,1,0,"MOVE_WALK"],[7,8,2,5,1,0,"MOVE_WALK"],[7,8,3,4,1,0,"MOVE_WALK"],[7,8,4,3,1,0,"MOVE_WALK"],[7,8,5,4,1,0,"MOVE_WALK"],[7,9,2,6,2,0,"MOVE_WALK"],[7,9,3,5,2,0,"MOVE_WALK"],[7,9,4,6,2,0,"MOVE_WALK"],[7,10,3,6,3,0,"MOVE_WALK"],[8,2,0,6,6,0,"MOVE_WALK"],[8,3,0,5,5,0,"MOVE_WALK"],[8,3,1,6,5,0,"MOVE_WALK"],[8,3,5,6,5,0,"MOVE_WALK"],[8,4,0,4,4,0,"MOVE_WALK"],[8,4,1,5,4,0,"MOVE_WALK"],[8,4,2,6,4,0,"MOVE_WALK"],[8,4,4,6,4,0,"MOVE_WALK"],[8,4,5,5,4,0,"MOVE_WALK"],[8,5,0,3,3,0,"MOVE_WALK"],[8,5,1,4,3,0,"MOVE_WALK"],[8,5,2,5,3,0,"MOVE_WALK"],[8,5,3,6,3,0,"MOVE_WALK"],[8,5,4,5,3,0,"MOVE_WALK"],[8,5,5,4,3,0,"MOVE_WALK"],[8,6,0,2,2,0,"MOVE_WALK"],[8,6,1,3,2,0,"MOVE_WALK"],[8,6,2,4,2,0,"MOVE_WALK"],[8,6,3,5,2,0,"MOVE_WALK"],[8,6,4,4,2,0,"MOVE_WALK"],[8,6,5,3,2,0,"MOVE_WALK"],[8,7,0,1,1,0,"MOVE_WALK"],[8,7,1,2,1,0,"MOVE_WALK"],[8,7,2,3,1,0,"MOVE_WALK"],[8,7,3,4,1,0,"MOVE_WALK"],[8,7,4,3,1,0,"MOVE_WALK"],[8,7,5,2,1,0,"MOVE_WALK"],[8,8,0,0,0,0,"NONE"],[8,8,1,1,0,0,"MOVE_WALK"],[8,8,2,2,0,0,"MOVE_WALK"],[8,8,3,3,0,0,"MOVE_WALK"],[8,8,4,2,0,0,"MOVE_WALK"],[8,8,5,1,0,0,"MOVE_WALK"],[8,9,2,6,1,0,"MOVE_WALK"],[8,9,3,5,1,0,"MOVE_WALK"],[8,9,4,6,1,0,"MOVE_WALK"],[9,3,1,6,5,0,"MOVE_WALK"],[9,4,0,6,4,0,"MOVE_WALK"],[9,4,1,5,4,0,"MOVE_WALK"],[9,4,2,6,4,0,"MOVE_WALK"],[9,5,0,5,3,0,"MOVE_WALK"],[9,5,1,4,3,0,"MOVE_WALK"],[9,5,2,5,3,0,"MOVE_WALK"],[9,5,3,6,3,0,"MOVE_WALK"],[9,5,5,6,3,0,"MOVE_WALK"],[9,6,0,4,2,0,"MOVE_WALK"],[9,6,1,3,2,0,"MOVE_WALK"],[9,6,2,4,2,0,"MOVE_WALK"],[9,6,3,5,2,0,"MOVE_WALK"],[9,6,4,6,2,0,"MOVE_WALK"],[9,6,5,5,2,0,"MOVE_WALK"],[9,7,0,4,1,0,"MOVE_WALK"],[9,7,1,3,1,0,"MOVE_WALK"],[9,7,2,4,1,0,"MOVE_WALK"],[9,7,3,5,1,0,"MOVE_WALK"],[9,7,4,6,1,0,"MOVE_WALK"],[9,7,5,5,1,0,"MOVE_WALK"],[9,8,1,6,1,0,"MOVE_WALK"],[9,8,2,5,1,0,"MOVE_WALK"],[9,8,3,6,1,0,"MOVE_WALK"],[10,4,1,6,5,0,"MOVE_WALK"],[10,5,0,6,4,0,"MOVE_WALK"],[10,5,1,5,4,0,"MOVE_WALK"],[10,5,2,6,4,0,"MOVE_WALK"],[10,6,0,5,3,0,"MOVE_WALK"],[10,6,1,4,3,0,"MOVE_WALK"],[10,6,2,5,3,0,"MOVE_WALK"],[10,6,3,6,3,0,"MOVE_WALK"],[10,6,5,6,3,0,"MOVE_WALK"],[10,7,0,5,2,0,"MOVE_WALK"],[10,7,1,4,2,0,"MOVE_WALK"],[10,7,2,5,2,0,"MOVE_WALK"],[10,7,3,6,2,0,"MOVE_WALK"],[10,7,5,6,2,0,"MOVE_WALK"],[10,8,1,6,2,0,"MOVE_WALK"],[10,8,2,5,2,0,"MOVE_WALK"],[10,8,3,6,2,0,"MOVE_WALK"],[11,4,1,6,5,0,"MOVE_WALK"],[11,5,0,6,4,0,"MOVE_WALK"],[11,5,1,5,4,0,"MOVE_WALK"],[11,5,2,6,4,0,"MOVE_WALK"],[11,6,0,6,3,0,"MOVE_WALK"],[11,6,1,5,3,0,"MOVE_WALK"],[11,6,2,6,3,0,"MOVE_WALK"],[11,7,2,6,3,0,"MOVE_WALK"],[11,8,2,6,3,0,"MOVE_WALK"],[12,5,1,6,5,0,"MOVE_WALK"],[12,6,1,6,4,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":8,"y":8,"facing":1,"mp":4,"considered":105,"legal":45,"states":[[6,7,5,4,2,0,"MOVE_WALK"],[7,6,5,4,2,0,"MOVE_WALK"],[7,7,0,4,1,0,"MOVE_WALK"],[7,7,4,4,1,0,"MOVE_WALK"],[7,7,5,3,1,0,"MOVE_WALK"],[7,8,4,4,1,0,"MOVE_WALK"],[8,5,0,4,3,0,"MOVE_WALK"],[8,6,0,3,2,0,"MOVE_WALK"],[8,6,1,4,2,0,"MOVE_WALK"],[8,6,5,4,2,0,"MOVE_WALK"],[8,7,0,2,1,0,"MOVE_WALK"],[8,7,1,3,1,0,"MOVE_WALK"],[8,7,2,4,1,0,"MOVE_WALK"],[8,7,4,4,1,0,"MOVE_WALK"],[8,7,5,3,1,0,"MOVE_WALK"],[8,8,0,1,0,0,"MOVE_WALK"],[8,8,1,0,0,0,"NONE"],[8,8,2,1,0,0,"MOVE_WALK"],[8,8,3,2,0,0,"MOVE_WALK"],[8,8,4,3,0,0,"MOVE_WALK"],[8,8,5,2,0,0,"MOVE_WALK"],[8,9,3,4,1,0,"MOVE_WALK"],[9,6,0,4,2,0,"MOVE_WALK"],[9,6,1,4,2,0,"MOVE_WALK"],[9,7,0,3,1,0,"MOVE_WALK"],[9,7,1,2,1,0,"MOVE_WALK"],[9,7,2,3,1,0,"MOVE_WALK"],[9,7,3,4,1,0,"MOVE_WALK"],[9,7,5,4,1,0,"MOVE_WALK"],[9,8,2,4,1,0,"MOVE_WALK"],[10,7,0,4,2,0,"MOVE_WALK"],[10,7,1,3,2,0,"MOVE_WALK"],[10,7,2,4,2,0,"MOVE_WALK"],[10,8,2,4,2,0,"MOVE_WALK"],[11,6,1,4,3,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":8,"y":8,"facing":1,"mp":6,"considered":417,"legal":218,"states":[[4,6,5,6,4,0,"MOVE_WALK"],[5,5,5,6,4,0,"MOVE_WALK"],[5,6,0,6,3,0,"MOVE_WALK"],[5,6,4,6,3,0,"MOVE_WALK"],[5,6,5,5,3,0,"MOVE_WALK"],[5,7,4,6,3,0,"MOVE_WALK"],[5,8,4,6,3,0,"MOVE_WALK"],[5,9,4,6,3,0,"MOVE_WALK"],[6,5,5,6,4,0,"MOVE_WALK"],[6,6,0,6,3,0,"MOVE_WALK"],[6,6,4,6,3,0,"MOVE_WALK"],[6,6,5,5,3,0,"MOVE_WALK"],[6,7,0,5,2,0,"MOVE_WALK"],[6,7,1,6,2,0,"MOVE_WALK"],[6,7,3,6,2,0,"MOVE_WALK"],[6,7,4,5,2,0,"MOVE_WALK"],[6,7,5,4,2,0,"MOVE_WALK"],[6,8,3,6,2,0,"MOVE_WALK"],[6,8,4,5,2,0,"MOVE_WALK"],[6,8,5,6,2,0,"MOVE_WALK"],[6,9,3,6,2,0,"MOVE_WALK"],[6,9,4,5,2,0,"MOVE_WALK"],[6,9,5,6,2,0,"MOVE_WALK"],[7,4,5,6,4,0,"MOVE_WALK"],[7,5,0,6,3,0,"MOVE_WALK"],[7,5,4,6,3,0,"MOVE_WALK"],[7,5,5,5,3,0,"MOVE_WALK"],[7,6,0,5,2,0,"MOVE_WALK"],[7,6,1,6,2,0,"MOVE_WALK"],[7,6,3,6,2,0,"MOVE_WALK"],[7,6,4,5,2,0,"MOVE_WALK"],[7,6,5,4,2,0,"MOVE_WALK"],[7,7,0,4,1,0,"MOVE_WALK"],[7,7,1,5,1,0,"MOVE_WALK"],[7,7,2,6,1,0,"MOVE_WALK"],[7,7,3,5,1,0,"MOVE_WALK"],[7,7,4,4,1,0,"MOVE_WALK"],[7,7,5,3,1,0,"MOVE_WALK"],[7,8,0,6,1,0,"MOVE_WALK"],[7,8,2,6,1,0,"MOVE_WALK"],[7,8,3,5,1,0,"MOVE_WALK"],[7,8,4,4,1,0,"MOVE_WALK"],[7,8,5,5,1,0,"MOVE_WALK"],[7,9,3,6,2,0,"MOVE_WALK"],[7,9,4,6,2,0,"MOVE_WALK"],[8,3,0,6,5,0,"MOVE_WALK"],[8,4,0,5,4,0,"MOVE_WALK"],[8,4,1,6,4,0,"MOVE_WALK"],[8,4,5,6,4,0,"MOVE_WALK"],[8,5,0,4,3,0,"MOVE_WALK"],[8,5,1,5,3,0,"MOVE_WALK"],[8,5,2,6,3,0,"MOVE_WALK"],[8,5,4,6,3,0,"MOVE_WALK"],[8,5,5,5,3,0,"MOVE_WALK"],[8,6,0,3,2,0,"MOVE_WALK"],[8,6,1,4,2,0,"MOVE_WALK"],[8,6,2,5,2,0,"MOVE_WALK"],[8,6,3,6,2,0,"MOVE_WALK"],[8,6,4,5,2,0,"MOVE_WALK"],[8,6,5,4,2,0,"MOVE_WALK"],[8,7,0,2,1,0,"MOVE_WALK"],[8,7,1,3,1,0,"MOVE_WALK"],[8,7,2,4,1,0,"MOVE_WALK"],[8,7,3,5,1,0,"MOVE_WALK"],[8,7,4,4,1,0,"MOVE_WALK"],[8,7,5,3,1,0,"MOVE_WALK"],[8,8,0,1,0,0,"MOVE_WALK"],[8,8,1,0,0,0,"NONE"],[8,8,2,1,0,0,"MOVE_WALK"],[8,8,3,2,0,0,"MOVE_WALK"],[8,8,4,3,0,0,"MOVE_WALK"],[8,8,5,2,0,0,"MOVE_WALK"],[8,9,1,6,1,0,"MOVE_WALK"],[8,9,2,5,1,0,"MOVE_WALK"],[8,9,3,4,1,0,"MOVE_WALK"],[8,9,4,5,1,0,"MOVE_WALK"],[8,9,5,6,1,0,"MOVE_WALK"],[8,10,3,6,2,0,"MOVE_WALK"],[9,4,0,6,4,0,"MOVE_WALK"],[9,4,1,6,4,0,"MOVE_WALK"],[9,5,0,5,3,0,"MOVE_WALK"],[9,5,1,5,3,0,"MOVE_WALK"],[9,5,2,6,3,0,"MOVE_WALK"],[9,5,5,6,3,0,"MOVE_WALK"],[9,6,0,4,2,0,"MOVE_WALK"],[9,6,1,4,2,0,"MOVE_WALK"],[9,6,2,5,2,0,"MOVE_WALK"],[9,6,3,6,2,0,"MOVE_WALK"],[9,6,4,6,2,0,"MOVE_WALK"],[9,6,5,5,2,0,"MOVE_WALK"],[9,7,0,3,1,0,"MOVE_WALK"],[9,7,1,2,1,0,"MOVE_WALK"],[9,7,2,3,1,0,"MOVE_WALK"],[9,7,3,4,1,0,"MOVE_WALK"],[9,7,4,5,1,0,"MOVE_WALK"],[9,7,5,4,1,0,"MOVE_WALK"],[9,8,0,6,1,0,"MOVE_WALK"],[9,8,1,5,1,0,"MOVE_WALK"],[9,8,2,4,1,0,"MOVE_WALK"],[9,8,3,5,1,0,"MOVE_WALK"],[9,8,4,6,1,0,"MOVE_WALK"],[10,5,0,6,4,0,"MOVE_WALK"],[10,5,1,6,4,0,"MOVE_WALK"],[10,6,0,5,3,0,"MOVE_WALK"],[10,6,1,5,3,0,"MOVE_WALK"],[10,6,2,6,3,0,"MOVE_WALK"],[10,6,5,6,3,0,"MOVE_WALK"],[10,7,0,4,2,0,"MOVE_WALK"],[10,7,1,3,2,0,"MOVE_WALK"],[10,7,2,4,2,0,"MOVE_WALK"],[10,7,3,5,2,0,"MOVE_WALK"],[10,7,4,6,2,0,"MOVE_WALK"],[10,7,5,5,2,0,"MOVE_WALK"],[10,8,0,6,2,0,"MOVE_WALK"],[10,8,1,5,2,0,"MOVE_WALK"],[10,8,2,4,2,0,"MOVE_WALK"],[10,8,3,5,2,0,"MOVE_WALK"],[10,8,4,6,2,0,"MOVE_WALK"],[10,9,2,6,2,0,"MOVE_WALK"],[11,5,0,6,4,0,"MOVE_WALK"],[11,5,1,6,4,0,"MOVE_WALK"],[11,6,0,5,3,0,"MOVE_WALK"],[11,6,1,4,3,0,"MOVE_WALK"],[11,6,2,5,3,0,"MOVE_WALK"],[11,6,3,6,3,0,"MOVE_WALK"],[11,6,5,6,3,0,"MOVE_WALK"],[11,7,1,6,3,0,"MOVE_WALK"],[11,7,2,5,3,0,"MOVE_WALK"],[11,7,3,6,3,0,"MOVE_WALK"],[11,8,1,6,3,0,"MOVE_WALK"],[11,8,2,5,3,0,"MOVE_WALK"],[11,8,3,6,3,0,"MOVE_WALK"],[12,6,0,6,4,0,"MOVE_WALK"],[12,6,1,5,4,0,"MOVE_WALK"],[12,6,2,6,4,0,"MOVE_WALK"],[12,7,2,6,4,0,"MOVE_WALK"],[12,8,2,6,4,0,"MOVE_WALK"],[12,9,2,6,4,0,"MOVE_WALK"],[13,5,1,6,5,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":7,"y":8,"facing":0,"mp":4,"considered":159,"legal":74,"states":[[4,7,5,4,3,0,"MOVE_WALK"],[5,6,5,4,3,0,"MOVE_WALK"],[5,7,0,4,2,0,"MOVE_WALK"],[5,7,4,4,2,0,"MOVE_WALK"],[5,7,5,3,2,0,"MOVE_WALK"],[5,8,4,4,2,0,"MOVE_WALK"],[5,9,4,4,2,0,"MOVE_WALK"],[6,6,5,4,3,0,"MOVE_WALK"],[6,7,0,4,2,0,"MOVE_WALK"],[6,7,4,4,2,0,"MOVE_WALK"],[6,7,5,3,2,0,"MOVE_WALK"],[6,8,0,3,1,0,"MOVE_WALK"],[6,8,1,4,1,0,"MOVE_WALK"],[6,8,3,4,1,0,"MOVE_WALK"],[6,8,4,3,1,0,"MOVE_WALK"],[6,8,5,2,1,0,"MOVE_WALK"],[6,9,3,4,1,0,"MOVE_WALK"],[6,9,4,3,1,0,"MOVE_WALK"],[6,9,5,4,1,0,"MOVE_WALK"],[7,4,0,4,4,0,"MOVE_WALK"],[7,5,0,3,3,0,"MOVE_WALK"],[7,5,1,4,3,0,"MOVE_WALK"],[7,5,5,4,3,0,"MOVE_WALK"],[7,6,0,2,2,0,"MOVE_WALK"],[7,6,1,3,2,0,"MOVE_WALK"],[7,6,2,4,2,0,"MOVE_WALK"],[7,6,4,4,2,0,"MOVE_WALK"],[7,6,5,3,2,0,"MOVE_WALK"],[7,7,0,1,1,0,"MOVE_WALK"],[7,7,1,2,1,0,"MOVE_WALK"],[7,7,2,3,1,0,"MOVE_WALK"],[7,7,3,4,1,0,"MOVE_WALK"],[7,7,4,3,1,0,"MOVE_WALK"],[7,7,5,2,1,0,"MOVE_WALK"],[7,8,0,0,0,0,"NONE"],[7,8,1,1,0,0,"MOVE_WALK"],[7,8,2,2,0,0,"MOVE_WALK"],[7,8,3,3,0,0,"MOVE_WALK"],[7,8,4,2,0,0,"MOVE_WALK"],[7,8,5,1,0,0,"MOVE_WALK"],[7,9,3,4,1,0,"MOVE_WALK"],[8,6,1,4,3,0,"MOVE_WALK"],[8,7,0,4,2,0,"MOVE_WALK"],[8,7,1,3,2,0,"MOVE_WALK"],[8,7,2,4,2,0,"MOVE_WALK"],[8,8,0,3,1,0,"MOVE_WALK"],[8,8,1,2,1,0,"MOVE_WALK"],[8,8,2,3,1,0,"MOVE_WALK"],[8,8,3,4,1,0,"MOVE_WALK"],[8,8,5,4,1,0,"MOVE_WALK"],[8,9,2,4,1,0,"MOVE_WALK"],[9,6,1,4,3,0,"MOVE_WALK"],[9,7,1,4,2,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":7,"y":8,"facing":0,"mp":6,"considered":531,"legal":302,"states":[[2,6,5,6,5,0,"MOVE_WALK"],[3,5,5,6,5,0,"MOVE_WALK"],[3,6,0,6,4,0,"MOVE_WALK"],[3,6,4,6,4,0,"MOVE_WALK"],[3,6,5,5,4,0,"MOVE_WALK"],[3,7,4,6,4,0,"MOVE_WALK"],[3,8,4,6,4,0,"MOVE_WALK"],[3,9,4,6,4,0,"MOVE_WALK"],[3,10,4,6,4,0,"MOVE_WALK"],[4,5,5,6,5,0,"MOVE_WALK"],[4,6,0,6,4,0,"MOVE_WALK"],[4,6,4,6,4,0,"MOVE_WALK"],[4,6,5,5,4,0,"MOVE_WALK"],[4,7,0,5,3,0,"MOVE_WALK"],[4,7,1,6,3,0,"MOVE_WALK"],[4,7,3,6,3,0,"MOVE_WALK"],[4,7,4,5,3,0,"MOVE_WALK"],[4,7,5,4,3,0,"MOVE_WALK"],[4,8,3,6,3,0,"MOVE_WALK"],[4,8,4,5,3,0,"MOVE_WALK"],[4,8,5,6,3,0,"MOVE_WALK"],[4,9,3,6,3,0,"MOVE_WALK"],[4,9,4,5,3,0,"MOVE_WALK"],[4,9,5,6,3,0,"MOVE_WALK"],[4,10,3,6,3,0,"MOVE_WALK"],[4,10,4,5,3,0,"MOVE_WALK"],[4,10,5,6,3,0,"MOVE_WALK"],[5,4,5,6,5,0,"MOVE_WALK"],[5,5,0,6,4,0,"MOVE_WALK"],[5,5,4,6,4,0,"MOVE_WALK"],[5,5,5,5,4,0,"MOVE_WALK"],[5,6,0,5,3,0,"MOVE_WALK"],[5,6,1,6,3,0,"MOVE_WALK"],[5,6,3,6,3,0,"MOVE_WALK"],[5,6,4,5,3,0,"MOVE_WALK"],[5,6,5,4,3,0,"MOVE_WALK"],[5,7,0,4,2,0,"MOVE_WALK"],[5,7,1,5,2,0,"MOVE_WALK"],[5,7,2,6,2,0,"MOVE_WALK"],[5,7,3,5,2,0,"MOVE_WALK"],[5,7,4,4,2,0,"MOVE_WALK"],[5,7,5,3,2,0,"MOVE_WALK"],[5,8,0,6,2,0,"MOVE_WALK"],[5,8,2,6,2,0,"MOVE_WALK"],[5,8,3,5,2,0,"MOVE_WALK"],[5,8,4,4,2,0,"MOVE_WALK"],[5,8,5,5,2,0,"MOVE_WALK"],[5,9,0,6,2,0,"MOVE_WALK"],[5,9,2,6,2,0,"MOVE_WALK"],[5,9,3,5,2,0,"MOVE_WALK"],[5,9,4,4,2,0,"MOVE_WALK"],[5,9,5,5,2,0,"MOVE_WALK"],[5,10,3,6,3,0,"MOVE_WALK"],[6,4,5,6,5,0,"MOVE_WALK"],[6,5,0,6,4,0,"MOVE_WALK"],[6,5,4,6,4,0,"MOVE_WALK"],[6,5,5,5,4,0,"MOVE_WALK"],[6,6,0,5,3,0,"MOVE_WALK"],[6,6,1,6,3,0,"MOVE_WALK"],[6,6,3,6,3,0,"MOVE_WALK"],[6,6,4,5,3,0,"MOVE_WALK"],[6,6,5,4,3,0,"MOVE_WALK"],[6,7,0,4,2,0,"MOVE_WALK"],[6,7,1,5,2,0,"MOVE_WALK"],[6,7,2,6,2,0,"MOVE_WALK"],[6,7,3,5,2,0,"MOVE_WALK"],[6,7,4,4,2,0,"MOVE_WALK"],[6,7,5,3,2,0,"MOVE_WALK"],[6,8,0,3,1,0,"MOVE_WALK"],[6,8,1,4,1,0,"MOVE_WALK"],[6,8,2,5,1,0,"MOVE_WALK"],[6,8,3,4,1,0,"MOVE_WALK"],[6,8,4,3,1,0,"MOVE_WALK"],[6,8,5,2,1,0,"MOVE_WALK"],[6,9,0,5,1,0,"MOVE_WALK"],[6,9,1,6,1,0,"MOVE_WALK"],[6,9,2,5,1,0,"MOVE_WALK"],[6,9,3,4,1,0,"MOVE_WALK"],[6,9,4,3,1,0,"MOVE_WALK"],[6,9,5,4,1,0,"MOVE_WALK"],[6,10,2,6,2,0,"MOVE_WALK"],[6,10,3,5,2,0,"MOVE_WALK"],[6,10,4,6,2,0,"MOVE_WALK"],[6,11,3,6,3,0,"MOVE_WALK"],[7,2,0,6,6,0,"MOVE_WALK"],[7,3,0,5,5,0,"MOVE_WALK"],[7,3,1,6,5,0,"MOVE_WALK"],[7,3,5,6,5,0,"MOVE_WALK"],[7,4,0,4,4,0,"MOVE_WALK"],[7,4,1,5,4,0,"MOVE_WALK"],[7,4,2,6,4,0,"MOVE_WALK"],[7,4,4,6,4,0,"MOVE_WALK"],[7,4,5,5,4,0,"MOVE_WALK"],[7,5,0,3,3,0,"MOVE_WALK"],[7,5,1,4,3,0,"MOVE_WALK"],[7,5,2,5,3,0,"MOVE_WALK"],[7,5,3,6,3,0,"MOVE_WALK"],[7,5,4,5,3,0,"MOVE_WALK"],[7,5,5,4,3,0,"MOVE_WALK"],[7,6,0,2,2,0,"MOVE_WALK"],[7,6,1,3,2,0,"MOVE_WALK"],[7,6,2,4,2,0,"MOVE_WALK"],[7,6,3,5,2,0,"MOVE_WALK"],[7,6,4,4,2,0,"MOVE_WALK"],[7,6,5,3,2,0,"MOVE_WALK"],[7,7,0,1,1,0,"MOVE_WALK"],[7,7,1,2,1,0,"MOVE_WALK"],[7,7,2,3,1,0,"MOVE_WALK"],[7,7,3,4,1,0,"MOVE_WALK"],[7,7,4,3,1,0,"MOVE_WALK"],[7,7,5,2,1,0,"MOVE_WALK"],[7,8,0,0,0,0,"NONE"],[7,8,1,1,0,0,"MOVE_WALK"],[7,8,2,2,0,0,"MOVE_WALK"],[7,8,3,3,0,0,"MOVE_WALK"],[7,8,4,2,0,0,"MOVE_WALK"],[7,8,5,1,0,0,"MOVE_WALK"],[7,9,1,6,1,0,"MOVE_WALK"],[7,9,2,5,1,0,"MOVE_WALK"],[7,9,3,4,1,0,"MOVE_WALK"],[7,9,4,5,1,0,"MOVE_WALK"],[7,9,5,6,1,0,"MOVE_WALK"],[7,10,2,6,2,0,"MOVE_WALK"],[7,10,3,5,2,0,"MOVE_WALK"],[7,10,4,6,2,0,"MOVE_WALK"],[7,11,3,6,3,0,"MOVE_WALK"],[8,4,1,6,5,0,"MOVE_WALK"],[8,5,0,6,4,0,"MOVE_WALK"],[8,5,1,5,4,0,"MOVE_WALK"],[8,5,2,6,4,0,"MOVE_WALK"],[8,6,0,5,3,0,"MOVE_WALK"],[8,6,1,4,3,0,"MOVE_WALK"],[8,6,2,5,3,0,"MOVE_WALK"],[8,6,3,6,3,0,"MOVE_WALK"],[8,6,5,6,3,0,"MOVE_WALK"],[8,7,0,4,2,0,"MOVE_WALK"],[8,7,1,3,2,0,"MOVE_WALK"],[8,7,2,4,2,0,"MOVE_WALK"],[8,7,3,5,2,0,"MOVE_WALK"],[8,7,4,6,2,0,"MOVE_WALK"],[8,7,5,5,2,0,"MOVE_WALK"],[8,8,0,3,1,0,"MOVE_WALK"],[8,8,1,2,1,0,"MOVE_WALK"],[8,8,2,3,1,0,"MOVE_WALK"],[8,8,3,4,1,0,"MOVE_WALK"],[8,8,4,5,1,0,"MOVE_WALK"],[8,8,5,4,1,0,"MOVE_WALK"],[8,9,0,6,1,0,"MOVE_WALK"],[8,9,1,5,1,0,"MOVE_WALK"],[8,9,2,4,1,0,"MOVE_WALK"],[8,9,3,5,1,0,"MOVE_WALK"],[8,9,4,6,1,0,"MOVE_WALK"],[9,4,1,6,5,0,"MOVE_WALK"],[9,5,0,6,4,0,"MOVE_WALK"],[9,5,1,5,4,0,"MOVE_WALK"],[9,5,2,6,4,0,"MOVE_WALK"],[9,6,0,5,3,0,"MOVE_WALK"],[9,6,1,4,3,0,"MOVE_WALK"],[9,6,2,5,3,0,"MOVE_WALK"],[9,6,3,6,3,0,"MOVE_WALK"],[9,6,5,6,3,0,"MOVE_WALK"],[9,7,0,5,2,0,"MOVE_WALK"],[9,7,1,4,2,0,"MOVE_WALK"],[9,7,2,5,2,0,"MOVE_WALK"],[9,7,3,6,2,0,"MOVE_WALK"],[9,7,5,6,2,0,"MOVE_WALK"],[9,8,2,6,2,0,"MOVE_WALK"],[10,5,1,6,5,0,"MOVE_WALK"],[10,6,0,6,4,0,"MOVE_WALK"],[10,6,1,5,4,0,"MOVE_WALK"],[10,6,2,6,4,0,"MOVE_WALK"],[10,7,0,6,3,0,"MOVE_WALK"],[10,7,1,5,3,0,"MOVE_WALK"],[10,7,2,6,3,0,"MOVE_WALK"],[10,8,2,6,3,0,"MOVE_WALK"],[11,5,1,6,5,0,"MOVE_WALK"],[11,6,1,6,4,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":7,"y":8,"facing":1,"mp":4,"considered":126,"legal":57,"states":[[5,7,5,4,2,0,"MOVE_WALK"],[6,7,5,4,2,0,"MOVE_WALK"],[6,8,0,4,1,0,"MOVE_WALK"],[6,8,4,4,1,0,"MOVE_WALK"],[6,8,5,3,1,0,"MOVE_WALK"],[6,9,4,4,1,0,"MOVE_WALK"],[7,5,0,4,3,0,"MOVE_WALK"],[7,6,0,3,2,0,"MOVE_WALK"],[7,6,1,4,2,0,"MOVE_WALK"],[7,6,5,4,2,0,"MOVE_WALK"],[7,7,0,2,1,0,"MOVE_WALK"],[7,7,1,3,1,0,"MOVE_WALK"],[7,7,2,4,1,0,"MOVE_WALK"],[7,7,4,4,1,0,"MOVE_WALK"],[7,7,5,3,1,0,"MOVE_WALK"],[7,8,0,1,0,0,"MOVE_WALK"],[7,8,1,0,0,0,"NONE"],[7,8,2,1,0,0,"MOVE_WALK"],[7,8,3,2,0,0,"MOVE_WALK"],[7,8,4,3,0,0,"MOVE_WALK"],[7,8,5,2,0,0,"MOVE_WALK"],[7,9,2,4,1,0,"MOVE_WALK"],[7,9,3,3,1,0,"MOVE_WALK"],[7,9,4,4,1,0,"MOVE_WALK"],[7,10,3,4,2,0,"MOVE_WALK"],[8,6,0,4,3,0,"MOVE_WALK"],[8,7,0,3,2,0,"MOVE_WALK"],[8,7,1,4,2,0,"MOVE_WALK"],[8,7,5,4,2,0,"MOVE_WALK"],[8,8,0,2,1,0,"MOVE_WALK"],[8,8,1,1,1,0,"MOVE_WALK"],[8,8,2,2,1,0,"MOVE_WALK"],[8,8,3,3,1,0,"MOVE_WALK"],[8,8,4,4,1,0,"MOVE_WALK"],[8,8,5,3,1,0,"MOVE_WALK"],[8,9,1,4,1,0,"MOVE_WALK"],[8,9,2,3,1,0,"MOVE_WALK"],[8,9,3,4,1,0,"MOVE_WALK"],[9,7,0,4,2,0,"MOVE_WALK"],[9,7,1,3,2,0,"MOVE_WALK"],[9,7,2,4,2,0,"MOVE_WALK"],[10,7,1,4,3,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":7,"y":8,"facing":1,"mp":6,"considered":456,"legal":244,"states":[[3,6,5,6,4,0,"MOVE_WALK"],[4,6,5,6,4,0,"MOVE_WALK"],[4,7,0,6,3,0,"MOVE_WALK"],[4,7,4,6,3,0,"MOVE_WALK"],[4,7,5,5,3,0,"MOVE_WALK"],[4,8,4,6,3,0,"MOVE_WALK"],[4,9,4,6,3,0,"MOVE_WALK"],[4,10,4,6,3,0,"MOVE_WALK"],[5,5,5,6,4,0,"MOVE_WALK"],[5,6,0,6,3,0,"MOVE_WALK"],[5,6,4,6,3,0,"MOVE_WALK"],[5,6,5,5,3,0,"MOVE_WALK"],[5,7,0,5,2,0,"MOVE_WALK"],[5,7,1,6,2,0,"MOVE_WALK"],[5,7,3,6,2,0,"MOVE_WALK"],[5,7,4,5,2,0,"MOVE_WALK"],[5,7,5,4,2,0,"MOVE_WALK"],[5,8,3,6,2,0,"MOVE_WALK"],[5,8,4,5,2,0,"MOVE_WALK"],[5,8,5,6,2,0,"MOVE_WALK"],[5,9,3,6,2,0,"MOVE_WALK"],[5,9,4,5,2,0,"MOVE_WALK"],[5,9,5,6,2,0,"MOVE_WALK"],[5,10,4,6,3,0,"MOVE_WALK"],[6,5,5,6,4,0,"MOVE_WALK"],[6,6,0,6,3,0,"MOVE_WALK"],[6,6,4,6,3,0,"MOVE_WALK"],[6,6,5,5,3,0,"MOVE_WALK"],[6,7,0,5,2,0,"MOVE_WALK"],[6,7,1,6,2,0,"MOVE_WALK"],[6,7,3,6,2,0,"MOVE_WALK"],[6,7,4,5,2,0,"MOVE_WALK"],[6,7,5,4,2,0,"MOVE_WALK"],[6,8,0,4,1,0,"MOVE_WALK"],[6,8,1,5,1,0,"MOVE_WALK"],[6,8,2,6,1,0,"MOVE_WALK"],[6,8,3,5,1,0,"MOVE_WALK"],[6,8,4,4,1,0,"MOVE_WALK"],[6,8,5,3,1,0,"MOVE_WALK"],[6,9,0,6,1,0,"MOVE_WALK"],[6,9,2,6,1,0,"MOVE_WALK"],[6,9,3,5,1,0,"MOVE_WALK"],[6,9,4,4,1,0,"MOVE_WALK"],[6,9,5,5,1,0,"MOVE_WALK"],[6,10,3,6,2,0,"MOVE_WALK"],[6,10,4,5,2,0,"MOVE_WALK"],[6,10,5,6,2,0,"MOVE_WALK"],[6,11,4,6,3,0,"MOVE_WALK"],[7,3,0,6,5,0,"MOVE_WALK"],[7,4,0,5,4,0,"MOVE_WALK"],[7,4,1,6,4,0,"MOVE_WALK"],[7,4,5,6,4,0,"MOVE_WALK"],[7,5,0,4,3,0,"MOVE_WALK"],[7,5,1,5,3,0,"MOVE_WALK"],[7,5,2,6,3,0,"MOVE_WALK"],[7,5,4,6,3,0,"MOVE_WALK"],[7,5,5,5,3,0,"MOVE_WALK"],[7,6,0,3,2,0,"MOVE_WALK"],[7,6,1,4,2,0,"MOVE_WALK"],[7,6,2,5,2,0,"MOVE_WALK"],[7,6,3,6,2,0,"MOVE_WALK"],[7,6,4,5,2,0,"MOVE_WALK"],[7,6,5,4,2,0,"MOVE_WALK"],[7,7,0,2,1,0,"MOVE_WALK"],[7,7,1,3,1,0,"MOVE_WALK"],[7,7,2,4,1,0,"MOVE_WALK"],[7,7,3,5,1,0,"MOVE_WALK"],[7,7,4,4,1,0,"MOVE_WALK"],[7,7,5,3,1,0,"MOVE_WALK"],[7,8,0,1,0,0,"MOVE_WALK"],[7,8,1,0,0,0,"NONE"],[7,8,2,1,0,0,"MOVE_WALK"],[7,8,3,2,0,0,"MOVE_WALK"],[7,8,4,3,0,0,"MOVE_WALK"],[7,8,5,2,0,0,"MOVE_WALK"],[7,9,0,6,1,0,"MOVE_WALK"],[7,9,1,5,1,0,"MOVE_WALK"],[7,9,2,4,1,0,"MOVE_WALK"],[7,9,3,3,1,0,"MOVE_WALK"],[7,9,4,4,1,0,"MOVE_WALK"],[7,9,5,5,1,0,"MOVE_WALK"],[7,10,1,6,2,0,"MOVE_WALK"],[7,10,2,5,2,0,"MOVE_WALK"],[7,10,3,4,2,0,"MOVE_WALK"],[7,10,4,5,2,0,"MOVE_WALK"],[7,10,5,6,2,0,"MOVE_WALK"],[7,11,2,6,3,0,"MOVE_WALK"],[7,11,3,5,3,0,"MOVE_WALK"],[7,11,4,6,3,0,"MOVE_WALK"],[7,12,3,6,4,0,"MOVE_WALK"],[8,4,0,6,5,0,"MOVE_WALK"],[8,5,0,5,4,0,"MOVE_WALK"],[8,5,1,6,4,0,"MOVE_WALK"],[8,5,5,6,4,0,"MOVE_WALK"],[8,6,0,4,3,0,"MOVE_WALK"],[8,6,1,5,3,0,"MOVE_WALK"],[8,6,2,6,3,0,"MOVE_WALK"],[8,6,4,6,3,0,"MOVE_WALK"],[8,6,5,5,3,0,"MOVE_WALK"],[8,7,0,3,2,0,"MOVE_WALK"],[8,7,1,4,2,0,"MOVE_WALK"],[8,7,2,5,2,0,"MOVE_WALK"],[8,7,3,6,2,0,"MOVE_WALK"],[8,7,4,5,2,0,"MOVE_WALK"],[8,7,5,4,2,0,"MOVE_WALK"],[8,8,0,2,1,0,"MOVE_WALK"],[8,8,1,1,1,0,"MOVE_WALK"],[8,8,2,2,1,0,"MOVE_WALK"],[8,8,3,3,1,0,"MOVE_WALK"],[8,8,4,4,1,0,"MOVE_WALK"],[8,8,5,3,1,0,"MOVE_WALK"],[8,9,0,5,1,0,"MOVE_WALK"],[8,9,1,4,1,0,"MOVE_WALK"],[8,9,2,3,1,0,"MOVE_WALK"],[8,9,3,4,1,0,"MOVE_WALK"],[8,9,4,5,1,0,"MOVE_WALK"],[8,9,5,6,1,0,"MOVE_WALK"],[8,10,2,6,2,0,"MOVE_WALK"],[8,10,3,6,2,0,"MOVE_WALK"],[8,11,2,6,3,0,"MOVE_WALK"],[9,5,0,6,4,0,"MOVE_WALK"],[9,5,1,6,4,0,"MOVE_WALK"],[9,6,0,5,3,0,"MOVE_WALK"],[9,6,1,5,3,0,"MOVE_WALK"],[9,6,2,6,3,0,"MOVE_WALK"],[9,6,5,6,3,0,"MOVE_WALK"],[9,7,0,4,2,0,"MOVE_WALK"],[9,7,1,3,2,0,"MOVE_WALK"],[9,7,2,4,2,0,"MOVE_WALK"],[9,7,3,5,2,0,"MOVE_WALK"],[9,7,4,6,2,0,"MOVE_WALK"],[9,7,5,5,2,0,"MOVE_WALK"],[9,8,1,6,2,0,"MOVE_WALK"],[9,8,2,5,2,0,"MOVE_WALK"],[9,8,3,6,2,0,"MOVE_WALK"],[9,9,2,6,2,0,"MOVE_WALK"],[10,6,0,6,4,0,"MOVE_WALK"],[10,6,1,6,4,0,"MOVE_WALK"],[10,7,0,5,3,0,"MOVE_WALK"],[10,7,1,4,3,0,"MOVE_WALK"],[10,7,2,5,3,0,"MOVE_WALK"],[10,7,3,6,3,0,"MOVE_WALK"],[10,7,5,6,3,0,"MOVE_WALK"],[10,8,1,6,3,0,"MOVE_WALK"],[10,8,2,5,3,0,"MOVE_WALK"],[10,8,3,6,3,0,"MOVE_WALK"],[11,6,0,6,4,0,"MOVE_WALK"],[11,6,1,5,4,0,"MOVE_WALK"],[11,6,2,6,4,0,"MOVE_WALK"],[11,7,2,6,4,0,"MOVE_WALK"],[11,8,2,6,4,0,"MOVE_WALK"],[12,6,1,6,5,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":2,"y":4,"facing":0,"mp":4,"considered":123,"legal":54,"states":[[0,2,5,4,3,0,"MOVE_WALK"],[0,3,5,4,2,0,"MOVE_WALK"],[1,1,5,4,3,0,"MOVE_WALK"],[1,2,0,4,2,0,"MOVE_WALK"],[1,2,4,4,2,0,"MOVE_WALK"],[1,2,5,3,2,0,"MOVE_WALK"],[1,3,0,4,1,0,"MOVE_WALK"],[1,3,4,4,1,0,"MOVE_WALK"],[1,3,5,3,1,0,"MOVE_WALK"],[1,4,4,4,1,0,"MOVE_WALK"],[2,0,0,4,4,0,"MOVE_WALK"],[2,1,0,3,3,0,"MOVE_WALK"],[2,1,1,4,3,0,"MOVE_WALK"],[2,1,5,4,3,0,"MOVE_WALK"],[2,2,0,2,2,0,"MOVE_WALK"],[2,2,1,3,2,0,"MOVE_WALK"],[2,2,2,4,2,0,"MOVE_WALK"],[2,2,4,4,2,0,"MOVE_WALK"],[2,2,5,3,2,0,"MOVE_WALK"],[2,3,0,1,1,0,"MOVE_WALK"],[2,3,1,2,1,0,"MOVE_WALK"],[2,3,2,3,1,0,"MOVE_WALK"],[2,3,3,4,1,0,"MOVE_WALK"],[2,3,4,3,1,0,"MOVE_WALK"],[2,3,5,2,1,0,"MOVE_WALK"],[2,4,0,0,0,0,"NONE"],[2,4,1,1,0,0,"MOVE_WALK"],[2,4,2,2,0,0,"MOVE_WALK"],[2,4,3,3,0,0,"MOVE_WALK"],[2,4,4,2,0,0,"MOVE_WALK"],[2,4,5,1,0,0,"MOVE_WALK"],[3,1,1,4,3,0,"MOVE_WALK"],[3,2,0,4,2,0,"MOVE_WALK"],[3,2,1,3,2,0,"MOVE_WALK"],[3,2,2,4,2,0,"MOVE_WALK"],[3,3,0,4,1,0,"MOVE_WALK"],[3,3,1,3,1,0,"MOVE_WALK"],[3,3,2,4,1,0,"MOVE_WALK"],[3,4,2,4,1,0,"MOVE_WALK"],[4,2,1,4,3,0,"MOVE_WALK"],[4,3,1,4,2,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":2,"y":4,"facing":0,"mp":6,"considered":396,"legal":222,"states":[[0,0,5,6,5,0,"MOVE_WALK"],[0,1,0,6,4,0,"MOVE_WALK"],[0,1,4,6,4,0,"MOVE_WALK"],[0,1,5,5,4,0,"MOVE_WALK"],[0,2,0,5,3,0,"MOVE_WALK"],[0,2,1,6,3,0,"MOVE_WALK"],[0,2,3,6,3,0,"MOVE_WALK"],[0,2,4,5,3,0,"MOVE_WALK"],[0,2,5,4,3,0,"MOVE_WALK"],[0,3,0,5,2,0,"MOVE_WALK"],[0,3,1,6,2,0,"MOVE_WALK"],[0,3,3,6,2,0,"MOVE_WALK"],[0,3,4,5,2,0,"MOVE_WALK"],[0,3,5,4,2,0,"MOVE_WALK"],[0,4,3,6,2,0,"MOVE_WALK"],[0,4,4,5,2,0,"MOVE_WALK"],[0,4,5,6,2,0,"MOVE_WALK"],[0,5,3,6,2,0,"MOVE_WALK"],[0,5,4,5,2,0,"MOVE_WALK"],[0,5,5,6,2,0,"MOVE_WALK"],[1,0,0,6,4,0,"MOVE_WALK"],[1,0,4,6,4,0,"MOVE_WALK"],[1,0,5,5,4,0,"MOVE_WALK"],[1,1,0,5,3,0,"MOVE_WALK"],[1,1,1,6,3,0,"MOVE_WALK"],[1,1,3,6,3,0,"MOVE_WALK"],[1,1,4,5,3,0,"MOVE_WALK"],[1,1,5,4,3,0,"MOVE_WALK"],[1,2,0,4,2,0,"MOVE_WALK"],[1,2,1,5,2,0,"MOVE_WALK"],[1,2,2,6,2,0,"MOVE_WALK"],[1,2,3,5,2,0,"MOVE_WALK"],[1,2,4,4,2,0,"MOVE_WALK"],[1,2,5,3,2,0,"MOVE_WALK"],[1,3,0,4,1,0,"MOVE_WALK"],[1,3,1,5,1,0,"MOVE_WALK"],[1,3,2,6,1,0,"MOVE_WALK"],[1,3,3,5,1,0,"MOVE_WALK"],[1,3,4,4,1,0,"MOVE_WALK"],[1,3,5,3,1,0,"MOVE_WALK"],[1,4,0,6,1,0,"MOVE_WALK"],[1,4,2,6,1,0,"MOVE_WALK"],[1,4,3,5,1,0,"MOVE_WALK"],[1,4,4,4,1,0,"MOVE_WALK"],[1,4,5,5,1,0,"MOVE_WALK"],[2,0,0,4,4,0,"MOVE_WALK"],[2,0,1,5,4,0,"MOVE_WALK"],[2,0,2,6,4,0,"MOVE_WALK"],[2,0,4,6,4,0,"MOVE_WALK"],[2,0,5,5,4,0,"MOVE_WALK"],[2,1,0,3,3,0,"MOVE_WALK"],[2,1,1,4,3,0,"MOVE_WALK"],[2,1,2,5,3,0,"MOVE_WALK"],[2,1,3,6,3,0,"MOVE_WALK"],[2,1,4,5,3,0,"MOVE_WALK"],[2,1,5,4,3,0,"MOVE_WALK"],[2,2,0,2,2,0,"MOVE_WALK"],[2,2,1,3,2,0,"MOVE_WALK"],[2,2,2,4,2,0,"MOVE_WALK"],[2,2,3,5,2,0,"MOVE_WALK"],[2,2,4,4,2,0,"MOVE_WALK"],[2,2,5,3,2,0,"MOVE_WALK"],[2,3,0,1,1,0,"MOVE_WALK"],[2,3,1,2,1,0,"MOVE_WALK"],[2,3,2,3,1,0,"MOVE_WALK"],[2,3,3,4,1,0,"MOVE_WALK"],[2,3,4,3,1,0,"MOVE_WALK"],[2,3,5,2,1,0,"MOVE_WALK"],[2,4,0,0,0,0,"NONE"],[2,4,1,1,0,0,"MOVE_WALK"],[2,4,2,2,0,0,"MOVE_WALK"],[2,4,3,3,0,0,"MOVE_WALK"],[2,4,4,2,0,0,"MOVE_WALK"],[2,4,5,1,0,0,"MOVE_WALK"],[2,5,2,6,1,0,"MOVE_WALK"],[2,5,3,5,1,0,"MOVE_WALK"],[2,5,4,6,1,0,"MOVE_WALK"],[2,6,3,6,2,0,"MOVE_WALK"],[3,0,0,6,4,0,"MOVE_WALK"],[3,0,1,5,4,0,"MOVE_WALK"],[3,0,2,6,4,0,"MOVE_WALK"],[3,1,0,5,3,0,"MOVE_WALK"],[3,1,1,4,3,0,"MOVE_WALK"],[3,1,2,5,3,0,"MOVE_WALK"],[3,1,3,6,3,0,"MOVE_WALK"],[3,1,5,6,3,0,"MOVE_WALK"],[3,2,0,4,2,0,"MOVE_WALK"],[3,2,1,3,2,0,"MOVE_WALK"],[3,2,2,4,2,0,"MOVE_WALK"],[3,2,3,5,2,0,"MOVE_WALK"],[3,2,4,6,2,0,"MOVE_WALK"],[3,2,5,5,2,0,"MOVE_WALK"],[3,3,0,4,1,0,"MOVE_WALK"],[3,3,1,3,1,0,"MOVE_WALK"],[3,3,2,4,1,0,"MOVE_WALK"],[3,3,3,5,1,0,"MOVE_WALK"],[3,3,4,6,1,0,"MOVE_WALK"],[3,3,5,5,1,0,"MOVE_WALK"],[3,4,0,6,1,0,"MOVE_WALK"],[3,4,1,5,1,0,"MOVE_WALK"],[3,4,2,4,1,0,"MOVE_WALK"],[3,4,3,5,1,0,"MOVE_WALK"],[3,4,4,6,1,0,"MOVE_WALK"],[3,5,3,6,2,0,"MOVE_WALK"],[4,0,1,6,5,0,"MOVE_WALK"],[4,1,0,6,4,0,"MOVE_WALK"],[4,1,1,5,4,0,"MOVE_WALK"],[4,1,2,6,4,0,"MOVE_WALK"],[4,2,0,5,3,0,"MOVE_WALK"],[4,2,1,4,3,0,"MOVE_WALK"],[4,2,2,5,3,0,"MOVE_WALK"],[4,2,3,6,3,0,"MOVE_WALK"],[4,2,5,6,3,0,"MOVE_WALK"],[4,3,0,5,2,0,"MOVE_WALK"],[4,3,1,4,2,0,"MOVE_WALK"],[4,3,2,5,2,0,"MOVE_WALK"],[4,3,3,6,2,0,"MOVE_WALK"],[4,3,5,6,2,0,"MOVE_WALK"],[4,5,1,6,2,0,"MOVE_WALK"],[4,5,2,5,2,0,"MOVE_WALK"],[4,5,3,6,2,0,"MOVE_WALK"],[5,0,1,6,5,0,"MOVE_WALK"],[5,1,0,6,4,0,"MOVE_WALK"],[5,1,1,5,4,0,"MOVE_WALK"],[5,1,2,6,4,0,"MOVE_WALK"],[5,2,0,6,3,0,"MOVE_WALK"],[5,2,1,5,3,0,"MOVE_WALK"],[5,2,2,6,3,0,"MOVE_WALK"],[5,3,2,6,3,0,"MOVE_WALK"],[5,5,2,6,3,0,"MOVE_WALK"],[6,1,1,6,5,0,"MOVE_WALK"],[6,2,1,6,4,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":2,"y":4,"facing":1,"mp":4,"considered":99,"legal":43,"states":[[1,2,5,4,2,0,"MOVE_WALK"],[1,3,5,4,1,0,"MOVE_WALK"],[2,1,0,4,3,0,"MOVE_WALK"],[2,2,0,3,2,0,"MOVE_WALK"],[2,2,1,4,2,0,"MOVE_WALK"],[2,2,5,4,2,0,"MOVE_WALK"],[2,3,0,2,1,0,"MOVE_WALK"],[2,3,1,3,1,0,"MOVE_WALK"],[2,3,2,4,1,0,"MOVE_WALK"],[2,3,4,4,1,0,"MOVE_WALK"],[2,3,5,3,1,0,"MOVE_WALK"],[2,4,0,1,0,0,"MOVE_WALK"],[2,4,1,0,0,0,"NONE"],[2,4,2,1,0,0,"MOVE_WALK"],[2,4,3,2,0,0,"MOVE_WALK"],[2,4,4,3,0,0,"MOVE_WALK"],[2,4,5,2,0,0,"MOVE_WALK"],[2,5,3,4,1,0,"MOVE_WALK"],[3,2,0,4,2,0,"MOVE_WALK"],[3,2,1,4,2,0,"MOVE_WALK"],[3,3,0,3,1,0,"MOVE_WALK"],[3,3,1,2,1,0,"MOVE_WALK"],[3,3,2,3,1,0,"MOVE_WALK"],[3,3,3,4,1,0,"MOVE_WALK"],[3,3,5,4,1,0,"MOVE_WALK"],[3,4,1,4,1,0,"MOVE_WALK"],[3,4,2,3,1,0,"MOVE_WALK"],[3,4,3,4,1,0,"MOVE_WALK"],[4,3,0,4,2,0,"MOVE_WALK"],[4,3,1,3,2,0,"MOVE_WALK"],[4,3,2,4,2,0,"MOVE_WALK"],[4,5,2,4,2,0,"MOVE_WALK"],[5,2,1,4,3,0,"MOVE_WALK"]],"board":"open"} +{"type":"case","x":2,"y":4,"facing":1,"mp":6,"considered":387,"legal":197,"states":[[0,1,5,6,4,0,"MOVE_WALK"],[0,2,0,6,3,0,"MOVE_WALK"],[0,2,4,6,3,0,"MOVE_WALK"],[0,2,5,5,3,0,"MOVE_WALK"],[0,3,0,6,2,0,"MOVE_WALK"],[0,3,4,6,2,0,"MOVE_WALK"],[0,3,5,5,2,0,"MOVE_WALK"],[0,4,4,6,2,0,"MOVE_WALK"],[0,5,4,6,2,0,"MOVE_WALK"],[1,0,5,6,4,0,"MOVE_WALK"],[1,1,0,6,3,0,"MOVE_WALK"],[1,1,4,6,3,0,"MOVE_WALK"],[1,1,5,5,3,0,"MOVE_WALK"],[1,2,0,5,2,0,"MOVE_WALK"],[1,2,1,6,2,0,"MOVE_WALK"],[1,2,3,6,2,0,"MOVE_WALK"],[1,2,4,5,2,0,"MOVE_WALK"],[1,2,5,4,2,0,"MOVE_WALK"],[1,3,0,5,1,0,"MOVE_WALK"],[1,3,1,6,1,0,"MOVE_WALK"],[1,3,3,6,1,0,"MOVE_WALK"],[1,3,4,5,1,0,"MOVE_WALK"],[1,3,5,4,1,0,"MOVE_WALK"],[1,4,3,6,1,0,"MOVE_WALK"],[1,4,4,5,1,0,"MOVE_WALK"],[1,4,5,6,1,0,"MOVE_WALK"],[2,0,0,5,4,0,"MOVE_WALK"],[2,0,1,6,4,0,"MOVE_WALK"],[2,0,5,6,4,0,"MOVE_WALK"],[2,1,0,4,3,0,"MOVE_WALK"],[2,1,1,5,3,0,"MOVE_WALK"],[2,1,2,6,3,0,"MOVE_WALK"],[2,1,4,6,3,0,"MOVE_WALK"],[2,1,5,5,3,0,"MOVE_WALK"],[2,2,0,3,2,0,"MOVE_WALK"],[2,2,1,4,2,0,"MOVE_WALK"],[2,2,2,5,2,0,"MOVE_WALK"],[2,2,3,6,2,0,"MOVE_WALK"],[2,2,4,5,2,0,"MOVE_WALK"],[2,2,5,4,2,0,"MOVE_WALK"],[2,3,0,2,1,0,"MOVE_WALK"],[2,3,1,3,1,0,"MOVE_WALK"],[2,3,2,4,1,0,"MOVE_WALK"],[2,3,3,5,1,0,"MOVE_WALK"],[2,3,4,4,1,0,"MOVE_WALK"],[2,3,5,3,1,0,"MOVE_WALK"],[2,4,0,1,0,0,"MOVE_WALK"],[2,4,1,0,0,0,"NONE"],[2,4,2,1,0,0,"MOVE_WALK"],[2,4,3,2,0,0,"MOVE_WALK"],[2,4,4,3,0,0,"MOVE_WALK"],[2,4,5,2,0,0,"MOVE_WALK"],[2,5,1,6,1,0,"MOVE_WALK"],[2,5,2,5,1,0,"MOVE_WALK"],[2,5,3,4,1,0,"MOVE_WALK"],[2,5,4,5,1,0,"MOVE_WALK"],[2,5,5,6,1,0,"MOVE_WALK"],[2,6,2,6,2,0,"MOVE_WALK"],[2,6,3,5,2,0,"MOVE_WALK"],[2,6,4,6,2,0,"MOVE_WALK"],[2,7,3,6,3,0,"MOVE_WALK"],[3,0,0,6,4,0,"MOVE_WALK"],[3,0,1,6,4,0,"MOVE_WALK"],[3,1,0,5,3,0,"MOVE_WALK"],[3,1,1,5,3,0,"MOVE_WALK"],[3,1,2,6,3,0,"MOVE_WALK"],[3,1,5,6,3,0,"MOVE_WALK"],[3,2,0,4,2,0,"MOVE_WALK"],[3,2,1,4,2,0,"MOVE_WALK"],[3,2,2,5,2,0,"MOVE_WALK"],[3,2,3,6,2,0,"MOVE_WALK"],[3,2,4,6,2,0,"MOVE_WALK"],[3,2,5,5,2,0,"MOVE_WALK"],[3,3,0,3,1,0,"MOVE_WALK"],[3,3,1,2,1,0,"MOVE_WALK"],[3,3,2,3,1,0,"MOVE_WALK"],[3,3,3,4,1,0,"MOVE_WALK"],[3,3,4,5,1,0,"MOVE_WALK"],[3,3,5,4,1,0,"MOVE_WALK"],[3,4,0,5,1,0,"MOVE_WALK"],[3,4,1,4,1,0,"MOVE_WALK"],[3,4,2,3,1,0,"MOVE_WALK"],[3,4,3,4,1,0,"MOVE_WALK"],[3,4,4,5,1,0,"MOVE_WALK"],[3,4,5,6,1,0,"MOVE_WALK"],[3,5,2,6,2,0,"MOVE_WALK"],[3,5,3,5,2,0,"MOVE_WALK"],[3,5,4,6,2,0,"MOVE_WALK"],[3,6,3,6,3,0,"MOVE_WALK"],[4,1,0,6,4,0,"MOVE_WALK"],[4,1,1,6,4,0,"MOVE_WALK"],[4,2,0,5,3,0,"MOVE_WALK"],[4,2,1,5,3,0,"MOVE_WALK"],[4,2,2,6,3,0,"MOVE_WALK"],[4,2,5,6,3,0,"MOVE_WALK"],[4,3,0,4,2,0,"MOVE_WALK"],[4,3,1,3,2,0,"MOVE_WALK"],[4,3,2,4,2,0,"MOVE_WALK"],[4,3,3,5,2,0,"MOVE_WALK"],[4,3,4,6,2,0,"MOVE_WALK"],[4,3,5,5,2,0,"MOVE_WALK"],[4,4,2,6,2,0,"MOVE_WALK"],[4,5,0,6,2,0,"MOVE_WALK"],[4,5,1,5,2,0,"MOVE_WALK"],[4,5,2,4,2,0,"MOVE_WALK"],[4,5,3,5,2,0,"MOVE_WALK"],[4,5,4,6,2,0,"MOVE_WALK"],[4,6,3,6,3,0,"MOVE_WALK"],[5,1,0,6,4,0,"MOVE_WALK"],[5,1,1,6,4,0,"MOVE_WALK"],[5,2,0,5,3,0,"MOVE_WALK"],[5,2,1,4,3,0,"MOVE_WALK"],[5,2,2,5,3,0,"MOVE_WALK"],[5,2,3,6,3,0,"MOVE_WALK"],[5,2,5,6,3,0,"MOVE_WALK"],[5,3,1,6,3,0,"MOVE_WALK"],[5,3,2,5,3,0,"MOVE_WALK"],[5,3,3,6,3,0,"MOVE_WALK"],[5,4,1,6,3,0,"MOVE_WALK"],[5,5,1,6,3,0,"MOVE_WALK"],[5,5,2,5,3,0,"MOVE_WALK"],[5,5,3,6,3,0,"MOVE_WALK"],[6,2,0,6,4,0,"MOVE_WALK"],[6,2,1,5,4,0,"MOVE_WALK"],[6,2,2,6,4,0,"MOVE_WALK"],[6,3,2,6,4,0,"MOVE_WALK"],[6,4,2,6,4,0,"MOVE_WALK"],[6,6,2,6,4,0,"MOVE_WALK"],[7,1,1,6,5,0,"MOVE_WALK"]],"board":"open"} diff --git a/crates/sds-core/tests/pathfind_corpus.rs b/crates/sds-core/tests/pathfind_corpus.rs new file mode 100644 index 0000000..3ed3046 --- /dev/null +++ b/crates/sds-core/tests/pathfind_corpus.rs @@ -0,0 +1,287 @@ +//! The movement corpus: what it contains, and what has to hold of it. +//! +//! `tests/corpus/pathfind.jsonl` is written by `bridge/sds/SdsPathfind.java`, +//! which walks MegaMek's own `MovePath` and keeps whatever `isMoveLegal` +//! accepts. Regenerate it with: +//! +//! ```text +//! ./sds.sh pathfind-dump +//! ``` +//! +//! It is an offline fixture, committed once, the way the line of sight corpus +//! and the hit tables are. Nothing dumps during a match. +//! +//! The differential test - our reachable state set equals MegaMek's - belongs +//! with the reachability search, which does not exist yet. What is here is the +//! corpus's own contract: that it covers the cases it claims to, that it is +//! internally consistent, and that it is written in an order that does not +//! depend on the heap. A corpus that quietly lost half its cases would +//! otherwise still let the differential test pass. + +use std::collections::{BTreeMap, BTreeSet}; + +use serde::Deserialize; + +const CORPUS: &str = include_str!("corpus/pathfind.jsonl"); + +/// One reachable end state: `[x, y, facing, mp, hexes, elevation, class]`. +#[derive(Debug, Deserialize)] +struct State(i32, i32, i32, i32, i32, i32, String); + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct Case { + board: String, + x: i32, + y: i32, + facing: i32, + mp: i32, + considered: i32, + legal: i32, + states: Vec, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct BoardHeader { + board: String, + width: i32, + height: i32, + walk_mp: i32, + run_mp: i32, + hexes: Vec, +} + +#[derive(Debug, Deserialize)] +struct Hex { + #[allow(dead_code)] + x: i32, + #[allow(dead_code)] + y: i32, + #[serde(default)] + level: i32, +} + +fn boards() -> BTreeMap { + CORPUS + .lines() + .filter(|line| line.contains("\"type\":\"board\"")) + .map(|line| { + let header: BoardHeader = serde_json::from_str(line).expect("board header"); + (header.board.clone(), header) + }) + .collect() +} + +fn cases() -> Vec { + CORPUS + .lines() + .filter(|line| line.contains("\"type\":\"case\"")) + .map(|line| serde_json::from_str(line).expect("case")) + .collect() +} + +/// The corpus covers what it says it covers. +/// +/// Named boards, both column parities, both facings, both budgets. The bound +/// is deliberate and small, so it is asserted exactly: a corpus that shrank +/// would otherwise pass everything below it by having less to disagree about. +#[test] +fn the_corpus_covers_the_cases_worth_testing() { + let boards = boards(); + let cases = cases(); + + assert_eq!( + boards.keys().collect::>(), + vec!["forest", "open"], + "one open board and one heavily wooded one" + ); + assert_eq!( + cases.len(), + 24, + "two boards, three starts, two facings, two budgets" + ); + + for board in boards.values() { + assert_eq!((board.width, board.height), (16, 17)); + assert_eq!(board.walk_mp, 6, "every case is inside a walk"); + assert!(board.run_mp > board.walk_mp); + } + + // The wooded board has a hill on it; the open one is flat. Both regimes + // are needed: elevation and terrain cost are separate ways to be wrong. + let relief = |key: &str| { + boards[key] + .hexes + .iter() + .map(|hex| hex.level) + .max() + .unwrap_or(0) + }; + assert!( + relief("forest") >= 3, + "the wooded board carries an elevation change" + ); + assert_eq!(relief("open"), 0, "the open board is flat"); + + for board in ["open", "forest"] { + let starts: BTreeSet<(i32, i32)> = cases + .iter() + .filter(|case| case.board == board) + .map(|case| (case.x, case.y)) + .collect(); + assert_eq!(starts.len(), 3, "{board}: three starts"); + let parities: BTreeSet = starts.iter().map(|(x, _)| x & 1).collect(); + assert_eq!(parities.len(), 2, "{board}: both column parities"); + + let facings: BTreeSet = cases + .iter() + .filter(|case| case.board == board) + .map(|case| case.facing) + .collect(); + assert_eq!(facings, BTreeSet::from([0, 1])); + + let budgets: BTreeSet = cases + .iter() + .filter(|case| case.board == board) + .map(|case| case.mp) + .collect(); + assert_eq!(budgets, BTreeSet::from([4, 6])); + } + + // The two boards are two regimes, not two copies of one. Six MP off the + // same kind of start reaches several times as many hexes in the open. + let reach = |board: &str| -> usize { + cases + .iter() + .filter(|case| case.board == board && case.mp == 6) + .map(|case| { + case.states + .iter() + .map(|state| (state.0, state.1)) + .collect::>() + .len() + }) + .max() + .unwrap() + }; + assert!( + reach("open") > 3 * reach("forest"), + "open {} against forest {} is not two regimes", + reach("open"), + reach("forest") + ); +} + +/// Every case is internally consistent, and written in a fixed order. +/// +/// The ordering assertion is the one that keeps "regenerates byte-identically" +/// true: the dump settles states out of a heap, and a file written in heap +/// order would churn on every MegaMek release without anything having changed. +#[test] +fn every_case_is_consistent() { + for case in cases() { + let label = format!( + "{} {},{} f{} mp{}", + case.board, case.x, case.y, case.facing, case.mp + ); + assert!(!case.states.is_empty(), "{label}: no states"); + assert!( + case.legal <= case.considered, + "{label}: more legal than considered" + ); + + let mut previous: Option<(i32, i32, i32)> = None; + let mut standing_still = 0; + for state in &case.states { + let State(x, y, facing, mp, hexes, _elevation, class) = state; + let key = (*x, *y, *facing); + if let Some(before) = previous { + assert!(before < key, "{label}: states are not sorted and unique"); + } + previous = Some(key); + + assert!( + *mp <= case.mp, + "{label}: {key:?} spends {mp} of {}", + case.mp + ); + assert!(*facing >= 0 && *facing < 6, "{label}: facing {facing}"); + // Terrain and turning both burn MP without moving you, so MP spent + // is never less than hexes crossed. + assert!( + *hexes <= *mp, + "{label}: {key:?} moved {hexes} hexes on {mp} MP" + ); + + if key == (case.x, case.y, case.facing) { + standing_still += 1; + assert_eq!(*mp, 0, "{label}: standing still is not free"); + assert_eq!(*hexes, 0); + assert_eq!( + class, "NONE", + "{label}: standing still has a movement class" + ); + } else { + assert!(*mp > 0, "{label}: {key:?} reached for nothing"); + assert_eq!(class, "MOVE_WALK", "{label}: {key:?} is not a walk"); + } + } + assert_eq!( + standing_still, 1, + "{label}: the start is not in its own state set" + ); + } +} + +/// The state set for four MP is a subset of the set for six. +/// +/// More budget cannot take a state away, and a state reachable with both must +/// cost the same in both. This is the property the two budgets are in the +/// corpus for, and it is also the first thing a cost model gets wrong. +#[test] +fn a_bigger_budget_only_adds() { + let all = cases(); + let by_case: BTreeMap<(&str, i32, i32, i32, i32), &Case> = all + .iter() + .map(|case| { + ( + (case.board.as_str(), case.x, case.y, case.facing, case.mp), + case, + ) + }) + .collect(); + + let mut compared = 0; + for ((board, x, y, facing, mp), small) in &by_case { + if *mp != 4 { + continue; + } + let large = by_case + .get(&(*board, *x, *y, *facing, 6)) + .expect("a six MP case beside every four MP one"); + + let wider: BTreeMap<(i32, i32, i32), (i32, i32)> = large + .states + .iter() + .map(|state| ((state.0, state.1, state.2), (state.3, state.4))) + .collect(); + for state in &small.states { + let key = (state.0, state.1, state.2); + let cost = wider + .get(&key) + .unwrap_or_else(|| panic!("{board} {x},{y} f{facing}: {key:?} lost at six MP")); + assert_eq!( + *cost, + (state.3, state.4), + "{board} {x},{y} f{facing}: {key:?} costs differently at six MP" + ); + } + assert!(large.states.len() >= small.states.len()); + compared += 1; + } + assert_eq!( + compared, 12, + "every start and facing compared at both budgets" + ); +} diff --git a/plan/candidates.md b/plan/candidates.md index 07f0f78..fd6370e 100644 --- a/plan/candidates.md +++ b/plan/candidates.md @@ -98,7 +98,7 @@ good offence and bad defence, and a single operator over `N` cannot say so. - [x] `Stand { hex, facing }` in `hex.rs` with parity-correct neighbour and turn helpers. Test: hand-checked adjacency on both column parities; six turns returns to start -- [ ] `bridge/sds/SdsPathfind.java` dumps MegaMek's own legal end states for a +- [x] `bridge/sds/SdsPathfind.java` dumps MegaMek's own legal end states for a unit on a board, by walking `MovePath` and testing `isMoveLegal`. **An offline fixture, committed once**, the way the LOS corpus and the hit tables are - nothing dumps during a match. Bound it to a handful of @@ -125,8 +125,10 @@ good offence and bad defence, and a single operator over `N` cannot say so. **Engagement** -- [ ] Port `Compute.isInArc`, including `secondaryFacing` for the torso twist. - Test: differential dump over all `(facing, twist, direction)` triples +- [x] Port `Compute.isInArc`, including `secondaryFacing` for the torso twist. + Test: differential dump over all `(facing, twist, direction)` triples. + The corpus is not committed - `./sds.sh arc-dump` regenerates it - so the + arc port is not verified on a machine without MegaMek and Docker - [ ] Arc prune: which weapons bear from a state toward a direction. Test: a unit with only forward weapons facing away bears nothing, and one twist recovers exactly one hexside diff --git a/scenarios/pathfind-forest.mms b/scenarios/pathfind-forest.mms new file mode 100644 index 0000000..d5b2230 --- /dev/null +++ b/scenarios/pathfind-forest.mms @@ -0,0 +1,24 @@ +# A board and one machine, for the movement corpus. Not a benchmark. +# +# bridge/sds/SdsPathfind.java loads this for its board and its first unit, then +# walks MegaMek's own MovePath to dump every legal end state. It never plays: +# the second unit is here because a scenario needs two sides, and it is never +# placed or asked for anything. +# +# The unit is a Phoenix Hawk PXH-1 because it walks 6. Every case in the corpus +# is inside that, so nothing in the dump is a run, and a port can be checked on +# terrain cost and turning before movement class enters it. +# +# MegaMek Data (C) 2025 by The MegaMek Team is licensed under CC BY-NC-SA 4.0. +# https://creativecommons.org/licenses/by-nc-sa/4.0/ +MMSVersion=1 +Name=pathfind-forest +Description=Heavy forest, one sheet, one machine. The movement corpus fixture. +BoardWidth=1 +BoardHeight=1 +Maps=Map Set 4/16x17 Heavy Forest 1 +Factions=North,South +Location_North=N +Location_South=S +Unit_North_1=Phoenix Hawk PXH-1,North 1,4,5 +Unit_South_1=Phoenix Hawk PXH-1,South 1,4,5 diff --git a/scenarios/pathfind-open.mms b/scenarios/pathfind-open.mms new file mode 100644 index 0000000..3b513cd --- /dev/null +++ b/scenarios/pathfind-open.mms @@ -0,0 +1,24 @@ +# A board and one machine, for the movement corpus. Not a benchmark. +# +# bridge/sds/SdsPathfind.java loads this for its board and its first unit, then +# walks MegaMek's own MovePath to dump every legal end state. It never plays: +# the second unit is here because a scenario needs two sides, and it is never +# placed or asked for anything. +# +# The unit is a Phoenix Hawk PXH-1 because it walks 6. Every case in the corpus +# is inside that, so nothing in the dump is a run, and a port can be checked on +# terrain cost and turning before movement class enters it. +# +# MegaMek Data (C) 2025 by The MegaMek Team is licensed under CC BY-NC-SA 4.0. +# https://creativecommons.org/licenses/by-nc-sa/4.0/ +MMSVersion=1 +Name=pathfind-open +Description=Open terrain, one sheet, one machine. The movement corpus fixture. +BoardWidth=1 +BoardHeight=1 +Maps=Map Set 5/16x17 Open Terrain 1 +Factions=North,South +Location_North=N +Location_South=S +Unit_North_1=Phoenix Hawk PXH-1,North 1,4,5 +Unit_South_1=Phoenix Hawk PXH-1,South 1,4,5 diff --git a/sds/cli.py b/sds/cli.py index 951c900..f77802d 100644 --- a/sds/cli.py +++ b/sds/cli.py @@ -327,6 +327,17 @@ def cmd_los_dump(args: argparse.Namespace) -> int: return code +def cmd_pathfind_dump(args: argparse.Namespace) -> int: + """Write the corpus the Rust reachability search is tested against.""" + from .match import pathfind_dump + + out = Path(args.out).resolve() + code = pathfind_dump(out) + if code == 0: + print(f"wrote {out}") + return code + + def cmd_arc_dump(args: argparse.Namespace) -> int: """Write the corpus the Rust weapon arcs are tested against.""" from .match import arc_dump @@ -711,6 +722,20 @@ def main(argv: list[str] | None = None) -> int: los_dump.add_argument("--cases", type=int, default=600, help="cases per board") los_dump.set_defaults(func=cmd_los_dump) + pathfind_dump = sub.add_parser( + "pathfind-dump", + help="dump MegaMek's legal movement end states, as a Rust test corpus", + description="Walks MegaMek's own MovePath a step at a time over a fixed " + "set of boards, starts, facings and MP budgets, keeping whatever " + "isMoveLegal accepts. One JVM, no match. An offline fixture: regenerate " + "it deliberately and commit the result, never during a game.", + ) + pathfind_dump.add_argument( + "--out", + default=str(REPO / "crates" / "sds-core" / "tests" / "corpus" / "pathfind.jsonl"), + ) + pathfind_dump.set_defaults(func=cmd_pathfind_dump) + arc_dump = sub.add_parser( "arc-dump", help="dump MegaMek's weapon arc tables, as a Rust test corpus", diff --git a/sds/match.py b/sds/match.py index 946e997..0bb9f57 100644 --- a/sds/match.py +++ b/sds/match.py @@ -331,6 +331,55 @@ def los_dump(scenarios: list[Path], out: Path, cases: int = 600) -> int: return _bridge("losdump", "sds.SdsLosDump", arguments) +# The committed movement cases: board, start, facing, MP budget. +# +# Two boards because open ground and heavy forest are the two regimes a cost +# model can be wrong in separately. Three starts each because MegaMek's hex +# geometry is column-parity dependent, so an even column and an odd one are +# different tests, and a start on a hillside is a third. Two MP budgets because +# the state set for 4 must be a subset of the set for 6, which is a property +# the corpus can be asked for directly rather than argued. +# +# An offline fixture, regenerated deliberately and committed. Nothing dumps +# during a match. +PATHFIND_BOARDS = { + "open": REPO / "scenarios" / "pathfind-open.mms", + "forest": REPO / "scenarios" / "pathfind-forest.mms", +} + +PATHFIND_STARTS = { + # Open ground in every direction, on an even column and then an odd one, + # plus a start inside the board's one stand of woods. + "open": [(8, 8), (7, 8), (2, 4)], + # The hilltop, where every neighbour is an elevation change, on an even + # column and then an odd one, plus flat heavy forest away from it. + "forest": [(6, 5), (7, 5), (4, 8)], +} + +PATHFIND_FACINGS = (0, 1) + +PATHFIND_BUDGETS = (4, 6) + + +def pathfind_dump(out: Path) -> int: + """Dump MegaMek's legal ground movement end states, as a test corpus. + + One short JVM, no server and no match: it loads each board with one + Phoenix Hawk on it, then walks `MovePath` a step at a time and keeps + whatever `isMoveLegal` accepts, in order of MP spent. The Rust + reachability search is checked against the file this writes. + """ + out.parent.mkdir(parents=True, exist_ok=True) + arguments = ["--out", f"/work/{out.resolve().relative_to(REPO)}"] + for key, scenario in PATHFIND_BOARDS.items(): + arguments += ["--board", f"{key}=/work/{scenario.relative_to(REPO)}"] + for x, y in PATHFIND_STARTS[key]: + for facing in PATHFIND_FACINGS: + for budget in PATHFIND_BUDGETS: + arguments += ["--case", f"{x},{y},{facing},{budget}"] + return _bridge("pathfind", "sds.SdsPathfind", arguments) + + def arc_dump(out: Path) -> int: """Dump MegaMek's weapon arc tables, as a test corpus.