Fixed critical infinite loop bug in teleportermap.

This commit is contained in:
Niels Serup 2012-08-14 17:02:06 +02:00
parent 40a7841b34
commit 46ead34f45
2 changed files with 22 additions and 5 deletions

View File

@ -80,7 +80,7 @@ class Left(Direction):
def to_str(): def to_str():
return 'left' return 'left'
all_directions = (Up, Right, Down, Left) all_directions = [Up, Right, Down, Left]
_sp = lambda n: lambda d: all_directions[(all_directions.index(d) + n) % 4] _sp = lambda n: lambda d: all_directions[(all_directions.index(d) + n) % 4]
succ, pred = _sp(1), _sp(-1) succ, pred = _sp(1), _sp(-1)
isDirection = all_directions.__contains__ isDirection = all_directions.__contains__

View File

@ -41,6 +41,9 @@ class Empty(object):
class Forbidden(object): class Forbidden(object):
pass pass
class StrictlyForbidden(object):
pass
class Visited(object): class Visited(object):
pass pass
@ -50,7 +53,7 @@ def generate_teleporter_map(width, height):
def _get(p): def _get(p):
if p[0] < 0 or p[0] >= width or p[1] < 0 or p[1] >= height: if p[0] < 0 or p[0] >= width or p[1] < 0 or p[1] >= height:
return Forbidden return StrictlyForbidden
return m[p[0]][p[1]] return m[p[0]][p[1]]
def _set(p, val): def _set(p, val):
@ -72,8 +75,12 @@ def generate_teleporter_map(width, height):
while True: while True:
if pos[0] == 1 and random.randint(0, height) == 0: if pos[0] == 1 and random.randint(0, height) == 0:
break break
t, found = random.randrange(4), None t = random.randrange(4)
for direc in all_directions[t:] + all_directions[:t]: found = None
alldirs = all_directions
if random.choice((True, False)):
alldirs.reverse()
for direc in alldirs[t:] + alldirs[:t]:
npos = direc.next_pos(pos) npos = direc.next_pos(pos)
if found is None and npos[0] != 0 and _get(npos) is Empty and ( if found is None and npos[0] != 0 and _get(npos) is Empty and (
(direc is Right and (direc is Right and
@ -92,12 +99,21 @@ def generate_teleporter_map(width, height):
pos = found pos = found
if pos[0] == 1: if pos[0] == 1:
break break
_set(pos, Forbidden)
_set(pos, StrictlyForbidden)
for direc in all_directions: for direc in all_directions:
npos = direc.next_pos(pos) npos = direc.next_pos(pos)
if _get(npos) is Visited: if _get(npos) is Visited:
pos = npos pos = npos
break break
for direc in all_directions:
npos = direc.next_pos(pos)
if _get(npos) is Forbidden:
occup_direc = succ(succ(direc))
if all(ndirec is occup_direc
or _get(ndirec.next_pos(npos)) in (Forbidden, Empty)
for ndirec in all_directions):
_set(npos, Empty)
_set((0, pos[1]), Visited) _set((0, pos[1]), Visited)
return m return m
@ -121,6 +137,7 @@ def print_map(tmap):
c = tmap[x][y] c = tmap[x][y]
print({Empty: '%', print({Empty: '%',
Forbidden: '#', Forbidden: '#',
StrictlyForbidden: '!',
Visited: '·'}[c], end='') Visited: '·'}[c], end='')
print() print()