Steven Halla
Steven Halla

Reputation: 45

Text based game random battle/hp python 2.7

Hi I'm having a few problems with a text based game (python 2.7). Right now the game only lets me kill one random monster,after that, if I get into another random battle,the monster is already dead and the combat function does not start past a couple of print statements.

I also noticed that after battles, My HP for the hero of the game is refilled to max.

I'm very new to programming so any help would be awesome.

I'm using code from a different game of mine for testing purposes. So story wise this current game will not make any sense.

import random


class Room:
    def __init__(self, name, description, doors, items):
        self.name = name
        self.description = description
        self.doors = doors
        self.items = items


def check(self,item_name): #checks words in a room description
    if not (item_name in self.items):
        print "checked [" + item_name + "], but found nothing "
        return


    else:
        self.items[item_name].check()


class item:
    def check(self):
        print "default check, do nothing"


class Weapon():
    def attack(self,monster):
        pass


class PulseRifle(Weapon):
    def __str__(self,player,damage,ammo):
        self.name = "pulse rifle"
        self.player = player
        self.damage = monster.hp -2
        self.ammo = 7


def bullet(self): # should ammo be a class?
    if ammo > 0:
        "pulse rifle" == True
    if ammo <= 0:
        "pulse rifle" == False



class CombatKnife(Weapon):
    def __init__(self,player):
        self.name = "combat knife"
        self.damage = monster.hp - 1


class Character:
    def __init__(self,hp):
        self.hp = hp

def attack(self, other):
    raise NotImplementedError


class Player(Character):
    def __init__(self):
        self.name = "chad"
        self.hp = 10
        self.x = 0
        self.y = 0
        self.items = {}

def attack(self,other): # lets a player attack, and defines the damage his options do
    answer = input ("what action would you like to pick?")
    if answer.lower() in ("pulse rifle", "combat knife"):
        if answer == "pulse rifle":
            other.hp -= int(2)
        elif answer == "combat knife":
            other.hp -= int(1)


def is_alive(self):
   return self.hp > 0


class Monster(Character): # This is the only enemy you encounter. I want the player to fight 1 on 1 battles.
    def __init__(self):  #Right now if you kill 1 monster, it wont let you engage others in battle.
        self.name = "infested marine"
        self.hp = 3

def attack(self, other):
    print ("the infested marine attacks...".format(self))
    player.hp -= int(1)


def is_alive(self):
    return self.hp > 0


class Prison:
    # This is the main framework of the game
    global battle

    global player
    player = Player()
    global monster
    monster = Monster()

def __init__(self):
    self.hp = int
    self.player = Player()
    self.rooms = []
    self.is_playing = True


