forked from ASPP/pelita
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_layout_consistency.py
69 lines (57 loc) · 2.45 KB
/
check_layout_consistency.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
"""Detect if a layout contains "chambers" with food"""
import sys
import networkx
from pelita.layout import parse_layout
def get_hw(layout):
walls = layout['walls']
width = max([coord[0] for coord in walls]) + 1
height = max([coord[1] for coord in walls]) + 1
return height, width
def layout_to_graph(layout):
"""Return a networkx.Graph object given the layout
"""
graph = networkx.Graph()
height, width = get_hw(layout)
walls = layout['walls']
for x in range(width):
for y in range(height):
if (x, y) not in walls:
# this is a free position, get its neighbors
for delta_x, delta_y in ((1,0), (-1,0), (0,1), (0,-1)):
neighbor = (x + delta_x, y + delta_y)
# we don't need to check for getting neighbors out of the maze
# because our mazes are all surrounded by walls, i.e. our
# deltas will not put us out of the maze
if neighbor not in walls:
# this is a genuine neighbor, add an edge in the graph
graph.add_edge((x, y), neighbor)
return graph
if __name__ == '__main__':
# either read a file or read from stdin
if len(sys.argv) == 1:
flname = 'stdin'
layout = parse_layout(sys.stdin.read())
else:
flname = sys.argv[1]
with open(flname, "rt") as fl:
layout = parse_layout(fl.read())
# first of all, check for symmetry
# if something is found on the left, it should be found center-mirrored on the right
height, width = get_hw(layout)
known = layout['walls']+layout['food']
layout['empty'] = [(x,y) for x in range(width) for y in range(height) if (x,y) not in known]
for x in range(width // 2):
for y in range(height):
coord = (x, y)
cmirror = (width-x-1, height-y-1)
for typ_ in ('walls', 'food', 'empty'):
if (coord in layout[typ_]) and (cmirror not in layout[typ_]):
print(f'{flname}: Layout is not symmetric {coord} != {cmirror}')
graph = layout_to_graph(layout)
# check for dead_ends
for node, degree in graph.degree():
if degree < 2:
print(f'{flname}: found dead end in {node}')
if networkx.node_connectivity(graph) < 2:
entrance = networkx.minimum_node_cut(graph).pop()
print(f'{flname}: Detected chamber, entrance: {entrance}')