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

Python Python Collections (2016, retired 2019) Dungeon Game Win or Lose

Steven Tagawa
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Steven Tagawa
Python Development Techdegree Graduate 14,438 Points

Somewhat extended dungeon game code

Kenneth suggested posting your final game code here, so I am... I took his advice in the first video, hashing out a bunch of stuff before watching some of the later videos, and where I took a different approach, my code looks a bit different. (For example, I used random.randint to return coordinates rather than using random.sample on a list of all possible coordinates.) I also took Craig's DRY advice and moved as much as possible into functions...which mostly involved me learning how to use the global keyword to modify global variables inside functions. :) I only implemented a couple of extensions—I let the user pick the size of the grid, and I put in a debug mode that can be toggled on and off. Anyway, it appears to all work, so I'm putting it here so others can see that it really can be done. :)

EDIT: The original had a break statement and some continue statements that were superfluous, so I removed them.

import random
import os

# CONSTANT declarations:
EMPTY_CELL = "[ ]"
PLAYER_CELL = "[P]"
MONSTER_CELL = "[M]"
EXIT_CELL = "[E]"
PLAYER = 0
MONSTER = 1
EXIT = 2

# FUNCTION declarations:


# intro function
def intro():
    global grid_size
    global debug
    debug = False
    clear_screen
    print("Welcome to the Python Dungeon!")
    valid = False
    while valid == False:
        try:
            response = int(input("Pick a size for your dungeon (5 - 12):  "))
        except ValueError:
            print("That's not a number!  Try again.")
            continue
        else:
            if response < 5:
                print("That's too small!  Try again.")
            elif response > 12:
                print("That's too big!  Try again.")
            else:
                grid_size = response - 1
                valid = True
            # end if
        # end try
    # end while


# set grid function
def create_grid(max_size, default_value):
    grid_list = []
    for y in range(max_size + 1):
        new_row = []
        for x in range(max_size + 1):
            new_row.append(default_value)
        grid_list.append(new_row)
    # end for
    return grid_list


# print grid function
def print_grid(grid):
    for y in range(len(grid)):
        print("".join(grid[y]))
    # end for


# clear screen function
def clear_screen():
    os.system("cls" if os.name == "nt" else "clear")


# get a single random location function
def get_location(max_range, *args):
    unique = False
    while unique == False:
        new_position = random.randint(0, max_range), random.randint(0, max_range)
        for arg in args:
            if new_position == arg:
                unique = False
            else:
                unique = True
            # end if
        # end for
    return new_position


# get a valid move from the player
def get_move(position, max_range):
    global game_over
    global debug
    all_moves = ["UP", "DOWN", "LEFT", "RIGHT"]
    valid_moves = ["UP", "DOWN", "LEFT", "RIGHT"]
    x_position, y_position = position
    if x_position == 0:
        valid_moves.remove("LEFT")
    if x_position == max_range:
        valid_moves.remove("RIGHT")
    if y_position == 0:
        valid_moves.remove("UP")
    if y_position == max_range:
        valid_moves.remove("DOWN")
    # because this list can only be up to four words long, three if statements would do,
    # but this also works for longer lists.
    output = ""
    if len(valid_moves) == 2:
        output = valid_moves[0] + " or " + valid_moves[1]
    else:
        for x in range(len(valid_moves) - 2):
            output += valid_moves[x] + ", "
        output += valid_moves[-2] + " or " + valid_moves[-1]
    print("You can move", output)
    valid = False
    while valid == False:
        new_move = input("Where do you want to go? (Enter 'Q' to quit)  >").upper()
        if new_move in all_moves:
            if new_move in valid_moves:
                valid = True
                if new_move == "LEFT":
                    x_position -= 1
                elif new_move == "RIGHT":
                    x_position += 1
                elif new_move == "UP":
                    y_position -= 1
                elif new_move == "DOWN":
                    y_position += 1
                # end if
            else:
                print("Ouch, that's a wall!  Try again.")
            # end if
        else:
            if new_move == "Q":
                if input("Are you sure you want to give up? (Y/N)  >").upper() == "Y":
                    print("Game Over!  You quit!")
                    valid = True
                    game_over = True
            elif new_move == "DEBUG":
                if not debug:
                    if input("Enter debug mode? (Y/N)  >").upper() == "Y":
                        debug = True
                        input("Debug mode ON.\n(Monster and exit will appear after your next move.)\nPress Enter to continue.")
                    # end if
                else:
                    if input("Exit debug mode? (Y/N)  >").upper() == "Y":
                        debug = False
                        input("Debug mode OFF.\n(Monster and exit will no longer appear after your next move.)\nPress Enter to continue.")
                    # end if
            else:
                print("That's not a direction!  Try again.")
        # end if
    # end while
    position = x_position, y_position
    return position


