Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Can someone explain why "cells_creator" is not defined? (Expansion of dungeon_game.py)

I'm trying to expand the dungeon_game.py file that we created with Kenneth at the end of Python Collections. Independently, my functions work but I'm having trouble when I try to assign them to the variable "CELLS". Here is my code:

CELLS = cells_creator(difficulty)


def cells_creator(difficulty):
    range_list = []
    for i in range(difficulty):
        range_list.append(i)
    index_tracker = 0
    cells = []
    complete = False
    while not complete:
        for item in range_list:
            cells.append(tuple((item, range_list[index_tracker])))
        index_tracker += 1
        if index_tracker > range_list[-1]:
            complete = True
    return cells

def difficulty_selector():
    difficulty = input("What difficulty would you prefer? EASY, MEDIUM, HARD ").upper()
    if difficulty == "EASY":
        difficulty = 5
    if difficulty == "MEDIUM" or "HARD":
        difficulty = 10
    else:
        input("Sorry, that was not a valid entry: press ENTER to try again!")
    return difficulty

My error is: Traceback (most recent call last): File "C:\Users\Alex\AppData\Local\Programs\Python\Python37-32\PythonFiles\dungeon_game_copy.py", line 4, in <module> CELLS = cells_creator(difficulty) NameError: name 'cells_creator' is not defined

I'm assuming it has something to do with how I have my functions ordered but I don't know why. If someone could explain it to me that would be great!

1 Answer

Dave StSomeWhere
Dave StSomeWhere
19,870 Points

You can't assign cells_creator(difficulty) to a variable until after the function is defined.

Also you can use difficulty as an argument until after it is assigned a value.

Try adding an assignment to difficulty and the call to cells_creator() at the bottom after the function definitions.

So, I moved everything around but now I get:

NameError: name 'difficulty' is not defined. I don't understand why because I defined difficulty within difficulty_selector. This time, I've added my entire code just in case it's something further down the line that's tripping things up. Apologies if that is too much.

import random # need this so we can get our starting points for player, monster and door
import os # still not familiar with this.  We will use a method from this module to clear the screen

def difficulty_selector():
    selection = input("What difficulty would you prefer? EASY, MEDIUM, HARD ").upper()
    if selection == "EASY":
        difficulty = 5
    if selection == "MEDIUM" or "HARD":
        difficulty = 10
    else:
        input("Sorry, that was not a valid entry: press ENTER to try again!")
    return difficulty


def cells_creator(difficulty):
    range_list = []
    for i in range(difficulty):
        range_list.append(i)
    index_tracker = 0
    map_layout = []
    complete = False
    while not complete:
        for item in range_list:
            map_layout.append(tuple((item, range_list[index_tracker])))
        index_tracker += 1
        if index_tracker > range_list[-1]:
            complete = True
    return map_layout


CELLS = cells_creator(difficulty)


def clear_screen():
    os.system('cls' if os.name == 'nt' else 'clear') # not very familiar with this but it will clear the screen.  Assuming this is one of those things that I'll learn as I get more experience


def get_locations():
    return random.sample(CELLS, 3) # takes 3 random samples, further in the code we unpack each sample and assign it to a variable


def move_player(player, move): # unpacks the tuple identifying the player's location and modifys the position based on the move
    x, y = player
    if move == "LEFT":
        x -= 1
    if move == "RIGHT":
        x += 1
    if move == "UP":
        y -= 1
    if move == "DOWN":
        y += 1
    return x, y


def monster_move(monster):
    x, y = monster
    available_monster_moves = []
    if monster[0] < 4:
        available_monster_moves.append(tuple((x + 1, y)))
    if monster[0] > 0:
        available_monster_moves.append(tuple((x - 1, y)))
    if monster[1] < 4:
        available_monster_moves.append(tuple((x, y + 1)))
    if monster[1] > 0:
        available_monster_moves.append(tuple((x, y - 1)))
    monster = random.choice(available_monster_moves)
    return monster


def start_screen():
    while True:
        print("Welcome to the dungeon!")
        decision = input("""Please enter START to start
Please enter HELP to see help """ ).upper()
        clear_screen()
        if decision == "START":
            break
        if decision == "HELP":
            input("""You must find the hidden door to exit the dungeon and win.
Don't let the hidden monster find you or you will lose.
You can only move: UP, DOWN, LEFT or RIGHT.
Press enter to go back to menu screen. """)
        clear_screen()



def get_moves(player): # lets the player know what direction they are allowed to move
    moves = ["LEFT", "RIGHT", "UP", "DOWN"]
    x, y = player
    if x == 0:
        moves.remove("LEFT")
    if x == 4:
        moves.remove("RIGHT")
    if y == 0:
        moves.remove("UP")
    if y == 4:
        moves.remove("DOWN")
    return moves


def draw_map(player, monster): # this function draws the map
    print(" _"*difficulty) # makes the top wall
    tile = "|{}"

    for cell in CELLS:
        x, y = cell
        if x < difficulty[-1]:
            line_end = ""
            if cell == player:
                output = tile.format("X")
            elif cell == monster:
                output = tile.format("M")
            else:
                output = tile.format("_")
        else:
            line_end = "\n"
            if cell == player:
                output = tile.format("X|")
            else:
                output = tile.format("_|")
        print(output, end=line_end)


def game_loop():
    player, monster, door = get_locations() # here is where we unpack the tuples of locations and assign them to our main three variables
    playing = True


    while playing:
        clear_screen()
        draw_map(player)
        valid_moves = get_moves(player)

        print("You're currently in room {}".format(player))  # gives the player their location on the map
        print("You can move {}".format(", ".join(valid_moves)))  # we use valid moves to show the player which direction they can move
        print("Enter QUIT to quit") # and a simple line that tells the player how to quit

        move = input("> ") # prompts the player to input a direction they want to move
        move = move.upper() # we want the players input to be ALL CAPS so it will match up with our code

        if move == 'QUIT': # simple if statement to make us break the loop if the player wants to quit
            print("\n ** See you next time **\n")
            break
        if move in valid_moves:
            player = move_player(player, move)

            monster_move(monster)

            if player == monster:
                print("\n ** Oh no! The monster got you! Better luck next time! **\n")
                playing = False
            if player == door:
                print("\n ** You escaped! Congratulations! **\n")
                playing = False

        else:
            input("\n ** Walls are hard!  Don't run into them! **\n")
    else:
        if input("Play again? [Y/N] ").lower() != "n":
            game_loop()
        else:
            input("Thanks for playing! Press enter to quit.")


clear_screen()
start_screen()
clear_screen()
difficulty_selector()
clear_screen()
game_loop()
Dave StSomeWhere
Dave StSomeWhere
19,870 Points

difficulty is only defined within the difficulty_selector() function scope and you are attempting to use it in the global scope. So you should probably investigate variable scoping.

Try this - added some comments - this should get you rolling - seems to work - didn't really do complete testing

import random # need this so we can get our starting points for player, monster and door
import os # still not familiar with this.  We will use a method from this module to clear the screen

def difficulty_selector():
    selection = input("What difficulty would you prefer? EASY, MEDIUM, HARD ").upper()
    if selection == "EASY":
        difficulty = 5
    if selection == "MEDIUM" or "HARD":
        difficulty = 10
    else:
        input("Sorry, that was not a valid entry: press ENTER to try again!")
    return difficulty


def cells_creator(difficulty):
    range_list = []
    for i in range(difficulty):
        range_list.append(i)
    index_tracker = 0
    map_layout = []
    complete = False
    while not complete:
        for item in range_list:
            map_layout.append(tuple((item, range_list[index_tracker])))
        index_tracker += 1
        if index_tracker > range_list[-1]:
            complete = True
    return map_layout

# Doesn't make sense to do this here moved below to execution area
# CELLS = cells_creator(difficulty)


def clear_screen():
    # I commented out the clear screen because I use eclipse and don't have TERM setup for development purposes- 
    print('clear screen called')
#     os.system('cls' if os.name == 'nt' else 'clear') # not very familiar with this but it will clear the screen.  Assuming this is one of those things that I'll learn as I get more experience


def get_locations():
    return random.sample(CELLS, 3) # takes 3 random samples, further in the code we unpack each sample and assign it to a variable


def move_player(player, move): # unpacks the tuple identifying the player's location and modifys the position based on the move
    x, y = player
    if move == "LEFT":
        x -= 1
    if move == "RIGHT":
        x += 1
    if move == "UP":
        y -= 1
    if move == "DOWN":
        y += 1
    return x, y


def monster_move(monster):
    x, y = monster
    available_monster_moves = []
    if monster[0] < 4:
        available_monster_moves.append(tuple((x + 1, y)))
    if monster[0] > 0:
        available_monster_moves.append(tuple((x - 1, y)))
    if monster[1] < 4:
        available_monster_moves.append(tuple((x, y + 1)))
    if monster[1] > 0:
        available_monster_moves.append(tuple((x, y - 1)))
    monster = random.choice(available_monster_moves)
    return monster


def start_screen():
    while True:
        print("Welcome to the dungeon!")
        decision = input("""Please enter START to start
Please enter HELP to see help """ ).upper()
        clear_screen()
        if decision == "START":
            break
        if decision == "HELP":
            input("""You must find the hidden door to exit the dungeon and win.
Don't let the hidden monster find you or you will lose.
You can only move: UP, DOWN, LEFT or RIGHT.
Press enter to go back to menu screen. """)
        clear_screen()



def get_moves(player): # lets the player know what direction they are allowed to move
    moves = ["LEFT", "RIGHT", "UP", "DOWN"]
    x, y = player
    if x == 0:
        moves.remove("LEFT")
    if x == 4:
        moves.remove("RIGHT")
    if y == 0:
        moves.remove("UP")
    if y == 4:
        moves.remove("DOWN")
    return moves


def draw_map(player, monster): # this function draws the map
    print(" _"*difficulty) # makes the top wall
    tile = "|{}"

    for cell in CELLS:
        x, y = cell
        # the brackets around -1 needed to be removed
        if x < difficulty -1:
            line_end = ""
            if cell == player:
                output = tile.format("X")
            elif cell == monster:
                output = tile.format("M")
            else:
                output = tile.format("_")
        else:
            line_end = "\n"
            if cell == player:
                output = tile.format("X|")
            else:
                output = tile.format("_|")
        print(output, end=line_end)


def game_loop():
    player, monster, door = get_locations() # here is where we unpack the tuples of locations and assign them to our main three variables
    playing = True


    while playing:
        clear_screen()
        draw_map(player, monster)
        valid_moves = get_moves(player)

        print("You're currently in room {}".format(player))  # gives the player their location on the map
        print("You can move {}".format(", ".join(valid_moves)))  # we use valid moves to show the player which direction they can move
        print("Enter QUIT to quit") # and a simple line that tells the player how to quit

        move = input("> ") # prompts the player to input a direction they want to move
        move = move.upper() # we want the players input to be ALL CAPS so it will match up with our code

        if move == 'QUIT': # simple if statement to make us break the loop if the player wants to quit
            print("\n ** See you next time **\n")
            break
        if move in valid_moves:
            player = move_player(player, move)

            monster_move(monster)

            if player == monster:
                print("\n ** Oh no! The monster got you! Better luck next time! **\n")
                playing = False
            if player == door:
                print("\n ** You escaped! Congratulations! **\n")
                playing = False

        else:
            input("\n ** Walls are hard!  Don't run into them! **\n")
    else:
        if input("Play again? [Y/N] ").lower() != "n":
            game_loop()
        else:
            input("Thanks for playing! Press enter to quit.")


clear_screen()
start_screen()
clear_screen()
# set difficulty in the global scope here
difficulty = difficulty_selector()
CELLS = cells_creator(difficulty)
clear_screen()
game_loop()

Thank you so much for your help. I've yet to explore local and global variables and will hopefully get there soon. It makes more sense to me now!