def build_rooms(self):



    cell_1 = Room(name="Cell 1",
                  description="The door to your cell is open. There is a bucket of urine and feces in the corner. .",
                  doors={"north": False, "south": False, "west": False, "east": True},
                  items={})
    forced_feeding_room = Room(name="Forced Eating Room",
                               description="There is a chair with straps.  \nIn a corner of the room is a blender with tubes attaced to the top\n" +
                                           "You see hundreds of rats hanging around a stool.\n Stools are great for reaching high places",
                               doors={"north": False, "south": True, "west": True, "east": True},
                               items={})
    hall_1 = Room(name="hall one",
                  description="The lights flicker on and off in the long hall.",
                  doors={"north": False, "south": True, "west": True, "east": True},
                  items={})
    janitor_closet = Room(name="janitor closet",
                          description="There are a lot of cleaning supplies in here. Along with a small  box",
                          doors={"north": False, "south": False, "west": True, "east": False},
                          items={})
    cell2 = Room(name="cell 2",
                 description="A babbling old man begs you to relase him n\ There is a guard with a bite wound on his neck. He is no longer alive.",
                 doors={"north": False, "south": False, "west": False, "east": True},
                 items={})
    needle_room = Room(name="needle room",
                       description="There is a blood stained mattress that is soiled with feces and cum amount other things,why would you want to touch that? \n There is a pile of dirty needles that look useless. \n There is also an old dresser with a red lock",
                       doors={"north": True, "south": True, "west": True, "east": True},
                       items={})
    hall_2 = Room(name="hall 2",
                  description="This hallway is boring",
                  doors={"north": True, "south": True, "west": True, "east": True},
                  items={})
    food_lift = Room(name="food lift",
                     description="The lift wire has  sharp barbs on it,gloves would be nice to have. \n The  lift looks like a small child could fit up there.",
                     doors={"north": False, "south": False, "west": True, "east": False},
                     items={})
    cell3 = Room(name="cell 3",
                 description="The darkness is everywhere in here. You can hear a loud skittering noise in the darkness. If only you had a light source. \n A burnable item,something to hold it,something to ignite it,and some lighter fluid would do the trick",
                 doors={"north": False, "south": False, "west": False, "east": True},
                 items={})
    eat_shit_room = Room(name="eat shit room",
                         description="This room has a man that weighs 700 pounds tied to a chair.\n  A small constant stream of liquid taco bell is going down his throat. Attached to his ass is a tube that ends in a funnel with a head strap",
                         doors={"north": True, "south": True, "west": True, "east": True},
                         items={})
    hall_3 = Room(name="hall3",
                  description="Nothing to do but walk",
                  doors={"north": True, "south": True, "west": True, "east": True},
                  items={})
    generator = Room(name="generator room ",
                     description="There is a sign that reads. \n use the station here to test oil before pouring. check the oil. \n There is a small red key on the floor",
                     doors={"north": False, "south": False, "west": True, "east": False},
                     items={ })
    cell4 = Room(name="cell4",
                 description=" There is a dead naked prison guard in a tiny cage. n\ next to the cage is  a pile of clothes ",
                 doors={"north": False, "south": False, "west": False, "east": True},
                 items={})
    pinata_room = Room(name="pinata room",
                       description="There are several dead men in here,each of which is hanging by his feet. one of the dead men has a pair of thick gloves. Each of the bodies is covered in deep bruises \n There is a shelf that is too high for you to reach without a stool.",
                       doors={"north": True, "south": False, "east": True, "west": True},
                       items={})
    hall_4 = Room(name="hall4",
                  description="There is a door to the east with a key card reader.",
                  doors={"north": True, "south": False, "west": True, "east": False},
                  items={})
    storage_room = Room(name="storage room",
                        description="A room with blankets and pillows. None of which the prisoners ever get to use. There is a ladder that leads up, and a hole that you can squeeze through.",
                        doors={"north": False, "south": False, "west": True, "east": False},
                        items={}
                        )


    self.rooms = [ #an array of rooms this is how you move about the prison
                [cell_1, forced_feeding_room, hall_1, janitor_closet],
                [cell2, needle_room, hall_2, food_lift],
                [cell3, eat_shit_room, hall_3, generator],
                [cell4, pinata_room, hall_4, storage_room]
            ]


def new_game(self):
    self.player = Player()

    self.player.y = 0
    self.player.x = 0

    self.build_rooms()
    self.is_playing = True
    print "starting game"


def battle(self):
    # this is what i use for random monster battles
    print "an infested marine appears"
    print "type pulse rifle or battle knife in parenthesis"


    while player.hp > 0 and monster.hp > 0:
        player.attack(monster)
        print ("the health of the monster is now {0.hp}.".format(monster))
        if monster.hp <= 0:
            break
        monster.attack(player)
        print ("your hp is now{0.hp}.".format(player))
    if player.hp > 0:
        print ("you killed the infested marine")
    elif monster.hp > 0:
        print ("the infested marine killed you.".format(monster))
        exit()


def describe_room(self):
    print self.get_current_room().description


def print_room_name(self):
    print "you are in the " + self.get_current_room().name


def get_current_room(self):
    return self.rooms[self.player.y][self.player.x]


def handle_input(self):
    input = raw_input("enter a commmand")


    if input == "help" or input == "h":
        self.help()


    elif input == "me" or input == "m": # this is a check to see your current stats. When I do this check, I notice my HP goes back to max after a battle is over.
        print "HP: " + str(self.player.hp)
        print "Your location (" + str(self.player.x) + "," + str(self.player.y) + ")"
        print "Doors:  " + str(self.get_current_room().doors)
        print "Inventory: " + str(self.player.items)

    elif input == "describe" or input == "d":
        self.describe_room()


    elif input == "north" or input == "n":
        global player
        if self.get_current_room().doors["north"]:
            print "Walking North"
            self.player.y -= 1
            animal = random.randint(1,20)
            if animal <= 5: # this is what i use to determine the probablity of a random batttle
                print ("hi")
                battle(self) # starts the battle function
            elif animal >= 6:
                print ("no")


        else:
            print "There is no door in that direction"


    elif input == "south" or input == "s":
        if self.get_current_room().doors["south"]:
            global player
            print "Walking South"
            self.player.y += 1
            animal = random.randint(1,20)
            if animal <= 5: # this is what i use to determine the probablity of a random batttle
                print ("hi")
            elif animal >= 6:
                battle(self) # starts the battle function
                print ("no")


        else:
            print "you try going south......there is no door"


    elif input == "west" or input == "w":
        if self.get_current_room().doors["west"]:
            print "Walking West"
            self.player.x -= 1
            animal = random.randint(1,20)
            if animal <= 5: # this is what i use to determine the probablity of a random batttle
                print ("hi")
                battle(self) # starts the battle function
            elif animal >= 6:
                print ("no")


        else:
            print "it would be nice to go west. To bad there isn't a door there. pay attention to where your going"


    elif input == "east" or input == "e":
        if self.get_current_room().doors["east"]:
            print "Walking East"
            self.player.x += 1
            animal = random.randint(1,6)
            if animal <= 5: # this is what i use to determine the probablity of a random batttle
                print ("hi")
                battle(self)# starts the battle function
            elif animal >= 6:
                print ("no")


        else:
            print "you try going east but you run right into a wall."


    elif input.startswith("check ") or input.startswith("c "): # checks items in a room
        pieces = input.split(" ")
        item_name = pieces[1]
        self.get_current_room().check(item_name)


    elif input.startswith("use ") or input.startswith("u "): # command to use items that are in your inventory
        pieces = input.split(" ")
        item_name = pieces[1]
        if item_name in self.player.items:


            if isinstance(self.player.items[item_name], UsableItem): #this is code to use an usable item. 
                self.player.items[item_name].use(self.player)
                del self.player.items[item_name]


            else:
                print "The item [" + item_name + "] is not usable."


        else:
            print "The item [" + item_name + "] is not in your inventory."


    elif input == "exit":
        self.is_playing = False


    else:
        print "Unknown command [" + input + "] "
        self.help()


