Now correctly draws lasers behind and in front of mirrors. Phew.

This commit is contained in:
Niels Serup
2012-08-13 16:20:45 +02:00
parent a654540095
commit 7713fbaf98
5 changed files with 127 additions and 45 deletions

View File

@@ -157,28 +157,34 @@ def generate_lasers(playfield):
Return [((x, y), direction), ...]
"""
width, height = 16, 16
sources = ((pos, obj.direction) for pos, obj in filter(lambda posobj: isinstance(posobj[1], Source), playfield.items()))
sources = ((pos, obj.direction) for pos, obj
in filter(lambda posobj: isinstance(posobj[1], Source),
playfield.items()))
lasers = []
def add(start, end):
t = (min(start, end), max(start, end))
if not t in lasers:
lasers.append(t)
for start, direc in sources:
end = start
while True:
cur = playfield.get(end)
if cur is Target:
lasers.append(((start, end), direc))
add(start, end)
break
if cur is Blocker:
lasers.append(((start, end), direc))
add(start, end)
break
if cur in (MirrorLeft, MirrorRight):
if (start, end) in ((start, end) for (start, end), direc in lasers):
break
lasers.append(((start, end), direc))
add(start, end)
direc = _mirror_new_direc(cur, direc)
start = end
new_end = direc.next_pos(end)
if new_end[0] < 0 or new_end[1] < 0 or new_end[0] >= width or new_end[1] >= height:
if (start, end) not in lasers:
lasers.append(((start, new_end), direc))
if new_end[0] < 0 or new_end[1] < 0 or \
new_end[0] >= width or new_end[1] >= height:
add(start, new_end)
break
end = new_end
return lasers