about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--brutalmaze/characters.py14
-rw-r--r--brutalmaze/constants.py6
-rw-r--r--brutalmaze/maze.py50
3 files changed, 43 insertions, 27 deletions
diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py
index bb3dd22..c2d2439 100644
--- a/brutalmaze/characters.py
+++ b/brutalmaze/characters.py
@@ -106,10 +106,11 @@ class Hero:
 
 class Enemy:
     """Object representing an enemy."""
-    def __init__(self, surface, maze, n, x, y):
+    def __init__(self, surface, maze, kind, x, y):
         self.surface, self.maze = surface, maze
-        self.angle, self.color = pi / 4, TANGO[TANGO_KEYS[n]]
+        self.angle, self.color = pi / 4, TANGO[kind]
         self.x, self.y = x, y
+        self.maze[x][y] = ENEMY
 
         self.awake = False
         self.offsetx = self.offsety = 0
@@ -128,7 +129,10 @@ class Enemy:
     def place(self, x=0, y=0):
         """Move the enemy by (x, y)."""
         self.x += x
+        self.x %= len(self.maze)
         self.y += y
+        self.y %= len(self.maze)
+        self.maze[self.x][self.y] = ENEMY
 
     def move(self):
         """Handle the movement of the enemy.
@@ -145,9 +149,9 @@ class Enemy:
         directions = [(sign(MIDDLE - self.x), 0), (0, sign(MIDDLE - self.y))]
         shuffle(directions)
         for x, y in directions:
-            if (x or y) and self.maze[self.x + x][self.y + y] == False:
-                self.offsetx = x * -4
-                self.offsety = y * -4
+            if (x or y) and self.maze[self.x + x][self.y + y] == EMPTY:
+                self.offsetx, self.offsety = x * -4, y * -4
+                self.maze[self.x][self.y] = EMPTY
                 self.place(x, y)
                 return True
         return False
diff --git a/brutalmaze/constants.py b/brutalmaze/constants.py
index bcfb070..95d9c79 100644
--- a/brutalmaze/constants.py
+++ b/brutalmaze/constants.py
@@ -21,6 +21,8 @@ from pygame.locals import *
 from pygame.math import Vector2
 
 SQRT2 = 2 ** 0.5
+EMPTY, WALL, HERO, ENEMY = range(4)
+ADJACENT_GRIDS = (1, 0), (0, 1), (-1, 0), (0, -1)
 
 FPS = 30
 SIZE = 400, 400
@@ -37,7 +39,7 @@ TANGO = {'Butter': ((252, 233, 79), (237, 212, 0), (196, 160, 0)),
          'Scarlet Red': ((239, 41, 41), (204, 0, 0), (164, 0, 0)),
          'Aluminium': ((238, 238, 236), (211, 215, 207), (186, 189, 182),
                        (136, 138, 133), (85, 87, 83), (46, 52, 54))}
-TANGO_KEYS = ('Butter', 'Orange', 'Chocolate', 'Chameleon',
-              'Sky Blue', 'Plum', 'Scarlet Red', 'Aluminium')
+ENEMIES = ('Butter', 'Orange', 'Chocolate', 'Chameleon',
+           'Sky Blue', 'Plum', 'Scarlet Red')
 BG_COLOR = TANGO['Aluminium'][-1]
 FG_COLOR = TANGO['Aluminium'][0]
diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py
index 42be98a..423f6c9 100644
--- a/brutalmaze/maze.py
+++ b/brutalmaze/maze.py
@@ -19,7 +19,7 @@
 
 from collections import deque
 from math import atan, cos, sin, pi
-from random import getrandbits
+from random import choice, getrandbits, randint
 
 import pygame
 
@@ -45,9 +45,9 @@ class Maze:
         self.rangey = range(MIDDLE - h, MIDDLE + h + 1)
 
         def wall(bit, upper=True):
-            if bit: return deque([True]*ROAD_WIDTH + [False]*ROAD_WIDTH)
-            if upper: return deque([True] * (ROAD_WIDTH<<1))
-            return deque([False] * (ROAD_WIDTH<<1))
+            if bit: return deque([WALL]*ROAD_WIDTH + [EMPTY]*ROAD_WIDTH)
+            if upper: return deque([WALL] * (ROAD_WIDTH<<1))
+            return deque([EMPTY] * (ROAD_WIDTH<<1))
 
         self.map = deque()
         for _ in range(MAZE_SIZE):
@@ -58,8 +58,16 @@ class Maze:
                 lower.extend(wall(b, False))
             for _ in range(ROAD_WIDTH): self.map.append(upper.__copy__())
             for _ in range(ROAD_WIDTH): self.map.append(lower.__copy__())
+        self.enemies = []
+        while len(self.enemies) < 8:
+            x, y = MIDDLE + randint(-w, w), MIDDLE + randint(-h, h)
+            if self.map[x][y] != WALL: continue
+            if all(self.map[x + a][y + b] == WALL for a, b in ADJACENT_GRIDS):
+                continue
+            self.enemies.append(
+                Enemy(self.surface, self.map, choice(ENEMIES), x, y))
         self.hero = Hero(self.surface)
-        self.enemies = [Enemy(self.surface, self.map, 4, 34, 34)]
+        self.map[MIDDLE][MIDDLE] = HERO
         self.right = self.down = self.offsetx = self.offsety = 0
         self.draw()
 
@@ -68,7 +76,7 @@ class Maze:
         self.surface.fill(BG_COLOR)
         for i in self.rangex:
             for j in self.rangey:
-                if not self.map[i][j]: continue
+                if self.map[i][j] != WALL: continue
                 x, y = pos(i, j, self.distance, self.middlex, self.middley)
                 square = regpoly(4, int(self.distance / SQRT2), pi / 4, x, y)
                 fill_aapolygon(self.surface, square, FG_COLOR)
@@ -84,12 +92,23 @@ class Maze:
         if starty > stopy : starty, stopy = stopy, starty
         for i in range(startx, stopx + 1):
             for j in range(starty, stopy + 1):
-                if not self.map[i][j] or (i, j) == (enemy.x, enemy.y): continue
+                if self.map[i][j] != WALL: continue
                 x, y = pos(i, j, self.distance, self.middlex, self.middley)
                 d = abs(dy*(x-self.x) - dx*(y-self.y)) / (dy**2 + dx**2)**0.5
                 if d <= mind: return
         enemy.awake = True
 
+    def rotate(self, x, y):
+        """Rotate the maze by (x, y)."""
+        for enemy in self.enemies: self.map[enemy.x][enemy.y] = EMPTY
+        if x:
+            self.offsetx = 0
+            self.map.rotate(x)
+        if y:
+            self.offsety = 0
+            for d in self.map: d.rotate(y)
+        for enemy in self.enemies: enemy.place(x, y)
+
     def update(self):
         """Update the maze."""
         modified = False
@@ -114,19 +133,10 @@ class Maze:
             modified = True
 
         if modified:
-            self.map[MIDDLE][MIDDLE] = False
-            if abs(self.offsetx) == 5:
-                s = sign(self.offsetx)
-                self.offsetx = 0
-                self.map.rotate(s)
-                for enemy in self.enemies: enemy.place(x=s)
-            if abs(self.offsety) == 5:
-                s = sign(self.offsety)
-                self.offsety = 0
-                for d in self.map: d.rotate(s)
-                for enemy in self.enemies: enemy.place(y=s)
-            self.map[MIDDLE][MIDDLE] = None
-
+            self.map[MIDDLE][MIDDLE] = EMPTY
+            self.rotate(sign(self.offsetx) * (abs(self.offsetx)==5),
+                        sign(self.offsety) * (abs(self.offsety)==5))
+            self.map[MIDDLE][MIDDLE] = HERO
             self.middlex = self.x + self.offsetx*self.step
             self.middley = self.y + self.offsety*self.step
             self.draw()