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 2

fahad lashari
fahad lashari
6,771 Points

I added some upgrades to the game. Please help making the code more efficient.

I decided to just tweak a few things around. I made the map bigger. Displayed the main monster on the map. Added an additional hidden monster to the map. Both of the monster now follow you around using the move_monster_closer() function in the code. And for a twist, I also added some mines littered around the map. There is also now a health system.

Even though the code works just fine. I believe it could definitely be made more efficient. Please let me know which parts of the code could be improved further. I would love your feedback.

I believe the code can be improved in the move_monster_closer(). Do you guys think there is a better shorter way of doing what I am doing there? Once the monsters know the whereabouts of the player they hover just one box outside of the player's location. I have had to do this manually in steps. However I will try to solve this using some algebra I guess but meanwhile if you guys can find a better way of solving this, that would be absolutely phenomenal!

Here is the game. Try it in your work spaces and Enjoy!!!

Kind regards,

Fahad

import random
import sys
#Create a health function maximum 2 health DONE
#Make the monster get closer with each try DONE
#create an addtional monster DONE
#Make the map bigger DONE
#two encounters with the monster end the game DONE
#Add a health collection method 1 health each time NOT DONE
#Warn player if monster is near by NOT DONE
#introduce 3 difference weapons for the player NOT DONE
#delete and remove the previously used boxes NOT DONE
#create a function to display all relevant information in a presentable manner NOT DONE
#litter the place with mines DONE
#new objective: litter the mines around the door, creating only one escape door NOT DONE
CELLS = [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5),
         (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
         (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
         (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
         (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (4, 5),
         (5, 0), (5, 1), (5, 2), (5, 3), (5, 4), (5, 5)] 


health = 2
def exit():
    sys.exit()

def get_locations():

  monster = random.choice(CELLS)

  door = random.choice(CELLS)

  start = random.choice(CELLS)
  monster2 = random.choice(CELLS)
  mine_locations = random.sample(CELLS, 6)




  if monster == start or monster == door or monster2 == start or monster2 == door or start == door:
     return get_locations()
  if monster in mine_locations or start in mine_locations or door in mine_locations or monster2 in mine_locations:
    return get_locations()
  print("POSSIBLE MINE LOCATIONS: {}".format(mine_locations))
  return monster, door, start, monster2, mine_locations

def move_monster_closer(player):

  #collect the player's location
  px, py = player
  #create a list of possible locations around the player
  x1, y1 = px - 1, py - 1
  x2, y2 = px - 1, py
  x3, y3 = px - 1, py + 1
  x4, y4 = px, py - 1
  x5, y5 = px, py + 1
  x6, y6 = px + 1, py - 1
  x7, y7 = px + 1, py
  x8, y8 = px + 1, py + 1

  xy_list = [(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x5, y5), (x6, y6), (x7, y7), (x8, y8)]
  bad_locations = []
  #print("This is the possible location list: {}".format(xy_list))
  for xy_item in xy_list:
    if xy_item[0] > 5 or xy_item[1] > 5 or xy_item[0] < 0 or xy_item[1] < 0:
      bad_locations.append(xy_item)
  for xy_item in bad_locations:
      while True:
        try:
          xy_list.remove(xy_item)
        except:
          break

  #print("These are the bad locations: {}".format(bad_locations))
  #print("This is the list of location from which the monster chose: {}".format(xy_list))
  monster = random.choice(xy_list)
  xy_list.remove(monster)
  #print("These are the possible locations for monster 2: {}".format(xy_list))
  monster2 = random.choice(xy_list)
  return monster, monster2


  #limit the maximum and minimum values of x, y to keep the monster in side the map

  print("Player correctly in cell: {}".format(player_cell))


def move_player(player, move):
  #Get the player's current location

  x, y = player

  if move == 'LEFT':
    y-=1
  elif move == 'RIGHT':
    y+=1
  elif move == 'UP':
    x-=1
  elif move == 'DOWN':
    x+=1
  return x, y


def get_moves(player):
  moves = ['LEFT', 'RIGHT', 'UP', 'DOWN']

  #player = (x, y)
  if player[1] == 0:
     moves.remove('LEFT')
  if player[1] == 5:
     moves.remove('RIGHT')
  if player[0] == 0:
     moves.remove('UP')
  if player[0] == 5:
     moves.remove('DOWN')

  return moves

def draw_map(player, monster, monster2, door, mine_locations):

  print(' _ _ _ _ _ _')
  tile = '|{}'

  for idx, cell in enumerate(CELLS):
    #use slicing here to shorten this code down
      if idx in [0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28,
                 30, 31, 32, 33, 34]:
        if cell == player:
          print(tile.format('X'), end='')
        elif cell == monster:
          print(tile.format('@'), end='')
        elif cell in mine_locations:
              print(tile.format('#'), end='')
        #elif cell == monster2:
          #print(tile.format('2'), end='')
        elif cell == door:
          print(tile.format('D'), end='')
        else:
          print(tile.format('_'), end='')
      else:
        if cell == player:
          print(tile.format('X|'))
        elif cell == monster:
          print(tile.format('@|'))
        elif cell in mine_locations:
          print(tile.format('#|'))
        elif cell == door:
          print(tile.format('D|'))
        #elif cell == monster2:
          #print(tile.format('2|'))
        else:
          print(tile.format('_|'))
monster, door, player, monster2, mine_locations = get_locations()
print("Welcome to the dungeon!")
while True:


  moves = get_moves(player)

  print("You are currently in room".format(player))
  #print("POSSIBLE MINE LOCATIONS: {}".format(mine_locations)) 
  #draw_map(player, monster)
  draw_map(player, monster, monster2, door, mine_locations)
  #draw_map(player, monster, monster2, door)
  #move_monster_closer(monster, player)
  print("You're currently in room {}".format(player))  # fill in with player position
  print("Monster is currently in room {}".format(monster))
  print("Hidden monster location: {}".format("Unknown"))
  print("You can move {}".format(moves))  # fill in with available moves
  print("Enter QUIT to quit")
  print("Health status: {}".format(health))

  move = input("> ")
  move = move.upper()

  if move == 'QUIT':
    break
  if move in moves:
    player = move_player(player, move)
  else:
    print("**Walls are hard. Stop walking into them! **")
    continue
  if health == 0 and player == monster:
    print("Ouch! You were eaten by the monster!")
    exit()  
  if player == monster:
    print("You were almost eaten! though the extent of your injuries give you a chance of survival;\nDo not expect to be so lucky next time!".upper())
    health-=1
  elif player == door:
    print("You escaped!")
    exit()
  elif player == monster2:
    print("Ouch! You were eaten by the second hidden monster!")
    exit()
  elif player in mine_locations:
    print("*BOOM!* You hit a mine! x_x ")
    exit()
  #print("Monster 2 is currently in room {}".format(monster2))
  monster, monster2 = move_monster_closer(player)
get_locations()

1 Answer

Your code looks great to me. (I might've missed something, I just skimmed through your code.)

For writing Python, I would recommend bumping up the indentation level from 2 to 4. That's Python's default :)

Most people (including Kenneth Love) use 4 spaces for the indentation level :smile:

I, however, personally like tabs (same size as 4 spaces) more than spaces, so I can easily un-indent code without hassle of memorizing one indentation level is equal to 4 spaces.

Good luck! :smile:

~Alex