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 trialDavid McCarty
5,214 PointsUpdated version of the Dungeon Game!
Earlier this week, or last week, or something, I posted my updated version of the dungeon game in which my version had the monster actually following the player. Previous Version
I was given a few good suggestions from John Hill and Brandon Wall on how to improve the code.
John Hill Gave ma many great ideas that I've now implemented into the game!
The problem is that, in order to implement some of the features I needed to create classes for the monsters and player, so this steps outside of the Dungeon Game area, but I thought you guys might like it anyways.
Here they are! Let me know if you have any suggestions on how to improve the code!
dungeon_game.py
import random
from dungeon_monster import Monster
from dungeon_player import Player
# Different selectable map sizes. - DONE!
# Play again option - DONE!
# Fix ability to go off the grid - DONE!
# Stop map from displaying twice after each move - DONE!
# Option to add more monsters (Will probably need a monster class for this) - DONE!
# Battle the monster
# Create more efficient way to populate grid
def create_moves(player, size):
row, col = player.location
plyr = player
removeable = (-1, -1)
up = (row - 1, col)
down = (row + 1, col)
left = (row, col - 1)
right = (row, col + 1)
move_list = [up, down, left, right]
if down[0] > size-1:
move_list[1] = removeable
if right[1] > size-1:
move_list[3] = removeable
if up[0] < 0:
move_list[0] = removeable
if left[1] < 0:
move_list[2] = removeable
try:
user_choice = 0
choice_list = ["1 = Up {}".format(up), "2 = Down {}".format(down), "3 = Left {}".format(left),
"4 = Right {}".format(right)]
for index, moves in enumerate(move_list):
if move_list[index] == removeable:
choice_list[index] = ""
updated_list = list()
for items in choice_list:
if items == "":
print("")
#do nothing
else:
updated_list.append(items)
print(*choice_list, sep='\n')
while True:
user_choice = input("\nChoice: ")
user_choice = int(user_choice)
if choice_list[user_choice-1] == "":
print("Invalid Choice. That would take you outside of the map!")
continue
else:
break
if user_choice > 4 or user_choice < 1:
raise ValueError
if user_choice == 1:
return up
elif user_choice == 2:
return down
elif user_choice == 3:
return left
elif user_choice == 4:
return right
except:
print("Choice must be a number and it must be between 1 and 4")
def create_monster_moves(mon_list, size, index):
removeable = (-1, -1)
m_move_list = list()
while True:
m_up = ((mon_list[index].location[0] - 1), mon_list[index].location[1])
m_down = ((mon_list[index].location[0] + 1), mon_list[index].location[1])
m_left = (mon_list[index].location[0], (mon_list[index].location[1] - 1))
m_right = (mon_list[index].location[0], (mon_list[index].location[1] + 1))
mon_list[index].set_moves(m_up, m_down, m_left, m_right)
m_move_list = mon_list[index].get_moves()
if m_move_list[1][0] > size-1:
m_move_list[1] = removeable
if m_move_list[3][1] > size-1:
m_move_list[3] = removeable
if m_move_list[0][0] < 0:
m_move_list[0] = removeable
if m_move_list[2][1] < 0:
m_move_list[2] = removeable
break
return m_move_list
def move_monster(mon_list, size, index, plyr):
removeable = (-1, -1)
m_move_list = create_monster_moves(mon_list, size, index)
best_move_num = 100.0
best_move_tup = (0,0)
while True:
for monster_moves in m_move_list:
if(monster_moves == removeable):
continue
else:
move = ((plyr.get_location()[0] - monster_moves[0])**(2) + (plyr.get_location()[1] -
monster_moves[1])**(2))**(.5)
if move < best_move_num:
best_move_num = move
best_move_tup = monster_moves
break
return best_move_tup
def monster_check(num, list, cell):
x = 0
equal = False
while x < num:
if list[x].location == cell:
equal = True
x += 1
return equal
def draw_map(plyr, mon_list, door, size, grid):
i = 0
mon_idx = 0
to_add = size
while i < size:
print(" _", end='')
i += 1
print("")
tile = "|{}"
index_list = list()
for i, items in enumerate(grid):
if i == size-1:
size += to_add
continue
index_list.append(i)
for idx, cell in enumerate(CELLS):
mon_num = len(mon_list)
if idx in index_list:
if cell == plyr.location:
print(tile.format('X'), end='')
elif monster_check(mon_num, mon_list, cell):
print(tile.format('M'), end='')
elif cell == door:
print(tile.format('D'), end='')
else:
print(tile.format('_'), end='')
else:
if cell == plyr.location:
print(tile.format("X|"))
elif monster_check(mon_num, mon_list, cell):
print(tile.format("M|"))
elif cell == door:
print(tile.format("D|"))
else:
print(tile.format("_|"))
def create_grid():
grid_size = 0
cells = list()
cont = True
while cont:
try:
grid_size = int(input("Pick grid size: "))
if grid_size >= 30:
choice = input("Woah! You're trying to make a big list! Seriously, this could mess some stuff up."
" Continue Y/N?: ").upper()
if choice == 'Y':
print("You asked for it....")
cont = False
else:
print("let's try this again...")
else:
cont = False
except:
print("Grid size must be a number")
a = 0
while a < grid_size:
b = 0
while b < grid_size:
cells.append((a, b))
b += 1
a += 1
return cells, grid_size
def was_eaten(player, mon_list):
for idx, mon in enumerate(mon_list):
if player.get_location() == mon.location:
return True
return False
def on_top(player, door, mon_list):
for idx, mon in enumerate(mon_list):
if mon.location == player.location or mon.location == door or door == player.location:
return False
else:
continue
return True
CELLS, grid_size = create_grid()
player = 0,0
door = 0
user_choice = 0
mon_num = 0
monster_list = list()
# Sets each object a cell. If anyone has the same cell, it starts over
while True:
again = True
try:
mon_num = input("How many monsters do you want?: ")
mon_num = int(mon_num)
except:
print("Monster amount needs to be a number.")
while again == True:
monster_list = list()
x = 0
while x < mon_num:
monster_list.append(Monster())
x += 1
player = Player()
player.set_location(CELLS)
door = random.choice(CELLS)
for i, mon in enumerate(monster_list):
monster_list[i].set_location(CELLS)
for idx, mon in enumerate(monster_list):
if on_top(player, door, monster_list):
again = True
else:
again = False
#If it's else, none of them were equal
break # Breaks out of the whole location testing loop
while True:
print("\nYou are in cell {}".format(player.get_location()))
draw_map(player, monster_list, door, grid_size, CELLS)
player.location = create_moves(player, grid_size)
if player.get_location() == door:
print("You win! You made it to the door!")
break
elif was_eaten(player, monster_list):
print("You got eaten by the monster :( Game over")
break
for index, mon in enumerate(monster_list):
monster_list[index].location = move_monster(monster_list, grid_size, index, player)
if was_eaten(player, monster_list):
print("You got eaten by the monster :( Game over")
break
play_again = input("Play Again? Y/N: ").upper()
if play_again == 'Y':
continue
else:
print("Goodbye :'(")
break
dungeon_monster.py
import random
from dungeon_combat import Combat
monster_weapons = ['Stick', 'Rock', 'Club', 'Razor']
class Monster(Combat):
location = (0, 0)
min_health = 1
max_health = 3
weapon = 'Stick'
up = (0, 0)
down = (0, 0)
left = (0, 0)
right = (0, 0)
def __init__(self, **kwargs):
self.weapon = random.choice(monster_weapons)
self.health = random.randint(self.min_health, self.max_health)
for key, value in kwargs.items():
setattr(self, key, value)
def set_location(self, cells):
self.location = random.choice(cells)
return self.location
def set_moves(self, up, down, left, right):
self.up = up
self.down = down
self.left = left
self.right = right
def get_moves(self):
return [self.up, self.down, self.left, self.right]
dungeon_player.py
import random
from dungeon_combat import Combat
weapon_list = ['Sword', 'Bow', 'Axe', 'Hammer', 'Plate']
class Player(Combat):
location = (0, 0)
health = 10
weapon = 'Sword'
def __init__(self, **kwargs):
self.weapon = random.choice(weapon_list)
for key, value in kwargs.items():
setattr(self, key, value)
def set_location(self, cells):
self.location = random.choice(cells)
return self.location
def get_location(self):
return self.location
dungeon_combat.py
The whole combat class and the health and weapons for the monster and player object will be implemented later as I want to add a system of combat if you run into the monsters.
import random
class Combat():
dodge_limit = 6
attack_limit = 6
def dodge(self):
roll = random.randint(self.dodge_limit)
return roll > 4
def attack(self, attacker):
roll = random.randint(0, self.attack_limit)
if attacker.weapon == 'Axe' or 'Sword':
roll += 2
elif attacker.weapon == 'Plate' or 'Rock':
roll -= 1
elif attacker.weapon == 'Hammer' or 'Club' or 'Razor':
roll += 1
return roll > 4
Vedang Patel
7,114 PointsHi David McCarty You a lot of bugs in the game could you try and catch them.
3 Answers
Kenneth Love
Treehouse Guest TeacherThat's awesome!
Martin Cornejo Saavedra
18,132 PointsCool game.
Brandon Wall
5,512 PointsWow! holy moses! I'm about to copy all of this into some notepads and run it through my python interpreter and play it right now, this looks great!
David McCarty
5,214 PointsHaha hope you enjoy it!
Ryan Ruscett
23,309 PointsRyan Ruscett
23,309 PointsWay to go man!! Awesome!
If you wanted to go one step further you could add sound effects "Muahahaha" lol.
Thanks!