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

I would Kenneth Love it if you would play and critique my dungeon game Kenneth Love.

Not a question, just following directions from the last video about adding features to "dungeon game". Definitely looking for ways to improve my code because it is UGLY and pretty slow. Also let me know if you like it. Kenneth Love

Here's the code

import os
import random



CELLS = [(0, 0), (1, 0), (2, 0), (3, 0), (4,0), (5,0), (6,0), 
        (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5,1), (6,1),
        (0, 2), (1, 2), (2, 2), (3, 2), (4, 2), (5,2), (6,2),
        (0, 3), (1, 3), (2, 3), (3, 3), (4, 3), (5,3), (6,3),
        (0, 4), (1, 4), (2, 4), (3, 4), (4, 4), (5,4), (6,4),
        (0, 5), (1, 5), (2, 5), (3, 5), (4, 5), (5,5), (6,5),
        (0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5,6), (6,6)]


rpsdata = ['ROCK','PAPER','SCISSORS']

def clear_screen():
    os.system('cls' if os.name == 'nt' else 'clear')

def get_locations():
    return random.sample(CELLS,6)

def RPS():

    play = True
    win = False

    while play:
        mon_rps = random.choice(rpsdata)
        p_rps = input("Quickly! Choose 'ROCK', 'PAPER', or 'SCISSORS'!>>> ")
        p_rps = p_rps.upper()
        if p_rps == "SCISSORS" and mon_rps == "PAPER":
            input("Enemy chose {}, you won!".format(mon_rps))
            win = True
            play = False
        elif p_rps == "SCISSORS" and mon_rps == "ROCK":
            input("Enemy chose {}, you lose!".format(mon_rps))
            win = False
            play = False
        elif p_rps == "ROCK" and mon_rps == "SCISSORS":
            input("Enemy chose {}, you won!".format(mon_rps))
            win = True
            play = False
        elif p_rps == "ROCK" and mon_rps == "PAPER":
            input("Enemy chose {}, you lose!".format(mon_rps))
            win = False
            play = False
        elif p_rps == "PAPER" and mon_rps == "ROCK":
            input("Enemy chose {}, you won!".format(mon_rps))
            win = True
            play = False
        elif p_rps == "PAPER" and mon_rps == "SCISSORS":
            input("Enemy chose {}, you lose!".format(mon_rps))
            win = False
            play = False
        else:
            input("It was a tie!")
    return win


def move_object(ob1, move):
    x, y = ob1
    if move == 'LEFT':
        x -= 1
    if move == 'RIGHT':
        x += 1
    if move == 'DOWN':
        y += 1
    if move == 'UP':
        y -= 1
    return x, y

def get_moves(ob1):
    moves = ["LEFT", "RIGHT", "UP", "DOWN"]
    x, y = ob1
    if y == 0:
        moves.remove("UP")
    if y == 6:
        moves.remove("DOWN")
    if x == 0:
        moves.remove("LEFT")
    if x == 6:
        moves.remove("RIGHT")
    return moves

def draw_map(player, monster, door, trap1, trap2, switch, cansee):
    print(" _" *7)
    tile = "|{}"

    for cell in CELLS:
        x, y = cell
        if x < 6:
            line_end = ""
            if cell == player:
                output = tile.format("X")
            elif cell == door:
                output = tile.format("]")
            elif cell == monster:
                output = tile.format("@")
            elif cell == switch:
                output = tile.format("o")
            elif cansee == True and cell == trap1:
                output = tile.format("^")
            elif cansee == True and cell == trap2:
                output = tile.format("^")
            else:
                output = tile.format("_")
        else:
            line_end = "\n"
            if cell == player:
                output = tile.format("X|")
            elif cell == monster:
                output = tile.format("@|")
            elif cell == door:
                output = tile.format("]|")
            elif cell == switch:
                output == tile.format("o|")
            elif cansee == True and cell == trap1:
                output == tile.format("^|")
            elif cansee == True and cell == trap2:
                output == tile.format("^|")
            else:
                output = tile.format("_|")
        print(output, end=line_end)

def ai_abridged(ob1, ob2):
    x,y = ob1
    a,z = ob2
    mov = ""
    if abs(x-a) > abs(y-z):
        if x-a > 0:
            mov = "LEFT"
        else:
            mov = "RIGHT"
    else:
        if y-z > 0:
            mov = "UP"
        else:
            mov = "DOWN"
    return mov   



