From 46ead34f45e6926070de8813e5a35cb5b6dcdbd7 Mon Sep 17 00:00:00 2001 From: Niels Serup Date: Tue, 14 Aug 2012 17:02:06 +0200 Subject: [PATCH] Fixed critical infinite loop bug in teleportermap. --- robotgame/logic/direction.py | 2 +- robotgame/logic/teleportermap.py | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/robotgame/logic/direction.py b/robotgame/logic/direction.py index 1107bcf..78a96db 100644 --- a/robotgame/logic/direction.py +++ b/robotgame/logic/direction.py @@ -80,7 +80,7 @@ class Left(Direction): def to_str(): 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] succ, pred = _sp(1), _sp(-1) isDirection = all_directions.__contains__ diff --git a/robotgame/logic/teleportermap.py b/robotgame/logic/teleportermap.py index 7043917..573678c 100644 --- a/robotgame/logic/teleportermap.py +++ b/robotgame/logic/teleportermap.py @@ -41,6 +41,9 @@ class Empty(object): class Forbidden(object): pass +class StrictlyForbidden(object): + pass + class Visited(object): pass @@ -50,7 +53,7 @@ def generate_teleporter_map(width, height): def _get(p): 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]] def _set(p, val): @@ -72,8 +75,12 @@ def generate_teleporter_map(width, height): while True: if pos[0] == 1 and random.randint(0, height) == 0: break - t, found = random.randrange(4), None - for direc in all_directions[t:] + all_directions[:t]: + t = random.randrange(4) + found = None + alldirs = all_directions + if random.choice((True, False)): + alldirs.reverse() + for direc in alldirs[t:] + alldirs[:t]: npos = direc.next_pos(pos) if found is None and npos[0] != 0 and _get(npos) is Empty and ( (direc is Right and @@ -92,12 +99,21 @@ def generate_teleporter_map(width, height): pos = found if pos[0] == 1: break - _set(pos, Forbidden) + + _set(pos, StrictlyForbidden) for direc in all_directions: npos = direc.next_pos(pos) if _get(npos) is Visited: pos = npos 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) return m @@ -121,6 +137,7 @@ def print_map(tmap): c = tmap[x][y] print({Empty: '%', Forbidden: '#', + StrictlyForbidden: '!', Visited: 'ยท'}[c], end='') print()