def help(self): # this prints when an invalid command is inputted
    print "bad command.  Check an item, use an item, or check your environment.??"


def play(self):# starts a new game
    self.new_game()
    print "Type m to check your stats, type  d for room descriptions."
    print "The  command check. Check your environment, or you can check an item. The use command is for medkits "

    while self.is_playing:
        self.print_room_name()
        self.handle_input()


        if not self.player.is_alive():
            print "you are dead"
            self.is_playing = False


    print "game over try again"
    exit()


prison = Prison()
prison.play()

Upvotes: 1

Views: 1065

Answers (1)

GantTheWanderer
GantTheWanderer

Reputation: 1292

1) Why is the monster dead

If you look at where the monster is defined:

class Prison:
    # This is the main framework of the game
    global battle

    global player
    player = Player()
    global monster
    monster = Monster() # <-- one monster created here, line is only executed once (definition of class, instantiation of static variable)

Notice that this is the only place where a Monster is created (calling Monster()) in the whole file and its in an area that is only executed once ever when this script runs. This means that there is only one Monster for the whole game.

Knowing that there is only one monster, AND the monster's hp is never set back to full in the file (look for monster.hp), consider the following code:

def battle(self):
    # this is what i use for random monster battles
    print "an infested marine appears"
    print "type pulse rifle or battle knife in parenthesis"

    # monster = Monster() - Try this for a new monster each battle

    while player.hp > 0 and monster.hp > 0:
        player.attack(monster)
        print ("the health of the monster is now {0.hp}.".format(monster))
        if monster.hp <= 0:
            break
        monster.attack(player)
        print ("your hp is now{0.hp}.".format(player))
    if player.hp > 0:
        print ("you killed the infested marine")
    elif monster.hp > 0:
        print ("the infested marine killed you.".format(monster))
        exit()

The first battle runs fine. The next battle the monster is dead... because its the same monster as last battle! Remember, this code refers to one global monster defined. Uncomment the line added above and the monster will be new each fight.

2) HP Seems to be maxed out after each battle

Lets see where the player's hp is affected:

def attack(self, other):
    print ("the infested marine attacks...".format(self))
    player.hp -= int(1)

where is it displayed:

        print "HP: " + str(self.player.hp)

Notice that the first case refers to player.hp and the other self.player.hp. SO? Whats the difference? Consider the following code:

class Prison:

    # This is the main framework of the game
    global battle

    global player
    player = Player() # 1) <-- One global player that exists no matter how many Prisons there are!
    global monster
    monster = Monster()

def __init__(self):
    self.hp = int
    self.player = Player() # 2) <-- A player that exists PER Prison!
    self.rooms = []
    self.is_playing = True

Notice that there are at least 2 players in the game, see where Player() occurs above. One is a global player that exists throughout all Prisons ever, and there is only one and ever only one of them! The other is a self.player that exists per Prison that you create. That means each time you call Prison(), the __init__ function runs and creates a new Player for that game, which is NOT THE SAME as the previous one.

The issue is that when the battle is happening, the one global player.hp is affected. But when you check your HP, the other self.player in this Prison game is checked and that guys is always healthy, he never has to fight! LAZY! Try affecting other which is passed into the attack function instead.

Note that if you change these global references, other parts of the code probably need to get checked too! Try not to use global stuff unless it makes the most sense! Should there be one global monster? Or should monsters exist per battle?

Upvotes: 2

Related Questions