1

I have to make a maze with three different levels that allows you to quit at any time. I've tried inserting my quit() call everywhere but I can't seem to get it to work. Can someone tell me what I'm doing wrong? Is it something easy I can fix or is my logic just way off? Thanks! :(

def start():
    print('Welcome to the Maze!')
    choose_level()

def choose_level():
    level = input('Select a level: Easy, Average, or Difficult \n')
    if level == 'Easy' or 'easy' or 'EASY' or '1':
        return easy()
    elif level == 'Average' or 'average' or 'AVERAGE' or '2':
        return average()
    elif level == 'Difficult' or 'difficult' or 'DIFFICULT' or '3':
        return difficult()


def easy():

    maze1_list = []
    # [Description, North, East, South, West]
    maze1_list.append(['Available Directions: East', None, 1, None, None]) #0
    maze1_list.append(['Available Directions: East, South, West', None, 2, 3, 0]) #1
    maze1_list.append(['Available Directions: West', None, None, None, 1]) #2
    maze1_list.append(['Available Directions: North, East', 1, 4, None, None]) #3
    maze1_list.append(['Available Directions: South, West', None, None, 5, 3]) #4

    current_tile = 0
    done = False

    directions = {'North' or 'north' or 'NORTH':1, 'East' or 'east' or 'EAST':2, 'South' or 'south' or 'SOUTH':3, 'West' or 'west' or 'WEST':4}
    #Source: obtained from <https://stackoverflow.com/questions/46511833/how-do-you-make-a-simple-3x3-maze-on-python-using-lists/46517061#46517061>
    #Date: <October 2, 2017>
    #Name of Author/Programmer: <Anton vBR>

    while not done:
        print('')
        print(maze1_list[current_tile][0])
        x = '0'
        available = False

        while not available:

            while not directions.get(x.title()): #Source: obtained from <http://programarcadegames.com/index.php?chapter=lab_adventure>
                                             #Date: <October 2, 2017>
                                             #Name of Author/Programmer: <Paul Vincent Craven>
                if x!='0':
                    print('Please choose an available direction. ')
                x = input('Which direction will you take? \n')

            next_move = directions.get(x.title()) #Source: obtained from <http://programarcadegames.com/index.php?chapter=lab_adventure>
                                              #Date: <October 2, 2017>
                                              #Name of Author/Programmer: <Paul Vincent Craven>
            next_tile = maze1_list[current_tile][next_move]

            if next_tile:
                available = True
                current_tile = next_tile

            elif x == 'quit':
                quit()

            else:
                print('Please choose an availble direction.')
                x = '0'

        if current_tile == 5:
            print('Congratulations! You found the exit. \nGoodbye.')
            done = True

# i'm going to cut off the average and difficult levels of my code here 
since they're the same concept as the easy level
SherylHohman
  • 16,580
  • 17
  • 88
  • 94