def game_loop():
    player, monster, door, trap1, trap2, switch = get_locations()
    cansee = False
    playing = True
    while playing:
        clear_screen()
        draw_map(player, monster, door, trap1, trap2, switch, cansee)
        valid_moves = get_moves(player)
        mon_moves = get_moves(monster)

        print("You're currently in room at {}".format(player))
        print("The monster is in the room at {}".format(monster))
        print("You can move {}, type help to reference your guide on this dungeon.".format(", ".join(get_moves(player))))
        print("Enter QUIT to quit")

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

        if move == 'QUIT':
            print("Discretion is the better part of valor.")
            input("A wise adventurer knows when to flee...")
            break
        if move == 'HELP':
            clear_screen()
            print("_"*110)
            print("The 'X', '@', 'o', ']', and '^' symbols stand for the player, monster, switch, door and trap respectively")
            print("If you touch the monster you will have to battle!")
            print("Whosoever touches a trap shall die")
            print("If you touch the switch it will reveal the location of the traps in the room!")
            print("The goal is to make it to the door or to kill the monster.")
            print("_"*110)
            input("Press enter to continue")
            continue

        #Player moves first
        if move in valid_moves:
            player = move_object(player, move)
            if player == monster:
                input("Prepare for battle!")
                lose = RPS()
                if lose == True:
                    print("A crushing victory.")
                    input("It is your valor in battle that has won the day!")
                    playing == False
                    break
                else:
                    print("Your body will make a great feast for the monster.")
                    input("Perhaps your gear will be of use to the next adventurer!")
                    playing == False
                    break
            elif player == door:
                print("You narrowly escape with your life.")
                input("Until next time...")
                playing = False
                break
            elif player == trap1 or player == trap2:
                print("You stepped on a trap and died!")
                input("Only the careful can know peace in this abhorrent dungeon...")
                playing == False
                break
            elif player == switch:
                print("You pressed a switch and revealed the traps in the room!")
                cansee = True

        else:
            input("\nYour brain said go {} and that didn't work. You stumble.\n".format(move))

        #Then monster moves
        input("The monster bounds towards you..")
        mon_pick = ai_abridged(monster,player)
        if mon_pick in mon_moves:
            monster = move_object(monster,mon_pick)
            if monster == door:
                print("The monster prevents your escape!")
                input("Surely it wishes to fight!")
            elif monster == player:
                input("Prepare for battle!")
                lose = RPS()
                if lose == True:
                    print("A crushing victory.")
                    input("It is your valor in battle that has won the day!")
                    playing == False
                    break
                else:
                    print("Your body will make a great feast for the monster.")
                    input("Perhaps your gear will be of use to the next adventurer!")
                    playing == False
                    break
            elif monster == trap1 or monster == trap2:
                print("The monster fell victim to his own trap.")
                input("Sometimes, survival is only a matter of luck...")
                playing == False
                break
            elif monster == switch:
                print("The monster is blocking the switch!")
        else:
            print("The monster glares at you and doesn't move")

    print("Thanks, I hope you enjoyed it!")
    if input("Do you wanna play or leave? (P/l) >>> ").lower()!= "l":
        game_loop()





clear_screen()
print("_"*100)
print("Welcome to Dungeon Game, a hellish nightmare of monsters and RNG where luck can be the greatest skill!")
input("Press enter to start")
clear_screen()
game_loop()

1 Answer

Kenneth Love
STAFF
Kenneth Love
Treehouse Guest Teacher

Hey Matt!

First off, love the title. You really know how to pique my curiosity.

Secondly, that's a lot of code! I'm sure we can find a thing or two to improve. So, I'm gonna copy and paste all of your code into my editor (PyCharm) and see what it tells me.

  • lines 117, 119, and 121 should probably be using = instead of ==
  • same for 187, 192, and 202
  • oh, and 225, 230, and 235

OK, so, I fixed those things and reformatted the file to fit PEP 8's standards (if you haven't seen PEP 8 I highly recommend you read it. It's the guide for how your Python code should look). From this point on, line numbers wouldn't necessarily match up, so I'll post snippets of code.

            elif cansee == True and cell == trap1:
                output = tile.format("^")
            elif cansee == True and cell == trap2:
                output = tile.format("^")

While these lines are fine, it's usually best not to compare directly to True or False. You should rewrite these as:

            elif cansee and cell == trap1:
                output = tile.format("^")
            elif cansee and cell == trap2:
                output = tile.format("^")

Also, you have a few places with really long strings. Let's look at this one:

            print(
                "The 'X', '@', 'o', ']', and '^' symbols stand for the player, monster, switch, door and trap respectively")

Strings often feel really hard to break up but they're really not. You can break them into multiple lines and combine them with plus signs. Or, since it's inside of the print() function, you can actually just stop one string and start the next one and Python'll join them up.

            print("The 'X', '@', 'o', ']', and '^' symbols stand for the player, "
                  "monster, switch, door and trap respectively")

Now let's talk about your RPS function. I love that you brought this in for battle. It's a great idea! There's a couple of places, though, where you wrote a bit more code than you needed to. I'll just show one example and I'm sure you'll see how to change the others.

        if p_rps == "SCISSORS" and mon_rps == "PAPER":

Since you're always comparing these two things, you can save yourself some time by comparing tuples instead of each variable explicitly.

        if (p_rps, mon_rps) == ("SCISSORS", "PAPER"):

Yes, it's still doing the same comparison, but it's a bit less to type and you don't have to remember that and. You might be amazed how often and and or get used incorrectly or just forgotten. I love 'em but they're a pain in the butt sometimes.

Overall, great job!

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Actually, those two trap comparisons could be even easier.

            elif cansee and cell in (trap1, trap2):
                output = tile.format("^")

Thanks a lot for the feedback! As I had guessed there was quite a bit wrong with my code. However I have just finished the OOP python course and the one covering PEP 8 so I plan to revise and improve my code greatly. Thank you for the multitude of suggestions I didn't actually expect to get such a great response. Keep up the good work, your python courses have been the most challenging and rewarding of the tracks I've been through. Building games is awesome.