0

Hey so I'm making an RPG text game and I've run into a problem for making armor increase the player's max-health. I have attempted to use definitions to achieve this and now the @property, both have left me unsuccessful. Attached is my entire code feel free to run it yourself. No trackback error occurs, but it seems like the modifier is not modifying my variable (self.maxhealth). To clarify, the area we are looking at is under the "Defense Modifiers." If you find anything confusing please ask away so we can resolve this issue. Thanks Mates!

import sys 
import os
import random
import pickle
import time

## Weapons
weapon1 = {"long sword":10}
weapon2 = {"great sword":40}

## Armor
armor1 = {"leather armor":20}

## Potions
healthpot = {"health potion": 10}

# User Statistics
class Player:
    def __init__(self, name):
        self.name = name
        self.exp = 100
        self.maxhealth = 100
        self.health = self.maxhealth
        self.base_attack = 10
        self.gold = 100
        self.pots_health = 0
        self.weap = ["rusty sword"]
        self.curweap = "rusty sword"
        self.arm = ["common clothes"]
        self.curarm = "common clothes"


# Attack Modifiers
    @property 
    def attack(self):
        attack = self.base_attack
        if self.curweap == "rusty sword":
            attack += 0

        if self.curweap == "long sword":
            attack += 10

        if self.curweap == "great sword":
            attack += 20

        return attack

# Defense Modifiers
    @property
    def armor(self):
        armor = self.maxhealth
        if self.curarm == "common clothes":
            armor += 0

        if self.curarm == "leather armor":
            armor += 25

        return armor

# Monsters
class Goblin:
    def __init__(self, name):
        self.name = name
        self.maxhealth = 30
        self.health = self.maxhealth
        self.attack = random.randint(3,8)
        self.goldgain = random.randint(5,10)
        self.expgain = random.randint(9,15)
#GoblinIG = Goblin("Goblin")

class Skeleton:
    def __init__(self, name):
        self.name = name
        self.maxhealth = 25
        self.health = self.maxhealth
        self.attack = random.randint(2,7)
        self.goldgain = random.randint(0,10)
        self.expgain = random.randint(5,10)
#SkeletonIG = Skeleton("Skeleton")

class Colbolt:
    def __init__(self, name):
        self.name = name
        self.maxhealth = 50
        self.health = self.maxhealth
        self.attack = random.randint(7,15)
        self.goldgain = random.randint(10,20)
        self.expgain = random.randint(9,20)
#ColboltIG = Colbolt("Colbolt")

# Functions

# Start Up Prompt
def main():
    os.system('clear')
    print ("Text RPG game.\nCreated on July 24, 2018.\n\n")
    print ("--------------\nKINDRED DEMONS\n--------------\n")
    print ("Select an option\n")
    print ("1.) Start")
    print ("2.) Load")
    print ("3.) Exit")
    raw_input = input (">>> ")
    option = raw_input
    if option == "start":
        start()
    elif option == "load":
        if os.path.exists("savefile") == True:
            os.system('clear')
            with open('savefile', 'rb') as f:
                global PlayerIG
                PlayerIG = pickle.load(f)
            loadtext = 'Loaded Save State...\n\n'
            for char in loadtext:
                sys.stdout.write(char)
                sys.stdout.flush()
                time.sleep(0.1)
            option = raw_input
            start1()
        else:
            print ("You have no save file for this game.")
            option = raw_input
            main()
    elif option == "exit":
        sys.exit()
    else:
        print ("Error 404: Unknown command")
        main()

# Goining User Infomation
def start():
    os.system('clear')
    print ("Hello, what is your name?")
    raw_input = input (">>> ")
    option = raw_input
    global PlayerIG
    PlayerIG = Player(option)
    startintro()
    start1()

