pymaze
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
pymaze [2023/11/10 03:52] – created appledog | pymaze [2023/11/10 07:25] (current) – appledog | ||
---|---|---|---|
Line 1: | Line 1: | ||
= PyMaze | = PyMaze | ||
+ | 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! | ||
+ | |||
+ | == main.py | ||
+ | < | ||
+ | from Window import Window | ||
+ | from Game import Game | ||
+ | |||
+ | def main(): | ||
+ | window = Window() | ||
+ | window.setLogo(" | ||
+ | window.setCaption(" | ||
+ | window.setSize(800, | ||
+ | window.setFont(" | ||
+ | |||
+ | game = Game(window) | ||
+ | game.start() | ||
+ | |||
+ | if __name__ == " | ||
+ | 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. | ||
+ | |||
+ | == Game.py | ||
+ | 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, | ||
+ | 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.ty = random.randint(0, | ||
+ | |||
+ | |||
+ | 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(" | ||
+ | self.quit() | ||
+ | |||
+ | def draw(self): | ||
+ | self.screen.fill((0, | ||
+ | self.maze.draw(self.screen) | ||
+ | self.drawText(self.tx, | ||
+ | self.drawText(self.px, | ||
+ | pygame.display.flip() | ||
+ | |||
+ | 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.px = self.px - 1 | ||
+ | elif event.key == pygame.K_RIGHT: | ||
+ | if not self.maze.get_wall(self.px, | ||
+ | self.px = self.px + 1 | ||
+ | elif event.key == pygame.K_UP: | ||
+ | if not self.maze.get_wall(self.px, | ||
+ | self.py = self.py - 1 | ||
+ | elif event.key == pygame.K_DOWN: | ||
+ | if not self.maze.get_wall(self.px, | ||
+ | self.py = self.py + 1 | ||
+ | |||
+ | def drawText(self, | ||
+ | text_surface = self.font.render(text, | ||
+ | x = self.window.fontwidth * at_x | ||
+ | y = self.window.fontheight * at_y | ||
+ | self.screen.blit(text_surface, | ||
+ | |||
+ | def quit(self): | ||
+ | quit() | ||
+ | exit() | ||
+ | </ | ||
+ | |||
+ | == Window.py | ||
+ | Unchanged. | ||
+ | |||
+ | == Cell.py | ||
+ | < | ||
+ | class Cell: | ||
+ | def __init__(self): | ||
+ | self.north = True | ||
+ | self.east = True | ||
+ | self.west = True | ||
+ | self.south = True | ||
+ | self.wall_color = " | ||
+ | </ | ||
+ | |||
+ | Just a simple class to store the info about walls. | ||
+ | |||
+ | == Maze.py | ||
+ | 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, | ||
+ | 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, | ||
+ | if d == ' | ||
+ | return True | ||
+ | elif d == ' | ||
+ | return True | ||
+ | elif d == ' | ||
+ | return True | ||
+ | elif d == ' | ||
+ | return True | ||
+ | |||
+ | # fail false. | ||
+ | return False | ||
+ | |||
+ | def set_wall(self, | ||
+ | if d == " | ||
+ | self.map[y][x].north = s | ||
+ | if y > 0: | ||
+ | self.map[y-1][x].north = s | ||
+ | |||
+ | elif d == " | ||
+ | self.map[y][x].east = s | ||
+ | if x < self.width: | ||
+ | self.map[y][x+1].west = s | ||
+ | |||
+ | elif d == " | ||
+ | self.map[y][x].west = s | ||
+ | if x > 0: | ||
+ | self.map[y][x-1].east = s | ||
+ | |||
+ | elif d == " | ||
+ | self.map[y][x].south = s | ||
+ | if y < self.width: | ||
+ | self.map[y+1][x].north = s | ||
+ | |||
+ | else: | ||
+ | print(" | ||
+ | quit() | ||
+ | exit() | ||
+ | |||
+ | def draw(self, screen): | ||
+ | line_color = " | ||
+ | |||
+ | 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, | ||
+ | if c.south: | ||
+ | pygame.draw.line(screen, | ||
+ | if c.west: | ||
+ | pygame.draw.line(screen, | ||
+ | if c.east: | ||
+ | pygame.draw.line(screen, | ||
+ | |||
+ | |||
+ | 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, | ||
+ | elif y == self.height - 1: | ||
+ | self.set_wall(x, | ||
+ | else: | ||
+ | if random.choice([True, | ||
+ | self.set_wall(x, | ||
+ | else: | ||
+ | self.set_wall(x, | ||
+ | </ | ||
+ | |||
+ | === Binary Tree Maze Algorithm | ||
+ | The binary tree maze algorithm is a simple algorithm for generating mazes. It is often used in computer graphics, game development, | ||
+ | |||
+ | 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. | ||
+ | |||
+ | # Iteration over Cells: | ||
+ | ** The code iterates over each cell in the maze, represented by x and y coordinates. | ||
+ | # Corner Cells Handling: | ||
+ | ** The algorithm checks if the current cell is at the bottom-right corner of the maze (x == self.width - 1 and y == self.height - 1). If so, it continues to the next iteration, skipping the cell. This ensures that the bottom-right cell remains open. | ||
+ | ** If the cell is on the rightmost edge but not the bottom-right corner, a passage is opened to the south (self.set_wall(x, | ||
+ | ** If the cell is on the bottom edge but not the bottom-right corner, a passage is opened to the east (self.set_wall(x, | ||
+ | # Inner Cells: | ||
+ | ** For inner cells (not on the right or bottom edge), a decision is made using random.choice([True, | ||
+ | ** If True, a passage is opened to the east (self.set_wall(x, | ||
+ | ** If False, a passage is opened to the south (self.set_wall(x, |
pymaze.1699588336.txt.gz · Last modified: 2023/11/10 03:52 by appledog