Home > Mobile >  Counting player kills in text rpg python
Counting player kills in text rpg python

Time:09-27

I've been learning Python by doing random projects here and there. My newest project is a simple text roguelike RPG. The player starts with base stats and just has to survive

Players can attack, heal or run. Which for the most part does work, however, I'm trying to display a kill count beside the player name and visible stats(exp and HP). I'm pretty sure my count variable is just misplaced as it resets to 0 after every enemy death. I want this because it SHOULD mimic b_count for boss appearance. My code is as follows:

import random
import math
import time


# Define base character class amd attributes
class Base:
    def __init__(self, name, lvl, max_hp, hp, strength, defense, wpn):
        self.name = name
        self.lvl = lvl
        self.max_hp = max_hp
        self.hp = hp
        self.wpn = wpn
        self.strength = strength
        self.defense = defense


# Set Player class as subclass of base, add exp and lvlUp attributes.
class Player(Base):
    def __init__(self, exp, lvlUp, **kwargs):
        super().__init__(**kwargs)
        self.exp = exp
        self.lvlUp = lvlUp

    # Define LevelUp
    def LevelUp(self):

        while self.exp >= self.lvlUp:
            self.lvl  = 1
            self.exp -= self.exp
            self.lvlUp *= 1.125
            hp_gain = round(self.max_hp * 0.125)
            str_gain = round(self.strength * 0.25)
            dfn_gain = round(self.defense * 0.25)
            self.max_hp *= 1.125
            self.hp == self.max_hp
            self.strength  = str_gain
            self.defense  = dfn_gain
            print("You leveled up and gained {} Hp, {} Strength, and {} Defense. \n You feel rejuvenated".format(hp_gain, str_gain, dfn_gain))

        else:
            pass

    # Define heal
    def heal(self):
        gain = random.randrange(4 , math.ceil(self.max_hp * 0.75), 2)
        if self.hp   gain >= self.max_hp:
            max_gain = self.max_hp - self.hp
            self.hp = self.max_hp
            return max_gain
        else:
            self.hp  = gain
            return gain

    # Define attack
    def attack(self, other):
        # Define damage based on strength and wpn
        dmg = math.floor(random.uniform(self.strength * self.wpn, (self.strength * self.wpn) * 2) - other.defense)
        time.sleep(0.2)
        print("You dealt {} damage".format(dmg))
        other.hp -= dmg
        if other.hp > 0:
            print("{} has {} health remaining".format(other.name, other.hp))
        # Define exp gain and player heal upon enemy death
        else:
            new_exp = random.randrange(2, 16, 2)
            heal = self.heal()
            print(f"You killed {other.name}. You healed {heal} HP and gained {new_exp} Exp")
            self.exp  = new_exp
            self.LevelUp()
            print("Level {}: [{}/{}]".format(self.lvl   1, self.exp, self.lvlUp))


# Set Mob class
class Mob(Base):
    def __init__(self, *args):
        super().__init__(*args)

    # Define Mob attack
    def attack(self, other):
        dmg = math.floor(random.uniform(self.strength * self.wpn, (self.strength * self.wpn) * 2) - other.defense)
        if dmg <= 0:
            dmg = 0
            print("{} dealt {} damage".format(self.name, dmg))

        elif dmg >= other.hp:
            print("{} dealt {} damage and killed you.".format(self.name, dmg))
            other.hp -= dmg

        else:
            other.hp -= dmg
            print("{} dealt {} damage".format(self.name, dmg))
            print("You have {} health remaining".format(other.hp))

#Set Boss class
#NOT DONE
class Boss(Base):
    def __init__(self, *args):
        super().__init__(*args)
        

# Set Player Name
hero_name = input("Enter your name...")

# Define base hero stats
hero = Player(exp=0, lvlUp=32, name=hero_name, lvl=1, max_hp=64, hp=64, strength=8, defense=4, wpn=1.125)

cmdlist = [
    ["a", "attack"],
    ["h", "heal"],
    ["r", "run"]]

