Laby/laby.py

613 lines
19 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from sys import exit
import pygame
import random
# Parameters
WIDTH = 960
WAIT = 2000
SIZE = 15
WALL_COLOR = pygame.Color('#8F8F8FFF')
EXIT_COLOR = pygame.Color('#FF7F00FF')
SOFT_EDGE_COLOR = pygame.Color('#AFAFAFFF')
SHARP_EDGE_COLOR = pygame.Color('#5F5F9FFF')
FLOOR_COLOR = pygame.Color('#0F0F0FFF')
SEEN_COLOR = pygame.Color('#0F0F0FFF')
WIN_COLOR = pygame.Color('#FF0000FF')
START_COLOR = pygame.Color('#00FF00FF')
PLAYER_COLOR = pygame.Color('#0000FFFF')
UP = (-1, 0)
RIGHT = (0, 1)
DOWN = (1, 0)
LEFT = (0, -1)
FONT_FACE = 'Serif'
KP_NUMS = [pygame.K_KP0, pygame.K_KP1, pygame.K_KP2, pygame.K_KP3, pygame.K_KP4,
pygame.K_KP5, pygame.K_KP6, pygame.K_KP7, pygame.K_KP8, pygame.K_KP9]
# Secondary parameters
HEIGHT = 10*WIDTH//16
CENTERX = WIDTH // 2
CENTERY = HEIGHT // 3
WIDTHS = [(5 * WIDTH / (7 * (2 * depth + 1))) // 2 for depth in range(0, SIZE)]
WIDTHS.insert(0, 3 * WIDTHS[0] // 2)
HEIGHTS = [(6 * HEIGHT / (7 * (2 * depth + 1))) // 3 for depth in range(0, SIZE)]
HEIGHTS.insert(0, 3 * HEIGHTS[0] // 2)
FONT_SIZE = WIDTHS[1] // 15
DIRECTIONS = (UP, RIGHT, DOWN, LEFT)
ANGLESYX = ((UP, RIGHT), (DOWN, RIGHT), (DOWN, LEFT), (UP, LEFT))
SEEN_SIZE = max((SIZE * SIZE) // 50, 1)
def debug(message, maze = None, path = None):
return
print('-----------------')
print(message)
if maze is not None:
for row in range(0, len(maze)):
r = maze[row]
s = ''
sr = ''
for col in range(0, 2 * SIZE + 1):
sr += '1' if r & 1<<col else '0'
if (row % 2) or (col % 2):
if r & (1<<col):
if (row % 2) and (col % 2):
if path is not None and (row, col) in path:
s += 'O' if (row, col) == path[0] else 'o'
else:
s += '+'
else:
s += '*'
else:
s += '.'
else:
s += ' '
print(s, sr)
def back_dir(dir):
if dir is UP: return DOWN
if dir is DOWN: return UP
if dir is RIGHT: return LEFT
if dir is LEFT: return RIGHT
def shift_path(path, yx):
for i in range(0, len(path)):
p = path[i]
path[i] = (p[0] + yx[0], p[1] + yx[1])
def grow_maze(maze, path, yx = None, bdir = None, recurs = 1):
if yx is None:
for yx in range(0, len(path)):
grow_maze(maze, path, path[yx], None, 1)
return
debug(str(recurs) + ': growing', maze, path)
dontgo_dontblock = [bdir]
go_on = True
while go_on:
exits = []
for d in DIRECTIONS:
if d not in dontgo_dontblock:
d2 = d
if d is UP and yx[0] == 1:
if len(maze) < 2 * SIZE:
for row in (1, 2): maze.insert(0, 0)
shift_path(path, (2, 0))
yx = (yx[0] + 2, yx[1])
debug(str(recurs) + '...Expand UP.', maze, path)
else:
maze[0] |= 1<<(yx[1])
debug(str(recurs) + '...No UP.')
d2 = None
if d is RIGHT and yx[1] == 2 * SIZE - 1:
maze[yx[0]] |= 1<<(2 * SIZE)
debug(str(recurs) + '...No RIGHT')
d2 = None
if d is DOWN and yx[0] == len(maze) - 2:
if len(maze) < 2 * SIZE:
maze.extend([0, 0])
debug(str(recurs) + '...Expand DOWN.', maze, path)
else:
maze[2 * SIZE] |= 1<<(yx[1])
debug(str(recurs) + '...No DOWN')
d2 = None
if d is LEFT and yx[1] == 1:
if any(row & 1<<(2 * SIZE - 1) for row in maze):
maze[yx[0]] |= 1
debug(str(recurs) + '...No LEFT')
d2 = None
else:
for r in range(0, len(maze)): maze[r] = maze[r] << 2
shift_path(path, (0, 2))
yx = (yx[0], yx[1] + 2)
debug(str(recurs) + '...Expand LEFT.', maze, path)
if d2 is not None \
and not maze[yx[0] + d2[0]] & 1<<(yx[1] + d2[1]) \
and not maze[yx[0] + 2 * d2[0]] & 1<<(yx[1] + 2 * d2[1]):
debug(str(recurs) + '...exit added: ' + str(d2))
exits.append(d2)
else:
debug(str(recurs) + '...exit discarded: ' + str(d2))
if len(exits) == 0:
go_on = False
else:
d = exits[random.randrange(0, len(exits))]
debug(str(recurs) + '...Grow ' + str(d))
maze[yx[0] + 2 * d[0]] |= 1<<(yx[1] + 2 * d[1])
dontgo_dontblock.append(d)
for (y, x) in ANGLESYX:
if not maze[yx[0] + y[0]] & 1<<(yx[1]) and not maze[yx[0]] & 1<<(yx[1] + x[1]) \
and maze[yx[0] + 2 * y[0]] & 1<<(yx[1]) and maze[yx[0]] & 1<<(yx[1] + 2 * x[1]) \
and not (maze[yx[0] + 2 * y[0]] & 1<<(yx[1] + x[1]) and maze[yx[0] + y[0]] & 1<<(yx[1] + 2 * x[1])):
if (yx[0], yx[1]) in path:
action = 0
elif y in dontgo_dontblock and x in dontgo_dontblock:
action = 0
elif maze[yx[0] + 2 * y[0]] & 1<<(yx[1] + 2 * x[1]):
if y in dontgo_dontblock:
action = 2
elif x in dontgo_dontblock:
action = 1
elif not maze[yx[0] + 2 * y[0]] & 1<<(yx[1] + x[1]):
action = 1
elif not maze[yx[0] + y[0]] & 1<<(yx[1] + 2 * x[1]):
action = 2
else:
action = random.randrange(1, 3)
elif y in dontgo_dontblock:
action = random.randrange(2, 4)
elif x in dontgo_dontblock:
action = random.randrange(0, 2)
else:
action = random.randrange(0, 3)
if action == 1:
maze[yx[0] + y[0]] |= 1<<(yx[1])
elif action == 2:
maze[yx[0]] |= 1<<(yx[1] + x[1])
else:
maze[yx[0] + y[0]] |= 1<<(yx[1] + 2 * x[1])
maze[yx[0] + 2 * y[0]] |= 1<<(yx[1] + x[1])
if go_on:
yx2 = (yx[0] + 2 * d[0], yx[1] + 2 * d[1])
bdir2 = back_dir(d)
if bdir2 is not UP and (yx2[0] - 2, yx2[1]) in path:
maze[yx2[0] - 1] |= 1<<(yx2[1])
if bdir2 is not RIGHT and (yx2[0], yx2[1] + 2) in path:
maze[yx2[0]] |= 1<<(yx2[1] + 1)
if bdir2 is not DOWN and (yx2[0] + 2, yx2[1]) in path:
maze[yx2[0] + 1] |= 1<<(yx2[1])
if bdir2 is not LEFT and (yx2[0], yx2[1] - 2) in path:
maze[yx2[0]] |= 1<<(yx2[1] - 1)
oldstart = path[0]
grow_maze(maze, path, yx2, bdir2, recurs + 1)
newstart = path[0]
yx = (yx[0] + newstart[0] - oldstart[0], yx[1] + newstart[1] - oldstart[1])
def create_maze(recurs = 1, maze = None, yx = None, bdir = None, path = None):
if maze == None:
# bits are considered to be from bit 0 = LEFT to heaviest bit = RIGHT!
maze = [0, 2, 0] # 3 rows of 3 bits (for a start)
yx = (1, 1)
bdir = None
path = [yx]
debug(str(recurs) + ': coming from ' + str(bdir), maze, path)
exits = []
for d in (UP, RIGHT, DOWN, LEFT):
if d is bdir:
d2 = back_dir(d)
else:
d2 = d
if not maze[yx[0] + d2[0]] & 1<<(yx[1] + d2[1]):
exits.append(d2)
while len(exits) > 0:
d = exits[random.randrange(0, len(exits))]
exits.remove(d)
debug(str(recurs) + '...Try' + str(d))
nmaze = maze[:]
nyx = yx
npath = path[:]
if d is UP:
if nyx[0] == 1:
for row in (1, 2): nmaze.insert(0, 0)
shift_path(npath, (2, 0))
nyx = (nyx[0] + 2, nyx[1])
nmaze[nyx[0] - 2] |= 1<<(nyx[1])
npath.append((nyx[0] - 2, nyx[1]))
if nyx[1] > 1 and nmaze[nyx[0] - 2] & 1<<(nyx[1] - 2):
nmaze[nyx[0] - 2] |= 1<<(nyx[1] - 1)
if nmaze[nyx[0] - 2] & 1<<(nyx[1] + 2):
nmaze[nyx[0] - 2] |= 1<<(nyx[1] + 1)
if nyx[0] > 3 and nmaze[nyx[0] - 4] & 1<<(nyx[1]):
nmaze[nyx[0] - 3] |= 1<<(nyx[1])
if bdir is LEFT:
nmaze[nyx[0] - 1] |= 1<<(nyx[1] - 2)
nmaze[nyx[0] - 2] |= 1<<(nyx[1] - 1)
if bdir is RIGHT:
nmaze[nyx[0] - 1] |= 1<<(nyx[1] + 2)
nmaze[nyx[0] - 2] |= 1<<(nyx[1] + 1)
if len(nmaze) == 2 * SIZE + 1:
return nmaze, npath
nmaze, npath = create_maze(recurs + 1, nmaze, (nyx[0] - 2, nyx[1]), DOWN, npath)
if nmaze is not None:
return nmaze, npath
if d is RIGHT:
nmaze[nyx[0]] |= 1<<(nyx[1] + 2)
npath.append((nyx[0], nyx[1] + 2))
if nyx[0] > 1 and nmaze[nyx[0] - 2] & 1<<(nyx[1] + 2):
nmaze[nyx[0] - 1] |= 1<<(nyx[1] + 2)
if nyx[0] < len(nmaze) - 2 and nmaze[nyx[0] + 2] & 1<<(nyx[1] + 2):
nmaze[nyx[0] + 1] |= 1<<(nyx[1] + 2)
if nmaze[nyx[0]] & 1<<(nyx[1] + 4):
nmaze[nyx[0]] |= 1<<(nyx[1] + 3)
if bdir is UP:
nmaze[nyx[0] - 1] |= 1<<(nyx[1] + 2)
nmaze[nyx[0] - 2] |= 1<<(nyx[1] + 1)
if bdir is DOWN:
nmaze[nyx[0] + 1] |= 1<<(nyx[1] + 2)
nmaze[nyx[0] + 2] |= 1<<(nyx[1] + 1)
if any(row & 1<<(2 * SIZE - 1) for row in nmaze):
return nmaze, npath
nmaze, npath = create_maze(recurs + 1, nmaze, (nyx[0], nyx[1] + 2), LEFT, npath)
if nmaze is not None:
return nmaze, npath
if d is DOWN:
if nyx[0] == len(nmaze) - 2:
nmaze.extend([0, 0])
nmaze[nyx[0] + 2] |= 1<<(nyx[1])
npath.append((nyx[0] + 2, nyx[1]))
if nyx[1] > 1 and nmaze[nyx[0] + 2] & 1<<(nyx[1] - 2):
nmaze[nyx[0] + 2] |= 1<<(nyx[1] - 1)
if nmaze[nyx[0] + 2] & 1<<(nyx[1] + 2):
nmaze[nyx[0] + 2] |= 1<<(nyx[1] + 1)
if nyx[0] < len(nmaze) - 4 and nmaze[nyx[0] + 4] & 1<<(nyx[1]):
nmaze[nyx[0] + 3] |= 1<<(nyx[1])
if bdir is LEFT:
nmaze[nyx[0] + 1] |= 1<<(nyx[1] - 2)
nmaze[nyx[0] + 2] |= 1<<(nyx[1] - 1)
if bdir is RIGHT:
nmaze[nyx[0] + 1] |= 1<<(nyx[1] + 2)
nmaze[nyx[0] + 2] |= 1<<(nyx[1] + 1)
if len(nmaze) == 2 * SIZE + 1:
return nmaze, npath
nmaze, npath = create_maze(recurs + 1, nmaze, (nyx[0] + 2, nyx[1]), UP, npath)
if nmaze is not None:
return nmaze, npath
if d is LEFT:
if nyx[1] == 1:
for r in range(0, len(nmaze)): nmaze[r] = nmaze[r] << 2
shift_path(npath, (0, 2))
nyx = (nyx[0], nyx[1] + 2)
nmaze[nyx[0]] |= 1<<(nyx[1] - 2)
npath.append((nyx[0], nyx[1] - 2))
if nyx[0] > 1 and nmaze[nyx[0] - 2] & 1<<(nyx[1] - 2):
nmaze[nyx[0] - 1] |= 1<<(nyx[1] - 2)
if nyx[0] < len(nmaze) - 2 and nmaze[nyx[0] + 2] & 1<<(nyx[1] - 2):
nmaze[nyx[0] + 1] |= 1<<(nyx[1] - 2)
if nyx[1] > 3 and nmaze[nyx[0]] & 1<<(nyx[1] - 4):
nmaze[nyx[0]] |= 1<<(nyx[1] - 3)
if bdir is UP:
nmaze[nyx[0] - 1] |= 1<<(nyx[1] - 2)
nmaze[nyx[0] - 2] |= 1<<(nyx[1] - 1)
if bdir is DOWN:
nmaze[nyx[0] + 1] |= 1<<(nyx[1] - 2)
nmaze[nyx[0] + 2] |= 1<<(nyx[1] - 1)
if any(row & 1<<(2 * SIZE - 1) for row in nmaze):
return nmaze, npath
nmaze, npath = create_maze(recurs + 1, nmaze, (nyx[0], nyx[1] - 2), RIGHT, npath)
if nmaze is not None:
return nmaze, npath
return None, None
def relative(dir, rel):
if dir is UP:
return rel
elif rel is UP:
return dir
elif rel is DOWN:
if dir is RIGHT:
return LEFT
elif dir is LEFT:
return RIGHT
else:
return UP
elif rel == dir:
return DOWN
elif dir is DOWN:
if rel is RIGHT:
return LEFT
else:
return RIGHT
else:
return UP
def is_exit(path, pos, dir):
return (pos[0] + dir[0] == 0 or pos[0] + dir[0] == 2 * SIZE \
or pos[1] + dir[1] == 0 or pos[1] + dir[1] == 2 * SIZE) \
and (pos[0], pos[1]) == path[-1]
def is_wall(maze, pos, dir):
return maze[pos[0] + dir[0]] & 1<<(pos[1] + dir[1])
def new_pos(pos, dir):
return (pos[0] + 2 * dir[0], pos[1] + 2 * dir[1])
def rotate_dir(dir, left_or_right):
return DIRECTIONS[(DIRECTIONS.index(dir) + left_or_right[1]) % 4]
def draw_maze(maze, path, game, seen, pos, dir, shift = None, depth = None, clip = None):
s = pygame.display.get_surface()
if clip is None:
fake_path = [pos, new_pos(pos, dir)]
debug('played:', maze, fake_path)
s.set_clip(None)
s.fill(FLOOR_COLOR)
draw_maze(maze, path, game, seen, pos, dir, 0, 1, s.get_rect())
pygame.display.update()
s.set_clip(None)
return
# Inner/Outer - Width/Height/X/Y
iw = WIDTHS[depth]
ow = WIDTHS[depth - 1]
ih = HEIGHTS[depth]
oh = HEIGHTS[depth - 1]
ix = CENTERX + 2 * shift * iw
ox = CENTERX + 2 * shift * ow
iy = oy = CENTERY
if not pygame.Rect(ox - ow, oy - oh, 2 * ow + 1, 3 * oh + 1).colliderect(clip) \
and not pygame.Rect(ix - iw, iy - ih, 2 * iw + 1, 3 * ih + 1).colliderect(clip):
return
it = [None, (ix + iw, iy - ih), (ix - iw, iy - ih)]
ib = [None, (ix + iw, iy + ih * 2), (ix - iw, iy + ih * 2)]
ot = [None, (ox + ow, oy - oh), (ox - ow, oy - oh)]
ob = [None, (ox + ow, oy + oh * 2), (ox - ow, oy + oh * 2)]
# floor
if seen != 0 and pos in game:
alpha = game[::-1].index(pos)
if seen < 0:
alpha = 255 - 171 * alpha / len(game)
elif alpha > seen - 1:
alpha = -1
else:
alpha = 255 - 190 * alpha / seen
else:
alpha = -1
if alpha >= 0:
s.set_clip(clip)
p = pygame.Surface(((iw + ow) // 2, (oy + 2 * oh - iy - 2 * ih) // 2))
p.fill(FLOOR_COLOR)
p.set_colorkey(FLOOR_COLOR)
pygame.draw.ellipse(p, PLAYER_COLOR, p.get_rect())
p.set_alpha(alpha)
s.blit(p, ((2 * ix + 2 * ox - iw -ow) // 4, (3 * iy / 2 + 3 * ih + oy / 2 + oh) // 2))
# ahead
if is_wall(maze, pos, dir):
s.set_clip(clip)
pygame.draw.polygon(s, EXIT_COLOR if is_exit(path, pos, dir) else WALL_COLOR, [ib[1], it[1], it[-1], ib[-1]])
pygame.draw.line(s, SHARP_EDGE_COLOR, it[-1], it[1])
pygame.draw.line(s, SHARP_EDGE_COLOR, ib[-1], ib[1])
pygame.draw.line(s, SOFT_EDGE_COLOR, it[-1], ib[-1])
pygame.draw.line(s, SOFT_EDGE_COLOR, it[1], ib[1])
else:
r = pygame.Rect(ix - iw, iy - ih, 2 * iw + 1, 3 * ih + 1).clip(clip)
if r.width > 0 and r.height > 0:
draw_maze(maze, path, game, seen, new_pos(pos, dir), dir, shift, depth + 1, r)
# sides
for d in (LEFT, RIGHT):
tmpdir = relative(d, dir)
s.set_clip(clip)
if (d is LEFT and shift > 0) or (d is RIGHT and shift < 0):
if not is_wall(maze, pos, tmpdir):
pygame.draw.line(s, SHARP_EDGE_COLOR, ot[-1 * d[1]], ob[-1 * d[1]])
elif is_wall(maze, pos, tmpdir):
pygame.draw.polygon(s, EXIT_COLOR if is_exit(path, pos, tmpdir) else WALL_COLOR, [ib[d[1]], it[d[1]], ot[d[1]], ob[d[1]]])
pygame.draw.line(s, SHARP_EDGE_COLOR, it[d[1]], ot[d[1]])
pygame.draw.line(s, SHARP_EDGE_COLOR, ib[d[1]], ob[d[1]])
pygame.draw.line(s, SOFT_EDGE_COLOR, it[d[1]], ib[d[1]])
pygame.draw.line(s, SOFT_EDGE_COLOR, ot[d[1]], ob[d[1]])
else:
tmppos = new_pos(pos, tmpdir)
r = pygame.Rect(ix + iw if d is RIGHT else ox - ow, 0, d[1] * (ox + d[1] * ow) - d[1] * (ix + d[1] * iw) + 1, HEIGHT).clip(clip)
if r.width > 0 and r.height > 0:
draw_maze(maze, path, game, seen, tmppos, dir, shift + d[1], depth, r)
if not is_wall(maze, tmppos, dir):
s.set_clip(clip)
pygame.draw.line(s, SHARP_EDGE_COLOR, it[d[1]], ib[d[1]])
def get_help_surface(maze, path = None):
size = HEIGHT // SIZE
s = pygame.Surface((SIZE * size, SIZE * size)).convert()
for row in range(0, SIZE):
for col in range(0, SIZE):
yx = (2 * row + 1, 2 * col + 1)
if path and yx == path[0]:
color = START_COLOR
elif path and yx == path[-1]:
color = EXIT_COLOR
else:
color = FLOOR_COLOR
pygame.draw.rect(s, color, pygame.Rect(col * size + 1, row * size + 1, size - 2, size - 2))
if is_wall(maze, yx, UP):
color = SHARP_EDGE_COLOR
else:
color = FLOOR_COLOR
pygame.draw.line(s, color, (col * size, row * size), ((col + 1) * size - 1, row * size))
if is_wall(maze, yx, RIGHT):
color = SHARP_EDGE_COLOR
else:
color = FLOOR_COLOR
pygame.draw.line(s, color, ((col + 1) * size - 1, row * size), ((col + 1) * size - 1, (row + 1) * size - 1))
if is_wall(maze, yx, DOWN):
color = SHARP_EDGE_COLOR
else:
color = FLOOR_COLOR
pygame.draw.line(s, color, (col * size, (row + 1) * size - 1), ((col + 1) * size - 1, (row + 1) * size - 1))
if is_wall(maze, yx, LEFT):
color = SHARP_EDGE_COLOR
else:
color = FLOOR_COLOR
pygame.draw.line(s, color, (col * size, row * size), (col * size, (row + 1) * size - 1))
return s
def get_player_surface():
size = HEIGHT // SIZE
p = pygame.Surface((size, size)).convert()
p.fill(WALL_COLOR)
pygame.draw.line(p, PLAYER_COLOR, (size // 3, 2 * size // 3), (size // 2, size // 3))
pygame.draw.line(p, PLAYER_COLOR, (2 * size // 3, 2 * size // 3), (size // 2, size // 3))
p.set_colorkey(WALL_COLOR)
return p
def draw_help(helpmap, pos = None, dir = None, player = None):
s = pygame.display.get_surface()
s.fill(WALL_COLOR)
s.blit(helpmap, (CENTERX - helpmap.get_width() // 2, 0))
if pos:
size = HEIGHT // SIZE
x = CENTERX - helpmap.get_width() // 2 + ((pos[1] - 1) / 2) * size
y = ((pos[0] - 1) / 2) * size
if dir is RIGHT:
p = pygame.transform.rotate(player, -90)
elif dir is LEFT:
p = pygame.transform.rotate(player, 90)
elif dir is DOWN:
p = pygame.transform.rotate(player, 180)
else:
p = player
s.blit(p, (x + 1, y + 1))
pygame.display.update()
def draw_end(helpmap, path, game):
txt = pygame.font.SysFont(FONT_FACE, FONT_SIZE)\
.render(str(len(game) - 1) + ' STEPS (+ ' + str(len(game) - len(path)) + ')', True, WIN_COLOR)
pygame.display.get_surface().blit(txt, (CENTERX - txt.get_width() // 2, CENTERY - txt.get_height() // 2))
pygame.display.update()
pygame.time.wait(WAIT)
size = HEIGHT // SIZE
player = pygame.Surface((size, size)).convert()
player.fill(WALL_COLOR)
pygame.draw.circle(player, PLAYER_COLOR, (size // 2, size // 2), size // 3)
shadow = pygame.Surface((size, size)).convert()
shadow.blit(player, (0, 0))
player.set_colorkey(WALL_COLOR)
shadow.set_colorkey(WALL_COLOR)
shadow.set_alpha(84)
endwait = True
while endwait and len(game):
yx = game.pop(0)
y = ((yx[0] - 1) / 2) * size
x = ((yx[1] - 1) / 2) * size
helpmap.blit(shadow, (x, y))
draw_help(helpmap, yx, UP, player)
pygame.time.wait(200)
for evt in pygame.event.get():
if evt.type == pygame.QUIT:
endwait = False
elif evt.type == pygame.KEYUP and evt.key == pygame.K_ESCAPE:
endwait = False
if endwait:
pygame.time.wait(WAIT)
def draw_fake_maze():
high = 1
low = 1
for i in range(0, SIZE):
high = (high<<2) | 3
low = (low<<2) | 1
fake = [high]
for i in range(0, SIZE):
fake.extend([low, high])
draw_help(get_help_surface(fake))
# Pygame initialisation
pygame.init()
pygame.event.set_allowed([pygame.QUIT, pygame.KEYUP])
pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('Laby')
pygame.mouse.set_visible(0)
# Choose maze size
draw_fake_maze()
redraw = False
while True:
evt = pygame.event.wait()
if evt.type == pygame.QUIT:
exit()
elif evt.type == pygame.KEYUP:
if evt.key == pygame.K_ESCAPE:
exit()
elif evt.key == pygame.K_KP_PLUS:
SIZE += 5
redraw = True
elif evt.key == pygame.K_KP_MINUS:
SIZE -= 5
redraw = True
else:
break
if redraw:
draw_fake_maze()
redraw = False
# Maze creation
maze, path = create_maze()
debug('PATH ', maze, path)
grow_maze(maze, path)
debug('GROWN ', maze, path)
# Player variables
play_pos = path[0]
play_dir = DIRECTIONS[random.randrange(0, 4)]
game = [play_pos]
helpmap = get_help_surface(maze, path)
heading = get_player_surface()
# Main loop
seen = 0
endwait = True
help = False
run = True
draw_maze(maze, path, game, seen, play_pos, play_dir)
while run:
evt = pygame.event.wait()
if evt.type == pygame.QUIT:
run = False
endwait = False
elif evt.type == pygame.KEYUP:
if evt.key == pygame.K_ESCAPE:
run = False
endwait = False
elif evt.key == pygame.K_h:
help = not help
elif evt.key == pygame.K_UP:
rel_dir = relative(UP, play_dir)
if is_exit(path, play_pos, rel_dir):
run = False
elif not is_wall(maze, play_pos, rel_dir):
play_pos = new_pos(play_pos, rel_dir)
game.append(play_pos)
elif evt.key == pygame.K_RIGHT:
play_dir = rotate_dir(play_dir, RIGHT)
elif evt.key == pygame.K_DOWN:
rel_dir = relative(DOWN, play_dir)
if is_exit(path, play_pos, rel_dir):
run = False
elif not is_wall(maze, play_pos, rel_dir):
play_pos = new_pos(play_pos, rel_dir)
game.append(play_pos)
elif evt.key == pygame.K_LEFT:
play_dir = rotate_dir(play_dir, LEFT)
elif evt.key in KP_NUMS:
seen = SEEN_SIZE * KP_NUMS.index(evt.key)
elif evt.key == pygame.K_KP_MULTIPLY:
seen = -SEEN_SIZE
elif evt.key == pygame.K_KP_PLUS:
seen += 5 * SEEN_SIZE
elif evt.key == pygame.K_KP_MINUS:
seen -= 5 * SEEN_SIZE
if help:
draw_help(helpmap, play_pos, play_dir, heading)
else:
draw_maze(maze, path, game, seen, play_pos, play_dir)
if endwait:
draw_end(helpmap, path, game)