# Starting Introduction
def startintro():
    os.system('clear')
    intro1 = '"There was once a time where demons and angels roamed the same plains. It was not until Barook, the King of the Chaos Rift, returned.\nBarook wielded the Great Staff, Jungik, which supposedly only a True King could wield. The Legends are told that it was Barook who was the one to split the plains in two:\nTHE ARCH PLAIN and ETERNAL DEPTHS PLAIN.\nChaos broke out as the wingless demons fell into the eternal depths plain, unable to return.\nIt is said that there once was a powerful demon, capable of contesting anything that stood in his way. It is said that he was cloaked in the Wings of Darkness.\nallowing him to soar through the Arch Plains."'
    intro2 = '\nThe old man paused.''\n"I seem to be forgetting the name of the demon. Ah yes it was..."'
    intro3 = '\n"%s!" \n"It is time."\n\n' % PlayerIG.name
    for char in intro1:
        sys.stdout.write(char)
        sys.stdout.flush()
        time.sleep(0.009)
    for char in intro2:
            sys.stdout.write(char)
            sys.stdout.flush()
            time.sleep(0.01)
    for char in intro3:
            sys.stdout.write(char)
            sys.stdout.flush()
            time.sleep(0.1)


# Main Page - What The User Chooses To Do
def start1():
    os.system('clear')
    print ("Name: %s" % PlayerIG.name)
    print ("Experience: %i" % PlayerIG.exp)
    print ("Attack: %i" % PlayerIG.attack)
    print ("Gold: %d" % PlayerIG.gold)
    print ("Current Weapon: %s" % PlayerIG.curweap)
    print ("Current Armor: %s" % PlayerIG.curarm)
    print ("Health Potions: %d" % PlayerIG.pots_health)
    print ("Health: %i/%i\n" % (PlayerIG.health, PlayerIG.maxhealth))
    print ("1.) Fight")
    print ("2.) Drink Health Potion")
    print ("3.) Shop")
    print ("4.) Inventory")
    print ("5.) Save")
    print ("6.) Exit")
    os.system('clear')
    raw_input = input (">>> ")
    option = raw_input
    if option == "fight":
        os.system('clear')
        prefight()
    elif option == "shop":
        shop()
    elif option == "drink health potion":
        drinkpot_health_startpage()
    elif option == "drink health":
        drinkpot_health_startpage()
    elif option == "health potion":
        drinkpot_health_startpage()
    elif option == "save":
        os.system('clear')
        with open('savefile', 'wb') as f:
            pickle.dump(PlayerIG, f)
            print ("\nGame has been saved!\n")
        option = raw_input
        start1()
    elif option == "exit":
        sys.exit()
    elif option == "inventory":
        inventory()
    else:
        print ("\n")
        start1()

# Accessing The Inventory Of The User
def inventory():
    os.system('clear')
    print ("What do you want to do?")
    print ("1.) Equip Weapon")
    print ("2.) Equip Armor")
    print ("3.) Exit")
    raw_input = input (">>> ")
    option = raw_input
    if option == "equip weapon":
        equip_weapon()
    if option == "equip armor":
        equip_armor()
    elif option == "exit":
        start1()
    else:
        os.system('clear')
        print ("Error 404: Unknown Command\n")
        inventory()

# Equiping Weapons
def equip_weapon():
    os.system('clear')
    print ("What do you want to equip?\n")
    for weapon in PlayerIG.weap:
        print (weapon.title())
    print ("Back")
    print ("Exit")
    raw_input = input (">>> ")
    option = raw_input
    if option == PlayerIG.curweap:
        print ("You already have that weapon equipped\n")
        option = raw_input
        equip_weapon()
    elif option == "back":
        inventory()
    elif option == "exit":
        start1()
    elif option in PlayerIG.weap:
        PlayerIG.curweap = option
        print ("You have equipped %s." % option, "\n")
        option = raw_input
        equip_weapon()
    else:
        print ("You don't have %s in your inventory" % option, "\n")
        equip_weapon()

#Equiping Armor
def equip_armor():
    os.system('clear')
    print ("What do you want to equip?\n")
    for armor in PlayerIG.arm:
        print (armor.title())
    print ("Back")
    print ("Exit")
    raw_input = input (">>> ")
    option = raw_input
    if option == PlayerIG.curarm:
        print ("You already have that armor equipped\n")
        option = raw_input
        equip_armor()
    elif option == "back":
        inventory()
    elif option =="exit":
        start1()
    elif option in PlayerIG.arm:
        PlayerIG.curarm = option
        print ("You have equipped %s." % option, "\n")
        option = raw_input
        equip_armor()
    else:
        print ("You dont't have %s in your inventory" % option, "\n")
        equip_armor()

