Normally this would be a very simple example of a game, maybe even in Season 1. However, if it is used there only introduce the very simple maze algorithms!
from Window import Window
from Game import Game
def main():
window = Window()
window.setLogo("logo32x32.png")
window.setCaption("Maze Game by Appledog")
window.setSize(800, 600)
window.setFont("PxPlus_IBM_VGA_8x16-2x.ttf", 32)
game = Game(window)
game.start()
if __name__ == "__main__":
main()
As you can see from this code, this is going to be a pygame terminal framework game. We're going to use a 2x wide (40 column) font for this for aesthetic purposes.
Standard, but there are some changes to draw(), update() and so forth. Also observe the changes to the game data at the start of the class.
import random
import pygame
from Maze import Maze
class Game:
def __init__(self, window):
self.window = window
self.screen = window.screen
self.font = window.font
self.logo = window.logo
# Game Data
self.FPS = 60
self.clock = pygame.time.Clock()
self.maze = Maze(19, 14, 30, 30)
self.maze.binary_tree_maze()
self.maze.cwidth = 32
self.maze.cheight = 32
self.px = 1
self.py = 1
self.tx = random.randint(0, self.maze.width)
self.ty = random.randint(0, self.maze.height)
def start(self):
while True:
self.checkEvents()
self.update()
self.draw()
self.clock.tick(self.FPS)
def update(self):
if self.px == self.tx and self.py == self.ty:
print("YOU WIN!")
self.quit()
def draw(self):
self.screen.fill((0, 0, 0)) # Clear the screen.
self.maze.draw(self.screen)
self.drawText(self.tx, self.ty, "X", "gold")
self.drawText(self.px, self.py, "@", "gray")
pygame.display.flip() # update the display.
def checkEvents(self):
for event in pygame.event.get():
# Window Quit Event
if event.type == pygame.QUIT:
self.quit()
return
# Keyboard Events
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
self.quit()
elif event.key == pygame.K_LEFT:
if not self.maze.get_wall(self.px, self.py, 'west'):
self.px = self.px - 1
elif event.key == pygame.K_RIGHT:
if not self.maze.get_wall(self.px, self.py, 'east'):
self.px = self.px + 1
elif event.key == pygame.K_UP:
if not self.maze.get_wall(self.px, self.py, 'north'):
self.py = self.py - 1
elif event.key == pygame.K_DOWN:
if not self.maze.get_wall(self.px, self.py, 'south'):
self.py = self.py + 1
def drawText(self, at_x, at_y, text, color):
text_surface = self.font.render(text, False, color)
x = self.window.fontwidth * at_x
y = self.window.fontheight * at_y
self.screen.blit(text_surface, (x+2, y+2))
def quit(self):
quit()
exit()
Unchanged.
class Cell:
def __init__(self):
self.north = True
self.east = True
self.west = True
self.south = True
self.wall_color = "gray"
Just a simple class to store the info about walls.
The work is done here. Note the requirement for class Cell (shown above):
import random
import pygame
from Cell import Cell
class Maze:
def __init__(self, w, h, cw, ch):
self.width = w
self.height = h
self.cwidth = cw
self.cheight = ch
self.map = [[Cell() for _ in range(w)] for _ in range(h)]
def get_wall(self, x, y, d):
if d == 'north' and self.map[y][x].north:
return True
elif d == 'south' and self.map[y][x].south:
return True
elif d == 'west' and self.map[y][x].west:
return True
elif d == 'east' and self.map[y][x].east:
return True
# fail false.
return False
def set_wall(self, x, y, d, s):
if d == "north":
self.map[y][x].north = s
if y > 0:
self.map[y-1][x].north = s
elif d == "east":
self.map[y][x].east = s
if x < self.width:
self.map[y][x+1].west = s
elif d == "west":
self.map[y][x].west = s
if x > 0:
self.map[y][x-1].east = s
elif d == "south":
self.map[y][x].south = s
if y < self.width:
self.map[y+1][x].north = s
else:
print("unknown wall position")
quit()
exit()
def draw(self, screen):
line_color = "gray"
for y in range(self.height):
for x in range(self.width):
c = self.map[y][x]
ax = 2 + x * self.cwidth
ay = 2 + y * self.cheight
bx = ax + self.cwidth
by = ay + self.cheight
if c.north:
pygame.draw.line(screen, line_color, (ax, ay), (bx, ay))
if c.south:
pygame.draw.line(screen, line_color, (ax, by), (bx, by))
if c.west:
pygame.draw.line(screen, line_color, (ax, ay), (ax, by))
if c.east:
pygame.draw.line(screen, line_color, (bx, ay), (bx, by))
def binary_tree_maze(self):
for x in range(self.width):
for y in range(self.height):
if x == self.width - 1 and y == self.height - 1:
continue
elif x == self.width - 1:
self.set_wall(x, y, "south", False)
elif y == self.height - 1:
self.set_wall(x, y, "east", False)
else:
if random.choice([True, False]):
self.set_wall(x, y, "east", False)
else:
self.set_wall(x, y, "south", False)
The binary tree maze algorithm is a simple algorithm for generating mazes. It is often used in computer graphics, game development, and robotics.
The binary tree maze algorithm works by iteratively deciding whether to create passages to the east or south, resulting in a maze with paths that resemble a binary tree structure. The randomness adds variability to the generated mazes. This algorithm is relatively easy to understand, making it suitable for beginners exploring maze generation algorithms and basic grid-based world generation.