0

I'm solving this maze game so i have to make an algorithm for this maze. Mazees are made randomly. The code for making the maze is as follows :

from random import shuffle
"""Contains the Maze class which is the array-represented maze."""

class Maze:

  def __init__(self, rows=30, cols=40):

    self.rows = rows
    self.cols = cols
    self.keep_going = 1

    self.maze = {}
    for y in range(rows):
      for x in range(cols):
        cell = {'south' : 1, 'east' : 1, 'visited': 0}
        self.maze[(x,y)] = cell

  def generate(self, start_cell=None, stack=[]):
    """Generates a random maze using a magical simple recursive function."""

    if start_cell is None:
      start_cell = self.maze[(self.cols-1, self.rows-1)]
    
    if not self.keep_going:
      return

    self.check_finished()
    neighbors = []

    # if the stack is empty, add the start cell
    if len(stack) == 0:
      stack.append(start_cell)

    # set current cell to last cell
    curr_cell = stack[-1]

    # get neighbors and shuffle 'em up a bit
    neighbors = self.get_neighbors(curr_cell)
    shuffle(neighbors)

    for neighbor in neighbors:
      if neighbor['visited'] == 0:
        neighbor['visited'] = 1
        stack.append(neighbor)
        self.knock_wall(curr_cell, neighbor)

        self.generate(start_cell, stack)

  def get_coords(self, cell):
    # grabs coords of a given cell
    coords = (-1, -1)
    for k in self.maze:
      if self.maze[k] is cell:
        coords = (k[0], k[1])
        break
    return coords

  def get_neighbors(self, cell):
    # obvious
    neighbors = []

    (x, y) = self.get_coords(cell)
    if (x, y) == (-1, -1):
      return neighbors

    north = (x, y-1)
    south = (x, y+1)
    east = (x+1, y)
    west = (x-1, y)
    
    if north in self.maze:
      neighbors.append(self.maze[north])
    if south in self.maze:
      neighbors.append(self.maze[south])
    if east in self.maze:
      neighbors.append(self.maze[east])
    if west in self.maze:
      neighbors.append(self.maze[west])

    return neighbors

  def knock_wall(self, cell, neighbor):
    # knocks down wall between cell and neighbor.
    xc, yc = self.get_coords(cell)
    xn, yn = self.get_coords(neighbor)

    # Which neighbor?
    if xc == xn and yc == yn + 1:
      # neighbor's above, knock out south wall of neighbor
      neighbor['south'] = 0
    elif xc == xn and yc == yn - 1:
      # neighbor's below, knock out south wall of cell
      cell['south'] = 0
    elif xc == xn + 1 and yc == yn:
      # neighbor's left, knock out east wall of neighbor
      neighbor['east'] = 0
    elif xc == xn - 1 and yc == yn:
      # neighbor's right, knock down east wall of cell
      cell['east'] = 0

  def check_finished(self):
    # Checks if we're done generating
    done = 1
    for k in self.maze:
      if self.maze[k]['visited'] == 0:
        done = 0
        break
    if done:
      self.keep_going = 0

And this is the maze game code.

from sys import argv
import pygame
from pygame.locals import *
from Maze import Maze

import time

Keep_Going = 1

class Game:

  def __init__(self, diff, dim, path):
    self.size = (800,600)
    self.screen = pygame.display.set_mode(self.size)
    pygame.display.set_caption('경남대학교 알고리즘 텀프로젝트')

    font = pygame.font.SysFont(pygame.font.get_default_font(), 55)
    text = font.render("Loading...", 1, (255,255,255))
    rect = text.get_rect()
    rect.center = self.size[0]/2, self.size[1]/2
    self.screen.blit(text, rect)
    pygame.display.update(rect)

    self.diff = diff
    self.dim = map(int, dim.split('x'))
    self.path = path

  def start(self):
    self.maze_obj = Maze(*self.dim)# pass args to change maze size: Maze(10, 10)
    if self.diff == 0:
      self.maze_obj.generate(self.maze_obj.maze[(0,0)])
    else:
      self.maze_obj.generate()
    self.draw_maze()
    self.reset_player()

