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
Dave Masom
9,584 PointsMy attempt at the Dungeon Game
I tried my best to figure this out before watching Kenneth's solution, and ended up getting carried away in the process. Here are the additional features of my version:
- Variable map size
- Introduced a character who will guide you to himself. If you get to him, he gives you a map, but also wakes the dragon
- Dragon will move towards player once map initiated
My code is definitely a lot more convoluted than Kenneth's. Any feedback on what I could do to improve would be greatly appreciated! What a fun challenge.
import random
import os
import sys
# Clear screen function
def clear_screen():
if os.name == 'nt':
os.system('cls')
else:
os.system('clear')
# Name your character
def name():
char_name = input("What's your name?: ")
return char_name
# Help text
def help():
print("""
Your goal is to reach the door without being eaten by the dragon.
Navigate using "W" (up), "A" (left), "S" (down), "D" (right).
Type HELP to view this help again.
Enter QUIT to quit.
""")
# Draw a grid for the dungeon using Tuples as coordinates
def DUNGEON_MAP(map_size):
map_coordinates = []
y_index = 1
x_index = 1
while y_index < map_size+1:
while x_index < map_size+1:
coord = (y_index, x_index)
map_coordinates.append(coord)
x_index += 1
y_index += 1
x_index = 1
return map_coordinates
# Define locations of characters
def locations(map_coordinates, map_size):
coord_choices = map_coordinates
# Create a hero and place him on the map
hero_location = random.choice(coord_choices)
hero_y, hero_x = hero_location
# Remove hero location from options for dragon/door/bob
coord_choices.remove(hero_location)
# Create a dragon and place it on the map
dragon_location = random.choice(coord_choices)
# Remove dragon location from options for door/bob
coord_choices.remove(dragon_location)
# Create a door and place it on the map
door_location = random.choice(coord_choices)
# Remove door location from options for bob
coord_choices.remove(door_location)
# Create Bob and place him on the map
bob_location = random.choice(coord_choices)
# Return characters
return hero_location, dragon_location, door_location, bob_location
# Define movement functions for the character:
def move_hero(hero, move, map_size):
# If move is "A" (left), x -1
if move == "A": # left
hero_y, hero_x = hero['location']
if hero_x - 1 < 0:
print("You try to proceed, but a mysterious force pushes you back...")
else:
hero_x -= 1
hero['location'] = (hero_y, hero_x)
hero['x'] = hero_x
print(immersive())
# If move is "W" (up), y -1
elif move == "W": # up
hero_y, hero_x = hero['location']
if hero_y - 1 < 0:
print("You try to proceed, but a mysterious force pushes you back...")
else:
hero_y -= 1
hero['location'] = (hero_y, hero_x)
hero['y'] = hero_y
print(immersive())
# If move is "D" (right), x +1
elif move == "D": # right
hero_y, hero_x = hero['location']
if hero_x + 1 > map_size + 1:
print("You try to proceed, but a mysterious force pushes you back...")
else:
hero_x += 1
hero['location'] = (hero_y, hero_x)
hero['x'] = hero_x
print(immersive())
# If move is "S" (down), y +1
elif move == "S": # down
hero_y, hero_x = hero['location']
if hero_y + 1 > map_size + 1:
print("You try to proceed, but a mysterious force pushes you back...")
else:
hero_y += 1
hero['location'] = (hero_y, hero_x)
hero['y'] = hero_y
print(immersive())
return hero
# Draw the map
def draw_map(hero, dragon, door_location, map_coordinates, map_size):
# Prep tiles
tile = "|{}"
top_line_count = map_size
while top_line_count:
print(" _", end="")
top_line_count -= 1
print("")
# Define right wall
right_wall = []
for coord in map_coordinates:
x, y = coord
if y == map_size:
right_wall.append(coord)
# Loop through map cells
# print(map_coordinates) # Uncomment if you want to see the coords of the map
for cell in map_coordinates:
if cell not in right_wall:
if cell == hero['location']:
print(tile.format("X"), end="")
elif cell == dragon['location']:
print(tile.format("&"), end="")
elif cell == door_location:
print(tile.format("D"), end="")
else:
print(tile.format("_"), end="")
else:
if cell == hero['location']:
print(tile.format("X|"))
elif cell == dragon['location']:
print(tile.format("&|"))
elif cell == door_location:
print(tile.format("D|"))
else:
print(tile.format("_|"))
print("")
# Prevent character from moving off the map
def get_moves(hero, map_size):
moves = ["A (left)", "W (up)", "S (down)", "D (right)"]
# if player's y is 0, remove "W" (up)
if hero['y'] == 0:
moves.remove("W (up)")
# if player's y is map_size+1, remove "S" (down)
if hero['y'] == map_size + 1:
moves.remove("S (down)")
# if player's x is 0, remove "A" (left)
if hero['x'] == 0:
moves.remove("A (left)")
# if player's x is map_size+1, remove "D" (right)
if hero['x'] == map_size + 1:
moves.remove("D (right)")
return moves
# Immersive experience
def immersive():
return random.choice([
"\n",
"You stumble through the undergrowth, roots clawing at your ankles.\n",
"The forest closes in around you, dark and foreboding.\n",
"A jackal calls out into the night.\n",
"The wind rattles the tree branches above your head.\n"])
# Define Bob whisper
def bob_whisper(hero, bob, dragon):
if bob['whisper'] == True:
if bob['location'] == hero['location']:
bob_encounter(hero, bob, dragon)
elif hero['x'] > bob['x']:
print("A voice whispers on the breeze: 'go left...'")
elif hero['x'] < bob['x']:
print("A voice whispers on the breeze: 'go right...'")
elif hero['y'] > bob['y']:
print("A voice whispers on the breeze: 'head north...'")
elif hero['y'] < bob['y']:
print("A voice whispers on the breeze: 'head south...'")
# Define Bob encounter
def bob_encounter(hero, bob, dragon):
clear_screen()
print("""
You break into a clearing and find Bob, your inexplicably
magical friend who went missing a few months ago.
Bob stares at you strangely...
""")
input("""Get his attention:
> """)
clear_screen()
print("""
'Oh, {}! I almost didn't recognize you. So you got
stuck in these woods too, huh?'
Bob grins and produces a wand from his khaki shorts.
'Well, fear not! I can light your way...'
Bob waves his wand.
""".format(hero['name']))
bob['whisper'] = False
input("> ")
clear_screen()
# Generate map
print("""
'There you go. Just find your way to the village and
you'll be okay.'
A rumble seems to come from Bob's stomach.
'Uh oh...'
Bob looks uncomfortable. 'You might want to move
quickly. There's a dragon in these woods, and...'
Bob shifts from toe to toe, avoiding eye contact.
'Well, I might have accidentally just woken him up
with my magic. And accidentally locked his killing
senses onto your location. But don't worry! I'm sure
you won't come to harm...
You should probably leave my clearing now. See you around!'
""")
# Initiate dragon movement
dragon['active'] = True
return bob, dragon
# Define dragon movement
def dragon_move(dragon, hero):
direction = random.choice([1,2])
dragon_y, dragon_x = dragon['location']
if direction == 1 and dragon['x'] > hero['x']:
dragon['x'] = dragon_x -1
dragon['location'] = (dragon_y, dragon_x -1)
elif direction == 1 and dragon['x'] < hero['x']:
dragon['x'] = dragon_x +1
dragon['location'] = (dragon_y, dragon_x +1)
elif direction == 2 and dragon['y'] < hero['y']:
dragon['y'] = dragon_y +1
dragon['location'] = (dragon_y +1, dragon_x)
elif direction == 2 and dragon['y'] < hero['y']:
dragon['y'] = dragon_y -1
dragon['location'] = (dragon_y -1, dragon_x)
else:
print("The dragon roars, chilling your feeble, snappable, flame-grillable bones.")
print("")
# Game start
while True:
try:
map_size = int(input("How big do you want to go? (Enter a number from 5 to 10): "))
break
except ValueError:
print("Please enter a number.")
map_coordinates = DUNGEON_MAP(map_size)
# print(DUNGEON_MAP(map_size)) # Uncomment if you want to see the coords of the map
coord_choices = map_coordinates[:]
hero_location, dragon_location, door_location, bob_location = locations(coord_choices, map_size)
# The following lines can be uncommented for debugging purposes:
# print("Hero is at {}".format(hero_location))
# print("Dragon is at {}".format(dragon_location))
# print("Door is at {}".format(door_location))
# print("Bob is at {}".format(bob_location))
# Create dictionaries for characters
hero_y, hero_x = hero_location
hero = {'name': {}, 'x': hero_x,'y': hero_y, 'location': hero_location}
hero['name'] = name()
bob_y, bob_x = bob_location
bob = {'x': bob_x, 'y': bob_y, 'location': bob_location, 'whisper': True}
dragon_y, dragon_x = dragon_location
dragon = {'x': dragon_x, 'y': dragon_y, 'location': dragon_location, 'active': False}
# Clear screen and display intro help
clear_screen()
print("Nice to meet you, {}.".format(hero['name']))
help()
print("Press ENTER to begin.")
response = input("> ")
if response == "QUIT":
quit()
clear_screen()
print("Okay, let's go!")
print("""
You wake up in a dark forest.
""")
# Core game loop
while True:
# Define loss if character stumbles onto dragon
if hero['location'] == dragon['location']:
print("""You hear a loud noise, like a car being crushed in a junkyard.
A big shadow comes over your head...
You see a flash of teeth.
You got ate!
""")
break
# Define win if character finds door
elif hero['location'] == door_location:
print("""You stagger, gasping for breath, round a tree.
There's light in the distance...
You move closer.
You push past an overgrown bush, jump over a
fallen oak, and emerge onto a lush, moonlit field.
You escaped the forest!
""")
break
else:
# Define near miss
dragon_x, dragon_y = dragon['location']
if hero['location'] == (dragon_x + 1, dragon_y) or hero['location'] == (dragon_x - 1, dragon_y) or hero['location'] == (dragon_x, dragon_y + 1) or hero['location'] == (dragon_x, dragon_y -1):
print("""An unholy screech pierces the stillness, sending chills down your spine.
Is that fire you see in the distance?
""")
# Get hero's new location
if dragon['active'] == True:
draw_map(hero, dragon, door_location, map_coordinates, map_size)
else:
print("You are at {}.".format(hero['location']))
print("You can move {}.".format(get_moves(hero, map_size)))
print("")
bob_whisper(hero, bob, dragon)
# Tee up next move
moves = ["A", "W", "S", "D"]
move = input("> ")
move = move.upper()
clear_screen()
if move == "QUIT":
break
elif move == "HELP":
help()
else:
if move in moves:
move_hero(hero, move, map_size)
# Move dragon
if dragon['active'] == True:
dragon_move(dragon, hero)
else:
print("You spin around in place, going a little crazy. Get it together, {}!".format(hero['name']))
print("")
Dave Masom
9,584 PointsThanks Jeff! Very kind of you to say. I will check out PyGame.
Ronit Mankad
12,166 PointsReally good game!!. Your code is very organised and easy to understand. I will try my own version with yours as a reference. Thanks very much!
2 Answers
FHATUWANI Dondry MUVHANGO
17,796 PointsI'm also very impressed
Dave Masom
9,584 PointsThank you!
Alexander Davison
65,469 PointsImpressive! It's a very interesting and fun short little game :)
Jeff Muday
Treehouse Moderator 28,732 PointsJeff Muday
Treehouse Moderator 28,732 PointsThis is very cool. The additional features are impressive. I wouldn't call your code "convoluted" at all, you included lots of thoughtful comments so anyone who wants to fork your code would know where to make modifications.
You may want to try your hand at refactoring your code to add a graphical user interface like PyGame!
http://www.pygame.org/