# set player in grid function
def set_cell(position, grid, entity):
    position_x, position_y = position
    if entity == PLAYER:
        grid[position_y][position_x] = PLAYER_CELL
    if entity == MONSTER:
        grid[position_y][position_x] = MONSTER_CELL
    if entity == EXIT:
        grid[position_y][position_x] = EXIT_CELL
    # end if


# clear player fron grid function
def clear_cell(position, grid):
    position_x, position_y = position
    grid[position_y][position_x] = EMPTY_CELL


# initialization function
def initialize_game():
    # set game status
    global game_over
    global MONSTER_POSITION
    global EXIT_POSITION
    global player_position
    global game_grid
    game_over = False
    # initialize grid
    game_grid = create_grid(grid_size, EMPTY_CELL)  
    # pick random locations for player, exit, monster
    MONSTER_POSITION = get_location(grid_size, None)
    EXIT_POSITION = get_location(grid_size, MONSTER_POSITION)
    player_position = get_location(grid_size, MONSTER_POSITION, EXIT_POSITION)
    # draw player in grid
    set_cell(player_position, game_grid, PLAYER)


# screen print function
def print_screen(position):
    clear_screen()
    print("You're in the Python Dungeon!")
    player_display_x, player_display_y = position
    print("You are in room [{}, {}]".format(player_display_x + 1, player_display_y + 1))
    print_grid(game_grid)


def check_win_lose(position):
    global game_over
    if position == MONSTER_POSITION:
        set_cell(player_position, game_grid, MONSTER)
        print_screen(player_position)
        print("You found the monster!\nGame over!  You lost!")
        game_over = True
    elif position == EXIT_POSITION:
        set_cell(player_position, game_grid, EXIT)
        print_screen(player_position)
        print("You found the exit!\nGame over!  You won!")
        game_over = True
    # end if


def main_loop():
    # main game loop
    global player_position
    global game_over
    while not game_over:
        print_screen(player_position)
        clear_cell(player_position, game_grid)
        player_position = (get_move(player_position, grid_size))
        # check if user quit here; skip rest of loop if so
        if game_over:
            continue
        set_cell(player_position, game_grid, PLAYER)
        if debug:
            set_cell(MONSTER_POSITION, game_grid, MONSTER)
            set_cell(EXIT_POSITION, game_grid, EXIT)
        check_win_lose(player_position)
    # end while


def play_again():
    global play
    valid = False
    while valid == False:
        response = input("Play again? (Y/N)  >").upper()
        if response == "Y":
            play = True
            valid = True
        elif response == "N":
            play = False
            valid = True
        else:
            print("Sorry, I didn't get that.")
        # end if
    #end while

# --------------------------------------------------------------------------------------------

# GAME STARTS HERE:

play = True
while play:
    intro()
    initialize_game()
    main_loop()
    play_again()
# end while
nakalkucing
nakalkucing
12,964 Points

Nice game, Steven! :) Plays well!

1 Answer

Good stuff friend! Looks neat!

Steven Tagawa
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Steven Tagawa
Python Development Techdegree Graduate 14,438 Points

Thanks! Of course after reading over it again I tweaked it a bit. There were some else: continue statements that were unnecessary because there was no more code to skip. (I had some trouble with the difference between break and continue.)