Joey Orlando
Joey Orlando

Reputation: 1432

Printing a Visual Map of RPG Game

Hi there guys and gals,

So I'm relatively new to Python (been learning for about 2 weeks now) and to reinforce my learning I have been striving to build my own rendition of the classic dungeon/adventure game. The game has a player, 1 monster (in the future I'm hoping to include 5 or 6), a key, and a door. The player must first search around the dungeon, find the key, and then find the door. Also, the player can pick up weapons and attack/dodge the monsters.

If the player runs into a room where a monster is then this 'wakes the monster up' and it will start to chase the player, moving closer to the player each turn.

I've built a visual representation of the game in the shell by printing out a map based on a list holding 100 tuples (for a 10 x 10 x-y coordinate grid). If the location of any of the game's elements are equal to a particular x, y coordinate then it prints out a representative figure (eg. if the player is in spot 1,1 it will print out a 'X' in spot 1, 1 instead of '_' or if it is the monster it will be '!').

See below for an example of the current map. The squares are currently tiny (1 character by 1 character) and I'm trying to expand it out to be 3 characters by 3 characters (see example 2) with the game element value (if any) printed out in the center.

The issue that I'm running in to is figuring out exactly how to construct these larger squares, I'm stumped. I've been fooling around for over an hour with increasingly complex/crazy-nested for loops and if statements. Wanted to take a breather from this problem and see if anyone has tried to do this in the past/has any handy tips or advice.

Thanks in advance for the help! :)

Joey

First Script

def draw_map(p_loc, m_loc, prior_moves):
  left_side_indices = list(range(0, 100))
  del_multiple = 9

  #This for loop deletes every 9th element (ie. 9, 19, 29...99) and assigns the 
  #existing numbers from 0 to 98 to left_side_indices. The reason why I did this was 
  #because the cells that are on the right side of the grid must be printed differently 
  #than all of the other cells.
  for i in range(10):
    del left_side_indices[del_multiple]
    del_multiple = del_multiple + 9

  non_right_wall_grid = left_side_indices

  print('\n\n\n\n' + ' _' * 10)
  tile = '|{}'


  #unpacking the player location to x and y
  x, y = p_loc
  p_loc = (x, y)
  #unpacking the monster location to a and b (x and y coordinates respectively)
  a, b = m_loc
  m_loc = (a, b)

  #loops through the grid list which is a list of tuples (x, y)
  for idx, cell in enumerate(grid):
    if idx in non_right_wall_grid:
      if cell == player_loc:
        print(tile.format('X'), end="")
      elif cell == monster_loc and player.spotted_monster == True:
        print(tile.format('!'), end="")
      elif cell == door_loc and player.spotted_door == True:
        print(tile.format('O'), end="")
      elif cell in prior_moves:
        print(tile.format('.'), end="")
      else:
        print(tile.format('_'), end="")
    else:
      if cell == player_loc:
        print(tile.format('X|'))
      elif cell == monster_loc and player.spotted_monster == True:
        print(tile.format('!|'))
      elif cell == door_loc and player.spotted_door == True:
        print(tile.format('O'))
      elif cell in prior_moves:
        print(tile.format('.|'))
      else:
        print(tile.format('_|'))

  print('\n\n\n\n')

First Script - Output

 _ _ _ _ _ _ _ _ _ _
|_|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|
|_|_|.|.|.|.|_|_|_|_|
|_|_|_|.|_|.|_|_|_|_|
|_|_|_|.|.|O|X|_|_|_|
|_|_|_|.|_|_|_|_|_|_|
|_|_|_|.|_|_|_|_|_|_|
|_|_|_|.|_|_|_|_|_|_|
|_|_|.|.|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|_|

You are currently in room (7, 5).
You currently do not have the key.
You are currently able to go ['LEFT', 'RIGHT', 'UP', 'DOWN'], type the appropriate word to check out that room.
Type QUIT to stop playing DUNGEON or HELP for help.

Player:  (7, 5)
Monster:  (2, 7)
Door:  (6, 5)
Key:  (9, 1)
Moves After Spotting:  0

Second script below (this is what I'm ultimately striving to build)

Second Script

print('\n\n ___' + '___' * 18 + '__ ')

for _ in range(10):
    print('|     ' * 10 + '|')
    print('|  {}  '.format('X') * 10 + '|')
    print('|_____' * 10 + '|')

print('\n\n')

Second Script - Output

 ___________________________________________________________ 
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|
|     |     |     |     |     |     |     |     |     |     |
|  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |  X  |
|_____|_____|_____|_____|_____|_____|_____|_____|_____|_____|

SOLUTION

def draw_map():
  left_side_indices = list(range(0, 100))
  del_multiple = 9

  #This for loop deletes every 9th element (ie. 9, 19, 29...99) and assigns the existing numbers from 0 to 98 to left_side_indices
  for i in range(10):
    del left_side_indices[del_multiple]
    del_multiple = del_multiple + 9

  non_right_wall_grid = left_side_indices


  print('\n\n ___' + '___' * 18 + '__ ')

  for row in range(10):
    print('|     ' * 10 + '|')
    for column in range(10):
      if column in non_right_wall_grid:
        print('|  {}  '.format(tile_contents(player_loc, monster_loc, prior_moves, row, column)), end='')
      else:
        print('|  {}  |'.format(tile_contents(player_loc, monster_loc, prior_moves, row, column)))
    print('|_____' * 10 + '|')
  print('\n\n')


def tile_contents(p_loc, m_loc, prior_moves, row, column):
  x, y = p_loc
  p_loc = (x, y)
  a, b = m_loc
  m_loc = (a, b)
  coordinate = (column, row)

  if coordinate == p_loc:
    return('X')
  elif coordinate == m_loc and player.spotted_monster == True:
    return('!')
  elif coordinate == door_loc and player.spotted_door == True:
    return('O')
  elif coordinate in prior_moves:
    return('.')
  else:
    return('_')

Upvotes: 1

Views: 1816

Answers (1)

Roberto
Roberto

Reputation: 2786

What about something like:

def print_map():     
    print('\n\n ___' + '___' * 18 + '__ ')  
    for row in range(10):
        print('|     ' * 10 + '|')
        for column in range(10):
            print('|  {}  '.format(tile_contents(row, column)), end='')
        print('|')
        print('|_____' * 10 + '|')
    print('\n\n')


def tile_contents(row,column):
    # Put here all conditionals based on row, column positions of player, monsters
    # Return the character to be displayed in the middle of the cell

    return "X"

print_map()

Upvotes: 1

Related Questions