## Deciding Monster Spawn Type
def prefight():
    global enemy
    if PlayerIG.exp <= 50:
        enemynum = random.randint(1, 2)
        if enemynum == 1:
            enemy = Goblin("Goblin")
        if enemynum == 2:
            enemy = Skeleton("Skeleton")
        fight()
    if PlayerIG.exp >= 50 <= 100: 
        enemynum = random.randint(1, 3)
        if enemynum == 1:
            enemy = Goblin("Goblin")
        elif enemynum == 2:
            enemy = Skeleton("Skeleton")
        else:
            enemy = Colbolt("Colbolt")
        fight()

# Determining What The User Wants To Do
def fight():
    os.system('clear')
    print ("%s     vs      %s" % (PlayerIG.name, enemy.name))
    print ("%s's Health: %d/%d    %s's Health: %i/%i" % (PlayerIG.name, PlayerIG.health, PlayerIG.maxhealth, enemy.name, enemy.health, enemy.maxhealth))
    print ("Health Potions %i\n" % PlayerIG.pots_health)
    print ("1.) Attack")
    print ("2.) Drink Health Potion")
    print ("3.) Run")
    raw_input = input (">>> ")
    option = raw_input
    if option == "attack":
        os.system('clear')
        attack()
    elif option == "run":
        run()
    elif option == "drink heatlh potion":
        drinkpot_health_fightpage()
    elif option == "drink heatlh":
        drinkpot_health_fightpage()
    elif option == "heatlh potion":
        drinkpot_health_fightpage()
    else:
        print ("What the hell does that mean?")
        fight()