I have to write codes in here


    
    **while Keep_Going == 1:
        #Here are Algorithm
        break**


  def reset_player(self):
    # Make the sprites for the player.
    w, h = self.cell_width - 3, self.cell_height - 3
    rect = 0, 0, w, h
    base = pygame.Surface((w,h))
    base.fill( (255,255,255) )
    self.red_p = base.copy()
    self.green_p = base.copy()
    self.blue_p = base.copy()
    self.goldy = base.copy()
    if self.path == 1:
      r = (255,0,0)
      g = (0,255,0)
    else:
      r = g = (255,255,255)
    b = (0,0,255)
    gold = (0xc5,0x93,0x48)
    pygame.draw.ellipse(self.red_p, r, rect)
    pygame.draw.ellipse(self.green_p, g, rect)
    pygame.draw.ellipse(self.blue_p, b, rect)
    pygame.draw.ellipse(self.goldy, gold, rect)

    # Make a same-size matrix for the player.
    self.player_maze = {}
    for y in range(self.maze_obj.rows):
      for x in range(self.maze_obj.cols):
        cell = {'visited' : 0} # if 1, draws green. if >= 2, draws red.
        self.player_maze[(x,y)] = cell
        self.screen.blit(base, (x*self.cell_width+2, y*self.cell_height+2))

    self.screen.blit(self.goldy, (x*self.cell_width+2, y*self.cell_height+2))
    self.cx = self.cy = 0
    self.curr_cell = self.player_maze[(self.cx, self.cy)] # starts at origin

    self.last_move = None # For last move fun

  def draw_maze(self):
    self.screen.fill( (255,255,255) )
    self.cell_width = self.size[0]/self.maze_obj.cols
    self.cell_height = self.size[1]/self.maze_obj.rows

    for y in range(self.maze_obj.rows):
      for x in range(self.maze_obj.cols):
        if self.maze_obj.maze[(x, y)]['south']: # draw south wall
          pygame.draw.line(self.screen, (0,0,0), \
            (x*self.cell_width, y*self.cell_height + self.cell_height), \
            (x*self.cell_width + self.cell_width, \
            y*self.cell_height + self.cell_height) )
        if self.maze_obj.maze[(x, y)]['east']: # draw east wall
          pygame.draw.line(self.screen, (0,0,0), \
            (x*self.cell_width + self.cell_width, y*self.cell_height), \
            (x*self.cell_width + self.cell_width, y*self.cell_height + \
            self.cell_height) )
    # Screen border
    pygame.draw.rect(self.screen, (0,0,0), (0,0, self.size[0], self.size[1]), 1)
    pygame.display.update()

  def loop(self, _key):
    self.clock = pygame.time.Clock()
    self.keep_going = 1
    moved = 0
    self.clock.tick(10)
        
    if _key == 'd':
      self.move_player('d')
      moved = 1
        
    if _key == 'u':
      self.move_player('u')
      moved = 1
        
    if _key == 'l':
      self.move_player('l')
      moved = 1
        
    if _key == 'r':
      self.move_player('r')
      moved = 1

    self.draw_player()
    pygame.display.update()

And i made no_move_~~~ to distinguish which wall I meet.

  def move_player(self, dir):
    global Keep_Going
    global no_move
    global no_move_east
    global no_move_south
    global no_move_west
    global no_move_north

    try:
      if dir == 'u':
        if not self.maze_obj.maze[(self.cx, self.cy-1)]['south']:
          self.cy -= 1
          self.curr_cell['visited'] += 1
        else: no_move_north = 1
      elif dir == 'd':
        if not self.maze_obj.maze[(self.cx, self.cy)]['south']:
          self.cy += 1
          self.curr_cell['visited'] += 1
        else: no_move_south = 1
      elif dir == 'l':
        if not self.maze_obj.maze[(self.cx-1, self.cy)]['east']:
          self.cx -= 1
          self.curr_cell['visited'] += 1
        else: no_move_west = 1
      elif dir == 'r':
        if not self.maze_obj.maze[(self.cx, self.cy)]['east']:
          self.cx += 1
          self.curr_cell['visited'] += 1
        else: no_move_east = 1
      else:
        no_move = 1
    except KeyError: # Tried to move outside screen
      no_move = 1
    # Handle last move...
    if ((dir == 'u' and self.last_move == 'd') or \
        (dir == 'd' and self.last_move == 'u') or \
        (dir == 'l' and self.last_move == 'r') or \
        (dir == 'r' and self.last_move == 'l')) and \
        not no_move:
      self.curr_cell['visited'] += 1

    if not no_move:
      self.last_move = dir
      self.curr_cell = self.player_maze[(self.cx, self.cy)]

    # Check for victory.
    if self.cx + 1 == self.maze_obj.cols and self.cy + 1 == self.maze_obj.rows:
      print ('Congratumalations, you beat this maze.')
      self.keep_going = 0
      Keep_Going = 0

  def draw_player(self):
    for y in range(self.maze_obj.rows):
      for x in range(self.maze_obj.cols):
        if self.player_maze[(x,y)]['visited'] > 0:
          if self.player_maze[(x,y)]['visited'] == 1:
            circ = self.green_p
          else:
            circ = self.red_p
          # draw green circles
          self.screen.blit(circ, (x*self.cell_width+2, y*self.cell_height+2))
    self.screen.blit(self.blue_p, (self.cx*self.cell_width+2, \
        self.cy*self.cell_height+2))

if __name__ == '__main__':
  pygame.init()
  args = argv[1:]
  diff = 0
  dim = '30x40'
  path = 1
  for arg in args:
    if '--diff' in arg:
      diff = int(arg.split('=')[-1])
    elif '--dim' in arg:
      dim = arg.split('=')[-1]
    elif '--path' in arg:
      path = int(arg.split('=')[-1])

  g = Game(diff, dim, path)
  g.start()

So what I want to know is what algorithm needs to escape this maze. This is part of the code I made.

       if no_move_south == 0 :
          no_move_east = 0
          print("reset n_m_e")
          print("move to south")
          self.loop('d')

        if no_move_north == 1 and no_move_east == 1 :
            self.loop('l')
            no_move_north = 0
            no_move_east = 0
            print("move to west and reset n_m_w, n_m_e")

                  

            
        elif no_move_south == 1:
            #self.loop('r')
            #print("move to east")
            while no_move_east == 0:

But I think these codes are too complicated, and I have to think about the number of cases and enter them myself.

So is there a fairly simple and decent algorithm?

Thank you for reading through.

  • 2
    If the code works and you just want to improve the code, I suggest asking a [Code Review](https://codereview.stackexchange.com/) question. – Rabbid76 Nov 15 '21 at 19:58

0 Answers0