Python Forum
Thread Rating:
  • 2 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
RPG game trouble
#1
Hi, 

I'm a bit out of my depth here, but suppose that's the best way to learn. I'm trying to create an RPG game where a hero goes against 6 enemies in 6 different lairs (each lair will be represented by a function).

Each lair has a particular enemy, who can be defeated only by choosing the correct weapon. The option to choose a weapon and fight only becomes available once you answer a question right. 

At the moment, I'm using a particular lair (home()) as the starting point, and then writing in a set path through the lairs by calling different lair functions in sequence. 

At the moment, it's early days, but I'm stuck on the def battle function. I want the player to select the correct weapon for that particular enemy (in this case it's 'money' for the enemy 'wife'). I then want a method of checking that the selection is correct or not (by checking the key value in the hero_weapon dict). In this instance, I've set lair_enemy on line 135 to 'wife'. I suppose there'll be a similar line for each subsequent lair which sets the value.

When I run it, I get the following error:

NameError: global name 'lair_enemy' is not defined

I guess that makes sense since it was defined in a previous function and is not global. I want to change this variable as you progress through the game. What would be the best way of comparing the selected weapon with the correct weapon listed in the dictionary? If I am approaching this wrong, can you suggest a different way of accomplishing this?

Thanks,

import random

class Character(object):
    def __init__(self, name, health):
        self.name = ""
        self.health = health

class Hero(Character):
    def __init__(self):
        super().__init__(name=player_name, health=3)

    #def attack(self, enemy):
    #    strike = enemy.health - 1
    #    miss = enemy.health - 0


    hero_weapon = {
        'wife':'money', 'jiminy_cricket':'slap', 'beer_monster':'drunk_fans',
        'gossip_auntie':'gossip', 'clubber_lang':'hannibal_impression',
        'friend':'snack'
        }

    hero_defence = {
        'wife':'ear_muffler', 'jiminy_cricket':'brakes', 'beer_monster':'recycle_bin',
        'gossip_auntie':'phone_jammer', 'clubber_lang':'shield', 'friend':'nose_peg'
        }

class Enemy(Character):
    def __init__(self):
        super().__init__(name=enemy.name, health = 2)

    enemy_lair = {
        'home':'wife', 'car':'jiminy_cricket', 'pub':'beer_monster',
        'off_license':'gossip_auntie', 'club':'clubber_lang',
        'friend_house':'friend'
        }

    enemy_weapon = {
        'wife':'banshee_scream', 'jiminy_cricket':'hypnosis',
        'beer_monster':'beer_can', 'gossip_auntie':'mobile',
        'clubber_lang':'punch', 'friend':'smoke'
        }

def intro():
    player_name = raw_input("What is your name? ")


    #player = Hero()

    ##player_name = self.hero.name
    print
    print """After getting the sack from your incompetent boss, you would like
          \rnothing better than a nice refreshing, take-the-edge-off alcoholic
          \rbeverage. From there, complete and utter inebriation is likely a
          \rforegone conclusion. BUT... when you get home you soon find out that
          \ryou are all out of beer... all out of vodka... all out of wine...
          \rall out of whisky!"""
    print

    print """Your mission, %s, is to spend the immediate future procuring alcohol
          \ras quickly as possible. Good luck.""" % player_name

    return home()


questions = {
 'What are the 2 ingredients of Cointreau? Alphabetize and separate by comma.':
 'Brandy, orange',
 'The ingredients of Sex on the Beach are? Alphabetize & separate by comma.':
 'cranberry juice, grapefruit juice, peach schnapps, vodka',
 'The ingredients of Tequila Sunrise are? Alphabetize and separate by comma.':
 'grenadine syrup, orange juice, tequila',
 'What country do you associate with Cognac?':'france',
 'What country do you associate with Sangria?':'spain',
 'What country do you associate with Rioja?':'spain',
 'What country do you associate with Sake?':'japan',
 'What brand has the slogan Probably the best lager in the world?':'carlsberg',
 'What brand has the slogan Reassuringly expensive?':'stella artois',
 'What brand has the slogan Good things come to those who wait?':'guinness',
 'What brand has the slogan Reaches the parts other beers cannot?':'heinneken',
 'What brand has the slogan Amber nectar?':'fosters',
 'What is considered to be the oldest alcoholic drink?':'mead',
 'Who is the Greek god of wine?':'dionysus',
 'Who is the Roman god of wine?':'bacchus',
 'What is the literal translation of whisky?':'water of life',
 'What is the literal translation of vodka?':'little water',
 'What do the initials ABV stand for?':'alcohol by volume',
 'Who said I drink to keep body and soul apart?':'oscar wilde',
 'At 1 time, brandy was used in thermometers instead of mercury. True or False?':
 'true',
 'At 1 time, whisky was used in thermometers instead of mercury. True or False?':
 'false',
 'The avg # of grapes needed to produce a bottle of wine is 600. True or False?':
 'true',
 'What language does the word Alcohol derive from?':'arabic',
 'What is added to an alcoholic drink when it is ordered neat?':'nothing',
 'What Greek drink is flavoured with Anise?':'ouzo',
 'What beer does Homer drink?':'duff',
 'What is James Bonds drink of choice?':'vodka martini',
 'What is added to an alcoholic drink when it is ordered on the rocks?':'ice'
}

def question():

    asked_question = random.choice(questions.keys())
    answer = questions[asked_question]
    response = raw_input("Question: %r " % asked_question).lower()
    print

    if response == answer:
        print "Correct! Well done."
        battle()
    else:
        print "Incorrect!"


def battle():
    #current_enemy = self.enemy.enemy_lair[lair]

    weapon_choice = raw_input("Choose your weapon: %s\n" % Hero.hero_weapon.values())

    if weapon_choice == Hero.hero_weapon[lair_enemy]:
        print "good"




def home():
    print """Now that you're finally home, you rake through the cupboards Like
    \ra feind, tossing things messily here and there. Your missus then walks in
    \rand asks you what's up. "You got fired?!" she bellows. There's one last
    \rcupboard that you have't rummaged through, but your beast of a wife is
    \rguarding it like a possessed, bat-shit she-devil. You must defeat her!"""

    lair_enemy = 'wife'

    question()



intro()
#game = hero()
#question()
Reply
#2
Variables have scope. Within the scope of the battle function, you have not defined lair_enemy. The best way to do this is to pass a parameter to the function:
def test(arg):
    print(arg)
test(801)
Now, you define lair_enemy in your home function, so you will need to pass it as a parameter to the question function, and then have the question function pass it to the battle function. For more details, check out the function tutorial in my signature below.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Thanks Craig. I added an argument to each function, and that did the trick.

I'm now having trouble with the instantiation of the objects.

Initially, I got the following error:

Traceback (most recent call last):
 File "drank_game.py", line 142, in <module>
   player = Hero()
 File "drank_game.py", line 12, in __init__
   super().__init__(name=player_name, health=3)
TypeError: super() takes at least 1 argument (0 given)

I did a little research, and am I right in thinking that the use of super() without arguments is only for Python3? I'm using Python 2.

If so, I tried changing it up:

class Character(object):
   def __init__(self, name, health):
       self.name = ""
       self.health = health

class Hero(Character):
   def __init__(self):
       super(name=player_name, health=3).__init__()
This gave me an error that player_name is not defined, which makes sense. What would be the cleanest way to setup the child class Hero to inherit from the parent Character using the super? Or, is using super in this case redundant? I'm trying to have it so the 'name' attribute is the same as the 'player_name' variable defined within the intro function.
Reply
#4
I always do super with explicit arguments (the current class, and the instance):
class Hero(Character):
    def __init__(self):
        super(Hero, self).__init__(name = player_name, health = 3)
If that's all you're doing in Hero's __init__, you don't need that. Since Hero is a subclass of Character, Hero.__init__ defaults to Charater.__init__, unless you override it.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#5
I also have the enemy class which inherits from the Character class as well, so wanted to differentiate between the two.
 
In this case, as both the Enemy and Hero class will have different health attributes, and the hero's name will be fetched from the player_name variable, would it be best to keep the super() to override the parent?
 
If I stick with it, I'm still getting the player_name variable not being defined within:
super(Hero, self).__init__(name=player_name, health=3)

Any idea why?
 
I thought maybe it's related to the order of the code (classes using player_name coming before it is defined within intro()), so split up the classes into another file and imported it into the main game script.
 
But, I then get an error that the name Hero is not defined. I added the following lines right at the end of the originally attached script just to get things started...



player = Hero()
villain = Enemy()
intro()
Really appreciate your continued help with this. Thanks.
Reply
#6
(Apr-20-2017, 10:25 AM)J125 Wrote: Really appreciate your continued help with this. Thanks.

You can show the level of appreciation by following ichabod801's actual advise from above. You were informed about scope and recommended to check his tutorials in signature. Both things will help you understand better how to wield your functions and classes to reach your end goal, the RPG and learning python.
Reply
#7
Yes, I have read the tutorials. I understand the logic of where I am going wrong, but I can't implement a workaround.

Not to worry, I'll keep at it.

Thanks,
Reply
#8
Quote:
class Hero(Character):
    def __init__(self):
        super().__init__(name=player_name, health=3)

class Enemy(Character):
    def __init__(self):
        super().__init__(name=enemy.name, health = 2)

player_name and enemy.name don't exist yet, so they can't be used as default values for the variables.  But since you always name them anyway, you don't need defaults.  So just getting rid of that bit would solve that particular issue.

ie:
class Hero(Character):
   def __init__(self, name, health=3):
       super().__init__(name, health)

class Enemy(Character):
   def __init__(self, name, health=2):
       super().__init__(name, health)
Reply
#9
Great, thanks Nilamo.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020