ES
games/open-lemmings / tools / solve.php · commit 04e2e2a
<?php// Plays every level's solution without a window and says how it ended.//   bin/jumphp php games/open-lemmings tools/solve.php [level] [ascii-every-N-ticks]require __DIR__ . '/../vendor/autoload.php';use App\Sim\Autoplay;use App\Sim\LevelBuilder;use App\Sim\Levels;$only = isset($argv[1]) && $argv[1] !== 'all' ? (int)$argv[1] : null;$dump = (int)($argv[2] ?? 0);$fail = 0;foreach (Levels::all() as $i => $def) {    if ($only !== null && $only !== $i + 1) {        continue;    }    $w = LevelBuilder::build($def);    $auto = new Autoplay($w, $def['solution']);    $log = [];    while (!$w->isOver()) {        $w->step();        $auto->step();        foreach ($w->events as $e) {            if (in_array($e[0], ['assign', 'splat', 'drown', 'gone', 'boom', 'clink'], true)) {                $log[] = "{$w->tick}:{$e[0]}" . ($e[3] ? "({$e[3]})" : '') . "@{$e[1]},{$e[2]}";            }        }        $w->events = [];        if ($dump > 0 && $w->tick % $dump === 0) {            $rows = explode("\n", $w->terrain->ascii(8));            foreach ($w->lumis as $l) {                if ($l->alive) {                    $r = intdiv(max(0, min($w->terrain->height - 1, $l->y - 4)), 8);                    $rows[$r][intdiv(max(0, min($w->terrain->width - 1, $l->x)), 8)] = $l->state[0];                }            }            echo "tick {$w->tick}\n" . implode("\n", $rows) . "\n";        }    }    $ok = $w->isWon() && $auto->done();    $fail += $ok ? 0 : 1;    printf("%2d %-20s %s saved %d/%d (need %d) ticks %d steps %s\n   %s\n", $i + 1, $def['name'], $ok ? 'WON ' : 'LOST', $w->saved, $w->total, $w->need,        $w->tick, $auto->done() ? 'done' : 'PENDING', implode(' ', $log));}exit($fail ? 1 : 0);