user8638151
  • 21
  • 1
  • 7
  • This may be useful: https://stackoverflow.com/questions/19747371/python-exit-commands-why-so-many-and-when-should-each-be-used – SherylHohman Oct 03 '17 at 17:26
  • Possible duplicate of [How do I test one variable against multiple values?](https://stackoverflow.com/questions/15112125/how-do-i-test-one-variable-against-multiple-values) – jasonharper Oct 03 '17 at 20:48
  • While the testing of one variable against multiple values Certainly was implemented incorrectly, (as was the dictionary definition for `directions`), Neither of those caused the OP's underlying issue and main problem of an endless loop, that could not be exited. – SherylHohman Oct 04 '17 at 04:33

1 Answers1

0
def start():
    print('Welcome to the Maze!')
    maze_list = choose_level()
    run_maze(maze_list)

def choose_level():
    level = input('Select a level: Easy, Average, or Difficult \n')

    # one way of checking a variable against multiple values
    if level == 'Easy' or level == 'easy' or level == 'EASY' or level =='1':
        maze_list = easy()
    # another way of checking a variable against multiple values
    elif level in ('Average', 'average', 'AVERAGE', '2'):
        maze_list = average()
    elif level in ('Difficult', 'difficult', 'DIFFICULT', '3'):
        maze_list = difficult()
    return maze_list

def average():
    maze_list = []
    return maze_list
def difficult():
    maze_list = []
    return maze_list

def easy():
    maze1_list = []
    #                  [Description,                               North, East, South, West]
    maze1_list.append(['Available Directions: East',              None,  1,    None,  None]) #0
    maze1_list.append(['Available Directions: East, South, West', None,  2,    3,     0   ]) #1
    maze1_list.append(['Available Directions: West',              None,  None, None,  1   ]) #2
    maze1_list.append(['Available Directions: North, East',       1,     4,    None,  None]) #3
    maze1_list.append(['Available Directions: South, West',       None,  None, 5,     3   ]) #4
    # solution: East, South, East, South

    return maze1_list

def run_maze(maze_list):

    '''
    # Improper use of dictionary key-value pair definitions
    directions = {'N' or 'n' or 'North' or 'north' or 'NORTH':1, 
                  'E' or 'e' or 'East'  or 'east'  or 'EAST ':2, 
                  'S' or 's' or 'South' or 'south' or 'SOUTH':3, 
                  'W' or 'w' or 'West'  or 'west'  or 'WEST' :4
                 }
    '''
    # proper dictionary definitions. each option must be it's own key value pair.
    # since we're using x.title(), we only need title-case variations
    directions = {'N'    : 1,
                  'North': 1, 
                  'E'    : 2,
                  'East' : 2, 
                  'S'    : 2, 
                  'South': 3, 
                  'W'    : 4,
                  'West' : 4
                 }


    # done when "solved the maze" ("quit" exits the program directly)
    done = False
    # current location in maze_list
    current_tile = 0

    while not done:
        if maze_list == []:
          print("No maze defined.. exiting.")
          return

        # "I have an available direction from the user."
        # available signifies that the user has entered a valid directions
        # more importantly, that we do not need to ask for a new value right now.
        # I'd probably rename this, and then use it slightly differently

        # reset this to False on each pass through this loop
        available = False

        # you had an extra outter loop here

        # loop below could be extracted as a function for requesting valid user input
        while not available:

            # input from user (menu: (directions)"N", "S", "E", "W", or "Quit")
            x = '0'  # not necessary to initialize

            # Let the user know what directions are "available"
            print( "  ", maze_list[current_tile][0])#, '(maze_list[current_tile][0])\n')

            # accepts the user's: direction, "quit" request, (or garbage)
            x = input('Which direction will you take?\n')

            if x.title() == 'Quit':
                #done = True
                #available = True
                print("Quitting..")
                quit()
                # if "quit()" isn't available in this environment..
                print("tried to quit.. returning now instead..")
                # see here if "quit() does not work":
                # https://stackoverflow.com/questions/19747371/python-exit-commands-why-so-many-and-when-should-each-be-used
                return


            # translate requested direction to a numbered direction
            # if user did not enter a direction, use get()'s default parameter
            # to set the requested_direction to "None"
            requested_direction = directions.get(x.title(), None)

            # uses short-circuit evaluation, to first check if requested_direction is "None"
            # only then will it check to see if it was an "available" direction
            if (requested_direction != None) and (maze_list[current_tile][requested_direction] != None):
                # (we can stop asking the user for a direction)
                available = True

            # else: run this loop again, asking for user directions.
            #   (the user either entered an unavailable direction, or complete nonsense.)
            #   we don't need to do anything here, as available==False, and re-enters the while loop


        next_move = directions.get(x.title())
        next_tile = maze_list[current_tile][next_move]
        current_tile = next_tile

        # no longer needed.
        # if next_tile:
        #     available = True
        #     current_tile = next_tile

        if current_tile == 5:
            print('     Congratulations! You found the exit. \nGoodbye.')
            done = True

start()

solution on repl.it

Bugs were as follows:

Some design ideas to ponder:

  • consolidate the loop asking for directions - it was in two different places, which was confusing.
  • DRY - consolidate logic of accepting user input to a single function that can be reused (called from within) easy(), average(), and difficult(). In turn, those function can be used simply to load the details of the maze itself.
  • the loop looking for valid user input could also be extracted into a separate function for simplification.

Finally, if quit() still doesn't work, see this link

SherylHohman
  • 16,580
  • 17
  • 88
  • 94