# Calculating Attacking Statistics + Running Fight Outcomes
def attack():
    PAttack = int(random.uniform(PlayerIG.attack // 2, PlayerIG.attack))
    EAttack = int(random.uniform(enemy.attack // 2, enemy.attack))
    if PAttack <= PlayerIG.attack // 2:
        print ("You miss!")
    else:
        enemy.health == PAttack
        print ("You deal %i damage!" % PAttack)
        enemy.health -= PAttack
    if enemy.health <= 1:
        win()
    os.system('clear')
    if EAttack <= enemy.attack // 2:
        print ("The enemy missed!")
    else:
        PlayerIG.health -= EAttack
        print ("The enemy deals %i damage!" % EAttack)
    if PlayerIG.health <= 0:
        dead()
    else:
        fight()

# If The User Drinks Health Potions From 'Start1()'
def drinkpot_health_startpage():
    os.system('clear')
    if PlayerIG.pots_health == 0:
        print ("You don't have any health potions!\n")
        start1()
    else:
        PlayerIG.health += 25
        if PlayerIG.health > PlayerIG.maxhealth:
            PlayerIG.health = PlayerIG.maxhealth
        print ("You drank a health potion!\n")
        PlayerIG.pots_health -= 1
        start1()

# If The User Drinks Health Potions From 'Fight()'
def drinkpot_health_fightpage():
    os.system('clear')
    if PlayerIG.pots_health == 0:
        print ("You don't have any health potions!\n")
        fight()
    else:
        PlayerIG.health += 25
        if PlayerIG.health > PlayerIG.maxhealth:
            PlayerIG.health = PlayerIG.maxhealth
        print ("You drank a health potion!\n")
        PlayerIG.pots_health -= 1
        fight()


# Calcualting And Running Statistics If The User Runs      
def run():
    os.system('clear')
    runnum = random.randint(1, 5)
    if runnum <= 3:
        print ("You have successfully ran away!")
        os.system('clear')
        start1()
    else:
        print ("You failed to get away!")
        os.system('clear')
        EAttack = random.randint(enemy.attack // 2, enemy.attack)
        if EAttack == enemy.attack/2:
            print ("The enemy missed!")
        else:
            PlayerIG.health -= EAttack
            print ("The enemy deals %i damage!" % EAttack)
        fight()
        if PlayerIG.health <= 0:
            dead()
        else:
            fight()

# When User Defeats Monster - Calculates What User Gained
def win():
    os.system('clear')
    enemy.health = enemy.maxhealth
    PlayerIG.gold += enemy.goldgain
    PlayerIG.exp += enemy.expgain
    print ("You have defeated the %s" % enemy.name)
    print ("You gained %i experience points!" % enemy.expgain)
    print ("You found %i gold!" % enemy.goldgain, "\n")
    start1()

# When User Dies
def dead():
    os.system('clear')
    print ("You have died\n")
    restart()

# Prompting User To Restart
def restart():
    os.system('clear')
    print ("Would you like to Restart?")
    raw_input = input (">>> ")
    option = raw_input
    if option == "yes" or "restart":
        text1 = "Restarting"
        for char in text1:
            sys.stdout.write(char)
            sys.stdout.flush()
            time.sleep(0.1)
        text2 = "...\n\n"
        for char in text2:
            sys.stdout.write(char)
            sys.stdout.flush()
            time.sleep(0.7)
        start()
    if option == "no":
        print ("Game Over")

# Accessing The Shop
def shop():
    os.system('clear')
    print ("Rhaast's Weapons Shop\n")
    print ("\nWhat would you like to buy?\n")
    print ("1.) Long Sword 10gp")
    print ("2.) Great Sword 40gp")
    print ("3.) Leather Armor 20gp")
    print ("4.) Health Potion 10gp")
    print ("Back")
    print (" ")
    raw_input = input (">>> ")
    option = raw_input

    if option in weapon1:
        if PlayerIG.gold >= weapon1[option]:
            os.system('clear')
            PlayerIG.gold -= weapon1[option]
            PlayerIG.weap.append(option)
            print ("You have bought %s!" % option, "\n")
            option = raw_input
            shop()
        else:
            os.system('clear')
            print ("You don't have enough gold\n")
            option = raw_input
            shop()

    if option in weapon2:
        if PlayerIG.gold >= weapon2[option]:
            os.system('clear')
            PlayerIG.gold -= weapon2[option]
            PlayerIG.weap.append(option)
            print ("You have bought %s!" % option, "\n")
            option = raw_input
            shop()
        else:
            os.system('clear')
            print ("You don't have enough gold\n")
            option = raw_input
            shop()

    if option in armor1:
        if PlayerIG.gold >= armor1[option]:
            os.system('clear')
            PlayerIG.gold -= armor1[option]
            PlayerIG.arm.append(option)
            print ("You have bought %s!" % option, "\n")
            option = raw_input
            shop()
        else:
            os.system('clear')
            print ("You don't have enough gold\n")
            option = raw_input
            shop()

    if option in healthpot:
        if PlayerIG.gold >= healthpot[option]:
            os.system('clear')
            PlayerIG.gold -= healthpot[option]
            PlayerIG.pots_health += 1
            print("You have bought %s!" % option, "\n")
            option = raw_input
            shop()
        else:
            os.system('clear')
            print ("You don't have enough gold\n")
            option = raw_input
            shop()

    elif option == "back":
        start1()

    else:
        os.system('clear')
        print ("That item does not exist\n")
        option = raw_input
        shop()

##__main__##
main()
Mark D
  • 23
  • 5
  • This is way, way too much code. Please give us a [mcve] that demonstrates just the bit you're having trouble with, not your entire program. – abarnert Aug 18 '18 at 03:51

1 Answers1

0

While I agree with abarnert's comment, and it would have been a good idea to strip out all of the rest of the game, I got interested in learning a thing or two about python, and thought that tinkering with your game would be fun. So I had a look.

I stepped through the relevant code parts using IDLE, and it's clear that your logic is off. You have a global called PlayerIG which is your in-game instance of your Player class. The reason that your weapons properly enhance your attack value is that you refer to the PlayerIG.attack property for the attack value, rather than the PlayerIG.base_attack property.

However, you don't do anything analogous with the armor property that you've set up. You're expecting your PlayerIG.maxhealth property to be augmented by equipping armor, and you haven't done that in your code. Instead, you're setting up an PlayerIG.armor property, setting its value as the augmented maxhealth value, and then not using it, instead using the PlayerIG.maxhealth value which you haven't changed.

If you wanted to use the augmented maximum health value if a user equips armor, you'd have to use the armor property rather than the maxhealth property. Which doesn't make much sense semantically; after all, maximum health isn't armor.

So, I would suggest that you set up your maxhealth property in a manner analogous to your attack property. Start with a base_maxhealth property, rename your armor property to maxhealth, and use the latter in your game calculations.

BobRodes
  • 5,990
  • 2
  • 24
  • 26