Terminal Game: Dungeon Crawl

Hello! I made a terminal dungeon crawler for my CS101 project.

Feel free to give any kind of feedback!

You can find it on github here: GitHub - toowo11/dungeon: codecademy project - dungeon crawler python practice

I’m a sucker for these kind of things…

Right, make a Room class and a Game class. Stuff shouldn’t all be hanging out there in global scope.

Ideally, I’d like to see:

game = Game()
while not game.done():
    game.turn()

Perhaps your biggest issue is that endturn and newturn call each other! It may not be immediately apparent, but they’re digging a deep callstack hole.

Hmm… a fun test example:

class Player:
    def __init__(self, name, health = 5):
        self.name, self.health = name, health
        self.max_health = self.health # if max health is start health, don't repeat yourself.
        self.stack_depth = 0 # just popping this in here for tracing

    def add_health(self, amount):
        self.health += amount
        if self.health > self.max_health:
            self.health = self.max_health
        elif self.health < 0:
            self.health = 0
        print("Your health is now at {}.".format(self.health))

    def alive(self):
        return self.health>0

player = Player("Alice", 3)

def end_turn():
    player.stack_depth += 1
    depth = player.stack_depth
    print("This turn has ended.")
    print("")
    if player.alive():
        new_turn()
    else:
        print("Game Over.")
    print("leaving end_turn", depth)
    player.stack_depth -= 1

def new_turn():
    player.stack_depth += 1
    depth = player.stack_depth
    print("Ouch, that hurts")
    player.add_health(-1)
    end_turn()
    print("leaving new_turn", depth)
    player.stack_depth -= 1

new_turn()

Result:

Ouch, that hurts
Your health is now at 2.
This turn has ended.

Ouch, that hurts
Your health is now at 1.
This turn has ended.

Ouch, that hurts
Your health is now at 0.
This turn has ended.

Game Over.
leaving end_turn 6
leaving new_turn 5
leaving end_turn 4
leaving new_turn 3
leaving end_turn 2
leaving new_turn 1

So, how to fix this? Something like:

class Game:
    def __init__(self, player):
        self.player = player

    def done(self):
        return not self.player.alive()

    def turn(self):
        if not self.done():
            self.new_turn()
            self.end_turn()

        if self.done():
            print("Game Over.")

    def end_turn(self):
        print("This turn has ended.")
        print("")

    def new_turn(self):
        print("Ouch, that hurts")
        self.player.add_health(-1)

game = Game(Player("Alice", 3))
while not game.done():
    game.turn()

Do not call an end turn function. Rather, always return our of your new_turn and let the code after that do cleanup.