changes for veh

main
Harald Holtmann 2025-09-07 15:07:38 +02:00
parent 3fcb0685ad
commit 839b7197e7
3 changed files with 50 additions and 46 deletions

@ -43,6 +43,7 @@ def init_explore_cache():
def write_explore_cache():
return
with open("explore_cache.json", "w") as h:
h.write(json.dumps(explore_cache))

@ -167,7 +167,6 @@ class Explore:
# print()
# for p, pu in self.unification_id.items():
# print(f" {p}: {pu}")
# print()
def unify(self, path1, path2):
@ -195,10 +194,7 @@ class Explore:
for n, ((p, rid), (pm, rmid)) in enumerate(zip(self.neighbors[path], self.neighbors[pmerge])):
if rid and rmid and rid != rmid:
raise ExploreError(f"neighbor {n} of '{path}'({rid}) and '{pmerge}'({rmid}) do not match")
if rmid:
merged_neighbors.append((self._path(pm), rmid))
else:
merged_neighbors.append((self._path(p), rid))
merged_neighbors.append((self._path(p), rid or rmid))
# fix rooms
del self.rooms[pmerge]
@ -253,7 +249,7 @@ class Explore:
def is_explored(self):
return next(self.unexplored(), None) is None and all(len(p) == 1 for p in self.room_ids.values())
def guess(self, orig=None, start=Path()):
def layout(self, orig=None, start=Path()):
aedi = graph.Aedificium(self.problem)
ids = {}
@ -263,6 +259,7 @@ class Explore:
connected = set()
connections = []
connect_errors = []
for path, ns in self.neighbors.items():
src_path = path
for src_door, (trg_path, _) in enumerate(ns):
@ -272,7 +269,10 @@ class Explore:
None,
)
if trg_door is None:
raise ExploreError(f"backlink not found: {(src, trg_path, self.neighbors[trg_path])}")
# raise Exception(f"backlink not found: {(src, trg_path, self.neighbors[trg_path])}")
print(f"backlink not found: {(src, trg_path, self.neighbors[trg_path])}")
connect_errors.append((src[0], src[1], trg_path))
trg_door = 0
trg = (trg_path, trg_door)
if (src, trg) in connected or (trg, src) in connected:
@ -286,6 +286,21 @@ class Explore:
)
aedi.add_edge(src[0], src[1], trg[0], trg[1])
if connect_errors:
# try to fix connection issues
updated = False
src = {src_path: (trg_path, src_door) for src_path, src_door, trg_path in connect_errors}
trg = {trg_path: (src_path, src_door) for src_path, src_door, trg_path in connect_errors}
for trg_path, (src_path, src_door) in trg.items():
if trg_path in src:
self.neighbors[trg_path][src_door] = (src_path, "**FIXED**")
updated = True
assert updated, "could not fix connections"
self.dump()
return self.layout(orig=orig, start=start)
if orig:
rooms = orig
else:
@ -300,7 +315,7 @@ class Explore:
}
aedi.render()
return api.guess(layout)
return layout
def returnfrom(self, path):
queue = [(path, Path())]
@ -314,40 +329,13 @@ class Explore:
assert False, "return path not found"
def walk(self, path):
here = Path()
def walk(self, path, start=Path()):
here = start
for d in map(int, path.path):
here = self.neighbors[here][d][0]
return here
def room_solve(problem, nrooms, plen):
ex = Explore(problem, [d + d + d + d + d + d for d in DOORS[:plen]])
api.select(ex.problem)
res = ex.explore(Path())
ex.update(Path(), res)
ex.dump()
while True:
door, unexplored = next(ex.unexplored(), (None, None))
if unexplored is None:
break
print("explore", door, unexplored)
path = unexplored + Path([door])
res = ex.explore(path)
ex.update(path, res)
ex.dump()
ex.unify_all()
ex.dump()
print("explored", ex.is_explored())
if ex.is_explored():
print("guess", ex.guess())
print("score", ex.score)
def get_mark(rid, mask):
return Path("[" + str(int(rid[0]) ^ mask) + "]")
@ -398,6 +386,7 @@ def mark_solve(problem, nrooms):
assert ex.is_explored(), "not fully explored"
if nrooms % len(ex.rooms) != 0:
raise ExploreError(f"not all rooms could be identifed {len(ex.rooms)}/{nrooms}")
if len(ex.rooms) == nrooms:
print("found all rooms")
break
@ -415,6 +404,7 @@ def mark_solve(problem, nrooms):
orig[path] = rid[0]
print(path, p, rid)
print(orig)
# try to identify original start
start = apply_mask(exs[0].rooms[Path()], mask)
starts = []
@ -426,9 +416,21 @@ def mark_solve(problem, nrooms):
starts.append(p)
print("start", start, starts, all_masked)
assert len(starts) > 0
print("guess", ex.guess(orig=orig, start=starts[0]))
# try to reach . from there
start = None
for s in starts:
t = ex.walk(loop, start=s)
print(f"walk {s} => {t}")
if t == Path():
start = s
print("use as start", start)
assert start
layout = ex.layout(orig=orig, start=starts[0])
guess_ok = api.guess(layout)
print("guess", guess_ok)
print("score", sum(e.score for e in exs))
return guess_ok
def path_solve(problem, nrooms, plen):
@ -496,12 +498,15 @@ if __name__ == "__main__":
if problem not in problems:
raise ExploreError(f"unknown problem {problem}")
ok = False
try:
mark_solve(problem, problems[problem]["size"])
ok = mark_solve(problem, problems[problem]["size"])
api.clean_explore_cache()
except ExploreError as exc:
api.clean_explore_cache()
raise exc
print(exc)
except Exception as exc:
api.write_explore_cache()
raise exc
print(exc)
sys.exit(0 if ok else 1)

@ -5,16 +5,14 @@ class Aedificium:
PORTS = ["n", "ne", "se", "s", "sw", "nw"]
def __init__(self, problem):
self.graph = pydot.Dot(problem, graph_type="graph")
self.graph = pydot.Dot(problem, graph_type="graph", rankdir="LR")
def add_node(self, name):
self.graph.add_node(pydot.Node(name, label=name, shape="hexagon"))
def add_edge(self, scr, src_d, trg, trg_d):
self.graph.add_edge(
pydot.Edge(
scr, trg
) # , headport=self.PORTS[src_d], tailport=self.PORTS[trg_d])
pydot.Edge(scr, trg) # , headport=self.PORTS[src_d], tailport=self.PORTS[trg_d])
)
def render(self):