Search code examples
pythonnumpymaze

How to come to the ending point of a maze?


In my code in the read_file method I am reading a file and returning an 2d array that contains the lines of the maze. E.g. [[1 0 0 0 0 1 0 0], [0 0 0 1 0 0 1 0 0]]

2 is the starting point in the maze and 3 is the ending point of the maze.

import numpy as np

class Maze:
    @staticmethod
    def read_file(file):
        """ function that reads the file and returns the content of the file in an array """
        # dict for replacements
        replacements = {'*': 0, ' ': 1, 'A': 2, 'B': 3}
        # open and read file
        file = open(file, "r")
        lines = file.readlines()
        file.close()
        # row and col count
        rows = len(lines)
        cols = len(lines[0]) - 1
        # create array
        maze_array = np.zeros((rows, cols), dtype=int)
        # add lines to array
        for index, line in enumerate(lines):
            for i in range(0, len(line) - 1):
            # replace line content with the ones from the dictionary and add it to the array
            maze_array[index][i] = replacements.get(line[i], line[i])
        return maze_array

Now I want to go through the maze and get the ending point, starting at the starting point. For that I have written a method called search. In this method I check the cells of the maze. When a cell equals 3 I have found the end of the maze. Equals 0 is a wall and equals 1 is an empty cell where I can go through. After going through the cells I set them to 4 to mark it as visited. Then the recursive calls below.

     @staticmethod
    def search(x, y, array):
        """
           0: wall
           1: empty
           2: starting point
           3: ending point
           4: visited cell
        """
        if array[x][y] == 3:
            print('end at %d,%d' % (x, y))
            return True
        elif array[x][y] == 0:
            print('wall at %d,%d' % (x, y))
            return False
        elif array[x][y] == 4:
            print('visited at %d,%d' % (x, y))
            return False

        print('visiting %d,%d' % (x, y))

        array[x][y] == 4

        if ((x < len(array) - 1 and Maze.search(x + 1, y, array))
            or (y > 0 and Maze.search(x, y - 1, array))
            or (x > 0 and Maze.search(x - 1, y, array))
            or (y < len(array) - 1 and Maze.search(x, y + 1, array))):
        return True

    return False


def main():
    """ Launcher """
    # [1][1] is starting point
    array = Maze.read_file("maze-one.txt")
    Maze.search(1, 1, array)


if __name__ == "__main__":
    main()

It doesn't work. I have changed my code thanks to @Florian H, but I still get following error:

 RecursionError: maximum recursion depth exceeded while calling a Python object

But I need to go through the whole maze to get the ending point. Is this possible with recursive calls or is it too much? Is there any other solution than using recursive calls?


Solution

  • You reload your file in your recursive function with

    array = Maze.read_file('maze-one.txt')
    

    in every recursion step, thus array[x][y] == 4 will be overwritten by the reload every time. That means your maze is always unvisited and your recursion is infinite.

    edit to your comment

    I'm not saying that you should use a global variable, but that would be an option. In your case i would prefer a function parameter.

    First of all, you neither need a self parameter in a static method nor an object of a class with static elements only, but thats a different topic and to much to explain here. You might read about OOP yourself.

    You can give the maze as a function parameter like follows:

    def search(x, y, array):
        ...
    

    than you call it from your main method like:

    def main():
        """ Launcher """
        # [1][1] is starting point
        Maze.search(1, 1, Maze.load_file('maze-one.txt'))
    

    remove the load_file line from your search function and change the Maze.search function calls in your search method the same way.

     if ((x < len(array) - 1 and Maze.search(x + 1, y, array))...
    

    Second edit

    I'm not really getting the if part of your search function. But instinctively i would split that into single if's similar to the following:

    if x < len(array) -1:
        if Maze.search(x + 1, y, array):
            return True
    
    if y > 0:
        if Maze.search(x, y - 1, array):
            return True
    
    if x > 0:
        if Maze.search(x - 1, y, array):
            return True
    
    if y < len(array):
        Maze.search(x, y + 1, array):
            return True
    
    return False