Michael Johnson
Michael Johnson

Reputation: 470

Inheritance issue I don't understand

I'm a beginner and stumbled across an issue with inheritance.

When I use this block of code, the program doesn't work correctly thanks to a line in the enter function:

class Bathroom(Room):

    def __init__(self):
        super(Bathroom, self).__init__("bathroom")


    def enter(self, world, player):
        super(Bathroom, self).enter(world, player)

But, when I use this, it does:

class Bathroom(Room):

    def __init__(self):
        super(Bathroom, self).__init__("bathroom")

Are they not the same thing?

The full script I've written (not finished btw) is below. When I enter 'y' after being asked 'Do you want to leave', the program finishes when I use 'super' to inherit the enter function. If I don't, the program works:

while player and self.name != "corridor":

            response = self._ask_question("Do you want to leave? (y/n) ", "y", "n")

            if response == "y":
                return world.corridor
            elif response == "n" and self.enemy:
                print("The", self.enemy, "kills you. You didn't even put up a\
fight")
                return world.death

Full script:

import random
import time
# bad from sys import exit

class Character(object):

    def __init__(self, name, health, attack):
        self.name = name
        self.health = health
        self.attack = attack

    def __str__(self):
        return str(self.health) + " health and " + str(self.attack) + " attack."



class Room(object):

    def __init__(self, name):
        self.name = name
        self.enemy = self._getRandEnemy()


    def enter(self, world, player):
        print(player.name + ",", "you are in the", self.name + ". You have\
 " + str(player))

        if self.enemy: # you may have killed it
            print("But, wait! There's a", self.enemy.name, "with " + str(\
                self.enemy))
            response = self._ask_question("Do you stay and fight?(y/n)\
", "n", "y")
            if response == "n":
                pass

            if response == "y":
                self.combat(player, self.enemy)

        else:
            print("No enemies here.")


        # check if player has no health after potential fight
        if player.health < 1:
            return world.death

        while player and self.name != "corridor":

            response = self._ask_question("Do you want to leave? (y/n) ", "y", "n")

            if response == "y":
                return world.corridor
            elif response == "n" and self.enemy:
                print("The", self.enemy, "kills you. You didn't even put up a\
fight")
                return world.death



    def _getRandEnemy(self):

        names = ["Troll", "Witch", "Ogre", "Jeremy Corbyn"]

        return Character(random.choice(names), random.randint(4, 6),\
                         random.randint(2, 3))


    def _ask_question(self, question, a, b):

        response = None
        while response not in(a, b):
            response = input(question)

        return response


    def combat(self, player, enemy):
        while player.health > 0 and enemy.health > 0:
            time.sleep(1)
            print("You attack and deal", player.attack, "damage")
            enemy.health -= player.attack
            if enemy.health >= 1:
                print("The enemy has " + str(self.enemy))
                time.sleep(1)
                print("The", self.enemy.name, "attacks and deals you",\
                      self.enemy.attack, "\
damage.")
                player.health -= enemy.attack
                print("You have " + str(player))



        if player.health < 1:
            pass
        if enemy.health < 1:
            print("Ha! Got him!")
            self.enemy = None





class Corridor(Room):

    def __init__(self):
        self.name = "corridor"
        self.enemy = None


    def enter(self, world, player):

        super(Corridor, self).enter(world, player)
        room = self._ask_question("Which room: bathroom, bedroom ",\
                                      "bedroom", "bathroom", "Library", "study")

        if room == "bedroom":
            return world.bedroom

        if room == "bathroom":
            return world.bathroom




class Bathroom(Room):

    def __init__(self):
        super(Bathroom, self).__init__("bathroom")


    def enter(self, world, player):
        super(Bathroom, self).enter(world, player)



class Bedroom(Room):

    def __init__(self):
        super(Bedroom, self).__init__("bedroom")



class Death(Room):

    def __init__(self):
        super(Death, self).__init__("death")


    def enter(self, world, player):
        time.sleep(1)
        responses = ["Off to the man in sky. You are dead", "You died,\
 no-one cried.", "Lolz. You're dead!"]
        print(random.choice(responses))

        return None



class World(object):

    def __init__(self):

        self.corridor = Corridor()
        self.bathroom = Bathroom()
        self.death = Death()
        self.bedroom = Bedroom()
        self.start = self.corridor



def play_game(world, player):

    room = world.start

    while room:

        room = room.enter(world, player)

play_game(World(), Character("Bob", 12, 2))

I know I must be missing something obvious.

Thanks, Dave.

Upvotes: 0

Views: 37

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121186

You forgot to return the result of the super().enter() call. You are swallowing the return value, so you never returned the new room. The following would be correct:

class Bathroom(Room):
    def enter(self, world, player):
        return super(Bathroom, self).enter(world, player)

Not that there is a point in defining a new Bathroom().enter() method if all you do is call the original version with super(). You may as well remove the whole enter() method (as I've done for the __init__ method, above).

Upvotes: 2

Related Questions