Как настроить метод, в котором один из переданных аргументов может не иметь значения? - PullRequest
1 голос
/ 25 мая 2019

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

Проект - игра, над которой я работаю. Этакая игра для двух игроков, представляющая собой очень простую боевую систему в пвп / кости. В этой игре игрок может иметь определенные умения, которые предлагают определенные бонусы для себя, или применять определенные штрафы к противнику. Как только этот навык используется, он не может быть снова использован в той же игре, и навык может быть выбран только во время хода игрока.

Например. Умение «сокрушительный удар» будет применять штраф -1 к следующему броску противника, или умение «Удар титана» будет применять + 50% бонус к урону ИГРОКА. Из-за этого я знаю, что мне нужно убедиться, что метод defineHit для этого игрока принимает ОБА функции «featUsed». Например, если первый игрок решит использовать наносящий удар удар, это, очевидно, ничего не изменит для его немедленной атаки, но повлияет на бросок второго игрока для атаки.

Проблема в том, что умения выбираются на ходу игрока. Естественно, что в начале, когда происходит playerOne, его метод usedFeat будет заполнен соответствующими данными, но метод playerTwo не будет иметь в нем ничего.

У меня есть весь список умений в JSON. Список довольно обширный, но я приведу здесь только биты, относящиеся к примеру. Как вы увидите в JSON, требуется только название умения и «действие». Название - это, очевидно, имя, а «действие» - это числовое значение, используемое для манипулирования бросками игрока каким-либо образом.

Я также включил два соответствующих метода и любые примечания, которые могут помочь.

Подвиг JSON:

    "titan blow": {
      "stat": "strength",
      "desc": "Your next attack deals 50% more damage, can only be used once per fight.",
      "requirements": [13, 10, 0, 0, "greater crushing blow"],
      "status": "active",
      "action": 0.5
    },
    "crippling blow": {
      "stat": "strength",
      "desc": "You strike your opponent with such a force that it hinders their own attempts to strike back, given them a -1 to their next attack.",
      "requirements": [3, 6, 4, 0, "none", 0],
      "status": "active",
      "action": -1
    },
    "improved crippling blow": {
      "stat": "strength",
      "desc": "improves crippling blow to -3 to their next attack.",
      "requirements": [7, 8, 5, 0, "crippling blow"],
      "status": "active",
      "action": -3
    },
    "greater crippling blow": {
      "stat": "strength",
      "desc": "improves crippling blow to -5 to their next attack.",
      "requirements": [9, 9, 6, 0, "improved crippling blow"],
      "status": "active",
      "action": -5

метод, чтобы запросить у игрока умение использовать его (Примечание: featDict извлекается из модуля, который загружает и выгружает умение JSON feat выше. Также обратите внимание, что существует метод с именем pTwoFeatUsed (self), который в основном является именно этим кодом. , только для второго игрока):

   def pOneFeatUsed(self):
        featDict = gameFeats.featDict()[0]
        feat = ""
        while feat != "none":
            feat = input("Do you wish to use a feat? (type full name of feat here, or 'none'): ")
            if feat == 'power attack' or feat == 'combat expertise' or feat == 'defensive fighting' or feat == 'masochist':
                print(feat + " is a passive feat, and will be determined after this.")
            elif feat in self.pOneInfo['feats taken']:
                print(featDict[0][feat]['action'])
                return [feat, featDict[0][feat]['action']]
            elif feat not in self.pOneInfo['feats taken'] and feat != "none":
                print("Either you do not have that feat, or you did not type it correctly")

Точно так же, как метод featUsed, существует метод defineHitPTwo, который по сути является точно таким же кодом, только для атаки playerTwo

   def determineHitPOne(self):
            pOneToHit = self.pOneInfo['hit']
            pTwoAC = self.pTwoInfo['ac']
            for word in self.pOneInfo["feats taken"]:
                if word == "power attack":
                    self.pOnepMod = self.pOnePowerAttack()
                if word == "combat expertise":
                    self.pOnecMod = self.pOneCombatExpertise()
                if word == "defensive fighting":
                    self.pOnedMod = self.pOneDefensiveFighting()
                if word == "masochist":
                    self.pOnemMod = self.pOneMasochist()
            pMod = self.pOnepMod
            cMod = self.pOnecMod
            dMod = self.pOnedMod
            mMod = self.pOnemMod
            pTwodMod = self.pTwodMod
            pTwomMod = self.pTwomMod
            hit = random.randint(1, 20)
            total = int(hit + pOneToHit - pMod + cMod - dMod + mMod)
            print("Roll: " + str(hit) + " Base: " + str(pOneToHit) + " PA: " + str(pMod) + " CE: " + str(cMod) + " DF: " + str(dMod) + " MC: " + str(mMod))
            totalAC = pTwoAC + pTwodMod - pTwomMod
            print("P2 AC: " + str(pTwoAC) + " DF: " + str(pTwodMod) + " MC: " + str(pTwomMod))
            if total >= totalAC:
                print(self.playerOne + " rolled a " + str(total) + " to hit an AC " + str(totalAC) + " and was successful.")
                self.pTwodMod = 0
                self.pTwomMod = 0
                self.determineDamagePOne()
            else:
                print(self.playerTwo + " rolled a " + str(total) + " to hit an AC " + str(totalAC) + " and missed.")
                self.pTwodMod = 0
                self.pTwomMod = 0
                self.scoreboard()

Я пробовал множество вещей. Мне известно о настройке значений по умолчанию для передачи аргументов, но, похоже, это работает только для чего-либо, НО списки и словари. Я пробовал:


   def determineHitPOne(self, pOneFeatUsed = ["none", 0], pTwoFeatUsed = ["none", 0]):

чтобы попытаться назначить список переменных по умолчанию, но 1) насколько я понимаю, это неправильное использование, поскольку данные изменчивы и не дают желаемых результатов? и 2) это даже не вызывает требуемые методы, и если я добавлю метод 'pOneFeatUsed = self.pOneFeatUsed (), он, очевидно, вызовет сам метод и выполнит его, а не присвоит его значения.

