"""Offline SE rail planner from installed map, with normal pushes and levers.""" import ast,json,heapq,re,subprocess,copy,pickle from pathlib import Path from collections import deque R=Path(__file__).resolve().parents[1];ns=dict(ROOT=R,json=json,heapq=heapq,re=re) t=ast.parse((R/'scripts/nav.py').read_text());f=next(n for n in t.body if isinstance(n,ast.FunctionDef) and n.name=='route');exec(compile(ast.Module(body=[f],type_ignores=[]),'route','exec'),ns) bn=dict(ROOT=R,json=json,heapq=heapq,re=re);exec(ast.unparse(f).replace('graph = {}','jumps = {}; graph = {}').replace('native_jump = terrain(n) == 1','native_jump = False'),bn) cache=R/'work/191-se-graphs.pkl' if cache.exists():graphs,bgraphs,events=pickle.loads(cache.read_bytes()) else: graphs=[];bgraphs=[] for mask in range(32): extra={'switches':{str(1127+i):bool(mask&(1<100000:raise SystemExit('Limit') adjacent=lambda xy:sorted(rr.intersection({(xy[0]+dx,xy[1]+dy) for dx,dy in [(0,1),(0,-1),(1,0),(-1,0)]})) if mask==0 and adjacent((115,65)): out=dict(actions=plan,cart_approach=adjacent((115,65))[0],states=len(seen));(R/'work/191-se-solution.json').write_text(json.dumps(out,indent=2));print('FOUND',out,flush=True);break for i,eid in enumerate(levers): e=events[eid];aa=adjacent((e['x'],e['y'])) for a in aa:q.append(((a,mask^(1<51:continue if any(not e['through'] and (e['x'],e['y'])==after for ei,e in events.items() if ei not in boxids+['65']):continue new=list(boxes);new[i]=after q.append(((before,mask,tuple(new),smashed),plan+[dict(event=int(boxids[i]),direction=k,box_to=after)])) else:print('NO SOLUTION',len(seen))