# Set mob list
mobs = [
    Mob("Goblin", 1, 16, 16, 4, 2, 1),
    Mob("Wolf", 1, 24, 24, 6, 2, 1),
    Mob("Imp", 1, 16, 16, 4, 2, 1.125),
    Mob("Minotaur", 1, 32, 32, 4, 4, 1.25),
    Mob("Bandit", 1, 24, 24, 8, 4, 1.125),
    Mob("Succubus", 1, 24, 24, 4, 4, 1.25),
    Mob("Gargoyle", 1, 32, 32, 6, 2, 1.25),
    Mob("Bear", 1, 48, 48, 6, 4, 1.375),
    Mob("Chimera", 1, 48, 48, 6, 4, 1.375),
    Mob("Necromancer", 1, 32, 32, 6, 4, 1.5)]

# Set boss list
bosses = [
    Boss("Minotaur", 1, 32, 32, 4, 4, 1.25),
    Boss("Bandit", 1, 24, 24, 8, 4, 1.125),
    Boss("Bear", 1, 48, 48, 6, 4, 1.375),
    Boss("Chimera", 1, 48, 48, 6, 4, 1.375),
    Boss("Necromancer", 1, 32, 32, 6, 4, 1.5)]



# Define battle sequence and count

def battle(player, enemy):
count = 0
       print("A {} charges towards you!".format(enemy.name))
       
       # Allows for attack/run each turn
       while player.hp > 0 and enemy.hp > 0:
            count = 0
            print("[{}] Kills: {}".format(player.name, count))
            print("[HP: {}] [Next Level {}: [{}/{}]".format(player.hp, player.lvl   1, player.exp, player.lvlUp))
        
            command = input("(A)ttack, (H)eal or (R)un? \n")
   
            if command.lower() in cmdlist[0]:
                
                player.attack(enemy)
                print("---------------------")
                time.sleep(.5)
                if enemy.hp <= 0:
                    count  = 1
                    return count
                enemy.attack(player)
                print("---------------------")
                time.sleep(.2)
                        
            elif command.lower() in cmdlist[1]:
                heal = player.heal()
                print("You heal for {} HP".format(heal))
                continue

            elif command.lower() in cmdlist[2]:
                chance = random.randint(1, 20)
                if chance in range(11, 21):
                    print("You got away without a scratch")
                    break
                elif chance in range(1, 10):
                        dmg = round(random.uniform((enemy.strength * enemy.wpn / 4), (enemy.strength * enemy.wpn) / 2))
                        player.hp -= dmg
                        print("You got away, but with minor injuries.[-{} HP] \nYou have {} HP remaining".format(dmg, hero.hp))
                        
                        time.sleep(0.5)
                        break
                

if __name__ == "__main__":
    b_count = 0
    if b_count < 5:
             while hero.hp > 0:
                b_count  =1
                battle(hero, random.choice(mobs))
                
                
             
    elif b_count > 5 and b_count % 3 == 0:
        if b_count % 3 == 0:
            while hero.hp > 0:
                      b_count  =1
                      print("That one looks bigger")
                      
                      battle(hero, random.choice(bosses))
                      
                      
        else:
                   while hero.hp > 0:
                    b_count  =1
                    battle(hero, random.choice(mobs))
                    
                    


CodePudding user response:

Inside the battle function, you're setting the count variable at the beginning of the function, but also resetting it in a loop before it gets displayed.

def battle(player, enemy):
    count = 0
    ...

    # Allows for attack/run each turn
    while player.hp > 0 and enemy.hp > 0:
        count = 0  # remove this line
        print("[{}] Kills: {}".format(player.name, count))

Removing the marked line will display the kills for that battle (the duration of the loop in the battle function). If you want to keep track of the payers kills for the entire game, I'd make the count variable an attribute of the Player class.

One last note, count is not the best variable name here. You're keeping track of several different counts in your game, so each one should have a distinct name that tells you at a glance what it refers to. In this case kill_count would be better.

  • Related