Я пробовал нечто, называемое часовым:

def determineHitPOne(self, pOneFeatUsed = None, pTwoFeatUsed = None):
    if pOneFeatUsed is None:
        pOneFeatUsed = ["none", 0]
    if pTwoFeatUsed is None:
        pTwoFeatUsed = ["none", 0]

Но, опять же, я не уверен, как вызвать метод так, чтобы я получил значения, назначенные в нем (если они есть), или назначил значение по умолчанию ["none", 0], если у игрока не было ход еще и нет значений для назначения.

Пожалуйста, запросите дополнительную информацию, если - как я подозреваю - это объяснение ясно, как грязь. Если вам нужна дополнительная информация, я буду рад предоставить ее.

Заранее спасибо.

1 Ответ

1 голос
/ 25 мая 2019

Когда вы определяете метод следующим образом:

def determineHitPOne(self, pOneFeatUsed=None, pTwoFeatUsed=None):

Вы определяете pOneFeatUsed как новую переменную, по существу игнорируя существование метода pOneFeatUsed.Этот синтаксис не будет вызывать метод, который вы хотите, он собирается создать новую переменную с этим именем, а затем либо A) присвоить None, если вы не указали значение для этого аргумента, либо B) назначить любое значениевы предоставили.

Вместо этого вы можете сохранить состояние последнего использованного навыка из другой игры и затем проверить это поле.

def pOneFeatUsed(self):
    featDict = gameFeats.featDict()[0]
    self.p1_last_feat = None
    while self.p1_last_feat is not None:
       self.p1_last_feat = input("Do you wish to use a feat? (type full name of feat here, or 'none'): ")
        if self.p1_last_feat == 'none':
            self.p1_last_feat = None
        elif self.p1_last_feat in ('power attack', 'combat expertise', 'defensive fighting', 'masochist'):
            print(self.p1_last_feat + " is a passive feat, and will be determined after this.")
        elif self.p1_last_feat in self.pOneInfo['feats taken']:
            print(featDict[0][self.p1_last_feat ]['action'])
            return [self.p1_last_feat , featDict[0][self.p1_last_feat ]['action']]
        else self.p1_last_feat not in self.pOneInfo['feats taken']:
            print("Either you do not have that feat, or you did not type it correctly")

Затем, вместо попытки вызвать этот методопять же вы можете просто проверить состояние last_feat

def determineHitPOne(self):
    if self.p1_last_feat is None:
        pOneFeatUsed = ["none", 0]
    if self.p2_last_feat is None:
        pTwoFeatUsed = ["none", 0]

Или вы можете даже явно хранить эти списки, если хотите.Дело в том, что при вызове метода должен быть установлен атрибут, затем вы можете проверить состояние этого атрибута позже.

...