Myles Taft
Myles Taft

Reputation: 11

TypeError: player_attack() missing 1 required positional argument: 'self'

I keep on getting this error and I have absolutely no idea why, I have 3 files importing information from each other however this main one only draws information from monster_01.py and its player.py.

TypeError: player_attack() missing 1 required positional argument: 'self'

---main code---

'''Player class
Fall 2014
@author Myles Taft (mbt6)
'''

import random
import monster_01



class Player():

    def __init__(self, strength = 0, player_hp = 0):
        self.strength = 1
        self.player_hp = 100
        print(self.strength, self.player_hp)

    def battle():



        def player_attack(self):
            print('success')
            while self.enemy_hp > 0:
                monster_01()
                self.dice1 = random.randint(1,6)
                self.dice2 = random.randint(1,6)
                self.dice_sum = dice1 + dice2
                self.attack = dice1 + dice2
                self.decide_roll = input('Type "roll" to roll the dice:')
                self.roll = print('First die:' + dice1, 'Second die:' + dice2, 'Sum of dice:' + dice_sum)

                if self.roll == 2 or 4 or 6 :
                    print('Hit!')
                    self.enemy_hp == strength
                    print(enemy_hp)
                elif self.roll == 1 or 3 or 5:
                    print('Miss!')

        def player_block(self):
            self.dice1 = random.randint(1,6)
            self.dice2 = random.randint(1,6)
            self.decide_roll = input('Type "roll" to roll the dice:')
            self.roll = print('First die:' + dice1, 'Second die:' + dice2, 'Sum of dice:' + dice_sum)

            if self.roll == 2 or 4:
                print('Blocked!')
                self.player_hp -= int((enemy_strength)/2)
            if self.roll == 1 or 3:
                self.player_hp -= int(enemy_strength)

        def choice(self):
            get_player_attack(get_player_attack)
            self.player_choice = input('Do you attack or block?') #self.player_hp, self.strength)
            if self.player_choice == 'attack':
                self.player_attack()
            elif self.player_choice == 'block':
                self.player_block()


        def get_player_attack(self):
            player_attack()



        choice(choice)




Player.battle()

I've been up and down this code a hundred times, any help would be much appreciated.

Upvotes: 0

Views: 2638

Answers (2)

user2555451
user2555451

Reputation:

The problem is with your get_player_attack method:

def get_player_attack(self):
    player_attack()

It calls player_attack as if it were a stand-alone function and not another method. But player_attack is a method of the class Player and therefore may only be called on an instance of Player.

The function should be called like:

self.player_attack()

Also, stuff like this:

if self.roll == 2 or 4 or 6 :

is just a problem waiting to happen. It should be written as:

if self.roll in (2, 4, 6):

Otherwise, the condition of the if-statement will be interpreted as:

if (self.roll == 2) or (4) or (6):

which will always evaluate to True. For more information, see How do I test one variable against multiple values?


Finally, you should not be putting all of your methods inside another function named battle. I don't know what you are trying to do here, but method definitions should be just under the class header:

class MyClass:          # Class header
    def method1(self):  # Definition of the first method
        ...

    def method2(self):  # Definition of the next method
        ...
    ...

I really think it would be good for you to read some tutorials on Python classes and OOP. Here are some to get you started:

Upvotes: 5

brycem
brycem

Reputation: 593

It's not clear what you're trying to do within battle(). You haven't defined a self parameter, but neither have you used the @static decorator to indicate you want it to be a static function. You've defined player_attack within battle, so it can't be an instance method. The syntax is incorrect.

If you meant battle() to be an instance method, add a self parameter and provide a method body or pass, then make player_attack de-indented.

Upvotes: 0

Related Questions