Словарь Python, вложенный в метод, автоматически выполняет все значения (методы) при вызове внешнего метода - PullRequest
0 голосов
/ 21 января 2019

Я работаю над простым каркасом для игры, и, пытаясь быть более "питоническим", я использую объекты / классы / словари, чтобы попытаться захватить все мои действия / поведение (как методы над функции и т. д.).

По какой-то причине, каждый раз, когда я выполняю метод act в классе «Player», словарь, встроенный в act, запускает все его значения (которые, в свою очередь, являются методами из одного экземпляра класса) Игрок "). Другими словами, игрок выбирает «атака, исцеление и бегство» каждый раз, все сразу, до того, как его попросят.

Я уверен, что есть простое объяснение, но я искал часы и не могу найти другой пример чьего-то словаря, автоматически запускающего все встроенные в него методы. Вы можете помочь?

Спасибо! - Джейк

from random import randint

### BEGIN ALL CLASSES HERE

# To be used for all game objects (living and non-living)
class gameObject(object):
    def __init__(self, name):
        self.name = name

# To be used for all characters who can act in some way/be killed/change
class livingThing(gameObject):
    def __init__(self, name, HP=1):
        self.name = name
        self.HP = HP

# The playable character(s)
class Player(livingThing):

    def __init__(self,name="The Stranger", HP=4, MP=5, strength=1, intellect=1, spirit=1, luck=5, gil=6):
        self.name = name
        self.HP = HP
        self.MP = MP
        self.gil = gil
        self.strength = strength
        self.intellect = intellect
        self.spirit = spirit
        self.luck = luck

    def act(player, enemy):
        actions = {
        "attack" : player.attack(enemy), 
        "heal" : player.heal(enemy), 
        "flee" : player.flee()
        }
        #Takes input from the player

        decision = input("What would you like to do? ")

        if decision.lower() in actions:
            actions[decision.lower()]
        else:
            print("That didn't work!  Try again.")

    # Prints both player and enemy HP
    def printHP(player, enemy):
        print("{0}'s' HP: {1} \n{2}'s HP: {3}".format(player.name, player.HP, enemy.name, enemy.HP))

    # Allows the player to attack an enemy (currently functional)
    def attack(player, enemy):
        enemy.HP -= player.strength
        print("You strike {0} for {1} damage!".format(enemy.name, player.strength))
        player.printHP(enemy)

    # Allows the player to heal a certain amount of health based on its "spirit" stat (currently functional)
    def heal(player, enemy):
        healed = randint(0, player.spirit)
        player.HP += healed
        print("You've healed for {0}!".format(healed))
        player.printHP(enemy)

    #Allows the player to attempt to run away
    def flee(player):
        randluck = randint(0, player.luck)
        if randluck > 3:
            print("You successfully escaped!")
            return player.HP
        else:
            print("You weren't able to escape!")


# Anything that can act with/against the player
class Actor(livingThing):
    def __init__(self, name="Unknown Entity", HP=10, MP=2, gil=3):
        self. name = name
        self.HP = HP
        self.MP = MP
        self.gil = gil

### END ALL CLASSES ###


### DICTIONARIES CONTAINING ACTIONS ###



### CHARACTERS ###

fighter = Player()

monster = Actor()




fighter.act(monster)

1 Ответ

0 голосов
/ 21 января 2019

Я вижу проблему. Когда вы выполняете код Python и у вас есть словарь, Python оценивает словарь полностью. Если вы хотите, чтобы ваши пары значений (в ключе: значение) были результатами этих методов, это, безусловно, один из способов сделать это.

В вашем случае вы можете ссылаться на саму функцию , а не вызывать ее. Вы можете сделать это, избавившись от скобок, например:

player.attack

вместо

player.attack()

Затем для вызова функции вы можете сделать что-то вроде

actions[decision.lower()](enemy)

Поскольку одна из ваших функций, flee , не принимает никаких параметров, вы можете задать flee параметр, который вы просто не используете в функции. Если вы разрабатываете много методов, с которыми ваш игрок может действовать , то одной стратегией будет дать им всем только именованные параметры, например:

def f1(enemy=None,something=None,foo=None):
    if enemy is None:
         raise Exception("enemy cannot be None")
    #process_enemy

Если, однако, у вас также есть очень большое количество параметров, то вы можете сделать это:

def attack(**kwargs):
    #kwargs is a dictionary of parameters provided to the function
    enemy = kwargs.get('enemy',None)
    if enemy is None:
        raise Exception("enemy cannot be None")

def eat(**kwargs):
    food = kwargs.get('food',None)
    if enemy is None:
        raise Exception("food cannot be None")

attack(enemy="someenemyobject")
eat(food="somefoodobject")

attack()                        # raises Exception
attack(food="somefoodobject")   # raises Exception
food(enemy="someenemyobject")   # raises Exception
food(food="somefoodobject",enemy="someenemyobject") # does not raise Exception
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...