Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Python Collections (Retired) Dungeon Game Building the Game: Part 1

Y. Kravets
Y. Kravets
10,350 Points

My version of dungeon game up for review :-)

Hi guys!

So as usual I have attempted to write the game before looking at Kenneth's solution. It seems to work with a small glitch I have noticed. Despite me specifically requesting that initial positions of the player, monster and door do not coincide I have managed to get some runs where these were the same. I honestly don't understand why. Apart from that it seems to be doing the trick :-)

Any comments and improvements are very welcome! The code is below.

Merry Xmas!!! :-)

import random

def show_help():
  print('Welcome to the Dungeon game!')
  print('\nYour goal is to get to the door before a monster gets to you')
  print('\nYou can navigate yourself by using UP, DOWN, LEFT, RIGHT commands')
  print('\nIf scared QUIT command will get you out of the game :)')

def meshcreation(x, y):
  coordinate_list = []
  row = 1
  column = 1
  while row < x:
    while column < y:
      cell = [row, column]
      row += 1
      column += 1
      coordinate_list.append(cell)
  return coordinate_list

def get_positions(CELLS):
  player = random.choice(CELLS)
  monster = random.choice(CELLS)
  door = random.choice(CELLS)

  if monster == player or monster ==door or door == player:
    get_positions(CELLS)
  return player, monster, door

def get_player_moves(player_move, player_coord):
  if player_move == 'LEFT': 
    if player_coord[0] == 1:
      print("Oops! You are currently are at the border of the grid. You cannot move LEFT. There is no life beyond the grid")
    else:
      player_coord[0] = player_coord[0]-1
  if player_move == 'RIGHT':
    if player_coord[0] == x:
      print("Oops! You are currently are at the border of the grid. You cannot move RIGHT. There is no life beyond the grid")
    else:
      player_coord[0] = player_coord[0]+1
  if player_move == 'UP':
    if player_coord[1] == 1:
      print("Oops! You are currently are at the border of the grid. You cannot move UP. There is no life beyond the grid")
    else:
      player_coord[1] = player_coord[1]-1
  if player_move == 'DOWN':
    if player_coord[1] == y:
      print("Oops! You are currently are at the border of the grid. You cannot move DOWN. There is no life beyond the grid")
    else:
      player_coord[1] = player_coord[1]+1

def get_monster_moves(monster_coord):
  moves = ['LEFT', 'RIGHT', 'UP', 'DOWN']
  monster_move = random.choice(moves)
  if monster_move == 'LEFT': 
    if monster_coord[0] == 1:
      get_monster_moves(monster_coord)
    else:
      monster_coord[0] = monster_coord[0]-1
  if monster_move == 'RIGHT':
    if monster_coord[0] == x:
      get_monster_moves(monster_coord)
    else:
      monster_coord[0] = monster_coord[0]+1
  if monster_move == 'UP':
    if monster_coord[1] == 1:
      get_monster_moves(monster_coord)
    else:
      monster_coord[1] = monster_coord[1]-1
  if monster_move == 'DOWN':
    if monster_coord[1] == y:
      get_monster_moves(monster_coord)
    else:
      monster_coord[1] = monster_coord[1]+1

show_help()

x_str = input('\nLet me know how long do you want your grid to be: ')
y_str = input('\nLet me know how wide do you want your grid to be: ')
x = int(x_str)
y = int(y_str)

CELLS = meshcreation(x, y)
player, monster, door = get_positions(CELLS)

print('You are currently in a {} position'.format(player))
print('The monster is currently in a {} position'.format(monster))
print('The door is currently in a {} position'.format(door))

while player != door:
  if player != monster:
    player_move = input('You are still alive! Whats your move: ')
    if player_move == 'QUIT':
      print('You have just quit the DUNGEON GAME! See you soon :-)')
      break
    else:
      get_player_moves(player_move, player)
      get_monster_moves(monster)
      print('You are currently in a {} position'.format(player))
      print('The monster is currently in a {} position'.format(monster))
      print('The door is currently in a {} position'.format(door))
  else:
    print('You have been eaten by a monster :-( Better luck in your next life!')
    break
else: 
  print('You have found the door! You are safe :-)')

2 Answers

Hi Yevgen Kravets, while your concept is good (I like the idea of being able to specify the grid size) unfortunately your code doesn't seem to work quite right as it is now.

I'll start with the meshcreation function. It doesn't create the grid the way that you would expect, for the following reasons:

  • You're incrementing both the row and column variables for each loop over the columns.
  • You're not looping enough times for each of the rows/columns, since you already start with your row/column counters at 1 and you're using a less-than conditional. You can either change the conditionals to less-than-or-equal-to (<=) or loop while row < x+1 and column < y+1.

The following should work (though perhaps you should be checking for sufficiently large dimensions to avoid other errors, see below):

def meshcreation(x, y):
  coordinate_list = []
  row = 1
  while row <= x:
    column = 1
    while column <= y:
      cell = [row, column]
      column += 1
      coordinate_list.append(cell)
    row += 1
  return coordinate_list

Next, in your get_positions function, your check for equal starting positions of the player/door/monster doesn't quite work right, and if the grid is too small, you can end up looping infinitely trying to generate it.

Try this:

def get_positions(CELLS):
  player = random.choice(CELLS)
  monster = random.choice(CELLS)
  door = random.choice(CELLS)

  if monster == player or monster == door or door == player:
    return get_positions(CELLS)
  else:
    return player, monster, door

Those fixes should be enough to get the game working, though there are some other things you should consider:

  • As mentioned, you need to make sure the grid is large enough that the player, door and monster can all exist in different locations (i.e. there are 3 or more spaces available). One way would be to make sure the product (multiplication) of x and y equals 3 or greater.
  • Because the monster MUST move each round/turn and the coordinates of the player, monster and door are all known, the game is very easy, because you can move to where the monster currently is, knowing it will move away from that space. Knowing this, it's basically impossible to lose on small grids.
  • If the player puts in an incorrect/invalid move (against the edge of the grid), the monster will still move... if that is not the desired behaviour, you'll need a way to make it trigger the request for a move again. Perhaps you could move the input and the QUIT check to the get_player_moves function?
  • You should check for and handle negative numbers or other values that won't successfully create a grid.

Keep on coding! :)

Y. Kravets
Y. Kravets
10,350 Points

These are great suggestions Iain Simmons! I will upload an updated versions soon!