User Tools

Site Tools


pymaze

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
pymaze [2023/11/10 03:53] appledogpymaze [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! 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
 +<Code>
 +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()
 +</Code>
 +
 +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.
 +
 +<Code>
 +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()
 +</Code>
 +
 +== Window.py
 +Unchanged.
 +
 +== Cell.py
 +<Code>
 +class Cell:
 +    def __init__(self):
 +        self.north = True
 +        self.east = True
 +        self.west = True
 +        self.south = True
 +        self.wall_color = "gray"
 +</Code>
 +
 +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):
 +
 +<Code>
 +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)
 +</Code>
 +
 +=== 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, 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.
 +
 +# 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, y, "south", False)). This creates a path towards the bottom of the maze.
 +** 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, y, "east", False)). This creates a path towards the right side of the maze.
 +# Inner Cells:
 +** For inner cells (not on the right or bottom edge), a decision is made using random.choice([True, False]). This randomly chooses whether to create a passage to the east or south.
 +** If True, a passage is opened to the east (self.set_wall(x, y, "east", False)).
 +** If False, a passage is opened to the south (self.set_wall(x, y, "south", False)).
pymaze.1699588422.txt.gz · Last modified: 2023/11/10 03:53 by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki