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 trialThomas Rose
Python Web Development Techdegree Student 393 PointsHigh score programming in python across programs: why do one of these work but the other doesn't?
I'm making a high score feature for the dungeon game in unit two of the python techdegree, and I'm not quite sure what is going wrong. Here's my code for it:
import random
import os
CELLS = [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0),
(0, 1), (1, 1), (2, 1), (3, 1), (4, 1),
(0, 2), (1, 2), (2, 2), (3, 2), (4, 2),
(0, 3), (1, 3), (2, 3), (3, 3), (4, 3),
(0, 4), (1, 4), (2, 4), (3, 4), (4, 4),]
def clear_screen():
os.system("cls" if os.name == "nt" else "clear")
def get_locations():
return random.sample(CELLS, 3)
def move_player(player, 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 get_moves(player):
moves = ["LEFT", "RIGHT", "UP", "DOWN"]
x, y = player
if y == 0:
moves.remove("UP")
if y == 4:
moves.remove("DOWN")
if x == 0:
moves.remove("LEFT")
if x == 4:
moves.remove("RIGHT")
return moves
def draw_map(player, door, monster):
print(" _" * 5)
tile = "|{}"
for cell in CELLS:
x, y = cell
if x < 4:
line_end = ""
if cell == player:
output = tile.format("X")
elif cell == door:
output = tile.format("O")
elif cell == monster:
output = tile.format("M")
else:
output = tile.format("_")
else:
line_end = "\n"
if cell == player:
output = tile.format("X|")
elif cell == door:
output = tile.format("O|")
elif cell == monster:
output = tile.format("M|")
else:
output = tile.format("_|")
print(output, end = line_end)
def game_loop():
player, door, monster = get_locations()
playing = True
move_count = 0
print("The high score is currently held by {} with a score of {}!".format(first_place[0], high_score[0]))
clear_screen()
while playing:
clear_screen()
high_score.sort()
draw_map(player, door, monster)
valid_moves = get_moves(player)
print("You're currently in room {}".format(player))
print("You can move {}".format(", ".join(valid_moves)))
print("Enter 'QUIT' to quit")
move = input("> ")
move = move.upper()
clear_screen()
if move == 'QUIT':
print("\n** See you next time! **\n")
break
if move in valid_moves:
move_count += 1
player = move_player(player, move)
clear_screen()
draw_map(player, door, monster)
if player == monster:
print("\n ** Oh no! The monster fot you! Better luck next time **\n")
playing = False
if player == door:
new_high = move_count
high_score.sort()
print("\n** You escaped in {} moves! Congratulations! **\n".format(new_high))
if new_high < high_score[0]:
high_score.insert(0, new_high)
print("\n** You have the new high score!!! **\n")
first_place = input("What is your name? \n > ")
else:
print("The high score is still held by {} with a score of {}!".format(first_place[0], high_score[0]))
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()
if __name__ == '__main__':
clear_screen()
print("Welcome to the dungeon!")
input("Press return to start!")
clear_screen
high_score = [15]
first_place = ["Niel Armstrong"]
game_loop()
I am getting an error for not having the first_place variable assigned before it's being read, but I used, as far as I can tell, this exact method to finally get the number guessing game highscore to work, code below:
import random
import os
def clear_screen():
os.system("cls" if os.name == "nt" else "clear")
def start_game():
low = 1
high = 10
secret_number = random.randint(low, high)
#This is a Test Line
#print("The number is {}".format(secret_number))
print("""
================================================
Welcome to the Number Guessing Extravaganza!!!!
================================================
""")
print("""
The rules are simple; choose a number between 1
and 10, and we will tell you if the secret
number is higher or lower than that. Try and
guess the secret number in as few guesses as
possible!
""")
print("The current high score is {}, held by {}. Try and beat it!".format(high_score[0], first_place[0]))
attempts = 0
while True:
try:
guess = int(input("What is your guess? "))
except ValueError:
print("Please enter a whole number!")
continue
if guess == secret_number:
attempts += 1
print("You got it!")
print("You guessed the secret number in {} try(s)!".format(attempts))
high_score.sort()
if high_score[0] > attempts:
first_place[0] = input("What is your name? ")
high_score.insert(0, attempts)
print("You have the new high score!")
else:
print("The high score is currently {}, held by {}".format(high_score[0], first_place[0]))
print("Thanks for playing!")
replay = input("""Would you like to play again? [y]es or [n]o? """)
if replay == "n":
print("Thanks for playing!")
break
if replay == "y":
clear_screen()
start_game()
if 1 <= guess < secret_number:
attempts += 1
print("Too low!")
continue
if 11 >= guess > secret_number:
attempts += 1
print("Too high!")
continue
if guess > 10:
print("The number must be between 1 and 10.")
continue
if guess < 1:
print ("The number must be between 1 and 10.")
continue
if __name__ == '__main__':
high_score = [7]
first_place = ["Jim-Bob"]
start_game()
I'm lost! Any help would be appreciated
Steven Parker
231,275 PointsIt looks like apostrophes (''') in the code instead of accents (```). And they have to be on lines by themselves, except the starting one can have the word "python" after it to give you syntax coloring.
4 Answers
Jeff Muday
Treehouse Moderator 28,722 PointsYou can assign your globals "high_score" and "first_place" right after your import statements.
import random
import os
# declaring/assigning variables in the global scope.
high_score = [7]
first_place = ["Jim-Bob"]
Then... in start_game() or any other function you choose can access these variables successfully as globals.
def start_game():
# this will give access to the global variables
global high_score
global first_place
low = 1
high = 10
secret_number = random.randint(low, high)
Here is some decent documentation on "global"
https://www.programiz.com/python-programming/global-keyword
Another cool trick from the magic of Treehouse is the workspace snapshot (that you can share). With the snapshot URL we can look at your code and supporting files rather than having to cut-and-paste it all in. The snapshot button is in the upper-right-hand corner of the workspace.
Later on, when you are doing some really complex stuff, you will have lots of files in a directory structure and you can share all these in the forum with a few clicks.
best, Jeff
Thomas Rose
Python Web Development Techdegree Student 393 PointsThank you so much, I didn't know that about variables and functions! Clears up a lot.
Thomas Rose
Python Web Development Techdegree Student 393 PointsHey thank you!! Okay got it all formatted
KRIS NIKOLAISEN
54,972 PointsThe difference between the two is in the dungeon game you have this:
first_place = input("What is your name? \n > ")
whereas in the number guessing game you have:
first_place[0] = input("What is your name? ")
If you change the variable to first_place[0] in the dungeon game it also runs without the error and without declaring the variables as global in the function. My question for Jeff or Steven is why?
I have a snapshot with the above code
a.py = number guessing game
b.py = dungeon game (I added some code to delay the clear_screen around where the error occurs )
c.py = shorter code that demonstrates the same error and seems to contradict a and b
Jeff Muday
Treehouse Moderator 28,722 PointsKris, your "c.py" is a great reductionist view of the issue!
The Python scoper does a "scope check" on any variable that is accessed or assigned within a new scope.
In f(), 'x' is accessed only... so Python looks into its parent's scope and finds 'x' (no errors)
In g(), 'x' is assigned, so it assumes it must be a LOCAL x, and doesn't find it. (throws an error) The telling thing here is that it won't even print(x) because the Python scoper already scanned ahead to find an assignment!
If you include the 'global x' command, it overrides the local scope and tells the Python scoper to use the 'x' in the parent scope.
x = 1
def f():
print(x)
def g():
print(x)
x = 2
f() #prints 1
g() #throws an error
Thomas Rose
Python Web Development Techdegree Student 393 PointsThomas Rose
Python Web Development Techdegree Student 393 PointsI'm so sorry, I have no idea what happened in formatting, tried putting the ``` on either end.