如何创建使用def函数作为条件的多个if语句,而不让def函数重复其条件

2024-09-26 22:43:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在创建一个游戏,其中一个老板(Suru)根据用户输入的内容采取不同的行动。用户输入是在类(Player)中的def()函数中创建的,必须使用returns将结果传递给主def()函数(boss\u battle)。但是,每当我尝试使用if代码来设置battle函数的条件时,用户输入就会自动重复,直到if语句的最后一行。你知道吗

以下是导致问题的if代码:

if player.attack(boss)== 'mercy':
            kind = True
            break
        #If the player input returns 'mercy' then the battle will stop
        #However the results don't show as the code moves on to repeat itself in the next line

        elif player.attack(boss) in ('heal, no_mercy'):
           pass
         #If the player chooses to heal or fails to give mercy then the battle will continue as normal, however Suru won't be able to attack the player that turn
         #The same happens with this line

        elif player.attack(boss)==('attack'):
            wait = 'no'
        #If the player chooses to fight then the battle will commence as normal, however Suru will no be able to attack throughout the rest of the battle
        #This line prints out the results but the results end up being inaccurate as 'mercy' or 'heal' aren't taken into effect

不管用户输入什么(代码返回什么)都会影响苏鲁的行为:“治疗”和“不怜悯”会让他等待(在那个回合不攻击),“怜悯”会让战斗结束,“攻击”会让苏鲁攻击玩家(并在战斗的剩余时间继续这样做)。 然而,它所做的是重复玩家输入3次,只考虑第三次输入。这会导致代码不准确,因为第三次输入满足的条件只适用于攻击(允许苏鲁攻击玩家),而不适用于仁慈或治疗/不仁慈。 请记住,即使为语句输入了正确的条件,代码也会继续遍历每个if语句(导致用户输入需要3次而不是1次)。你知道吗

下面是一个示例代码,如果需要可以运行,同时解释代码的基础和我试图实现的目标。你知道吗

class Character:
#Creates the base for the Player and the enemy setup

    def __init__(self, health, power, speed, core, max_health):

        self.health = health
        self.power = power
        self.speed = speed
        self.core = core

    def attack(self, other):
        raise NotImplementedError
    #Allows for the enemy_attack and attack_enemy methods (functions) to be placed into separate classes
    #Allows for the player and enemy to be able to attack each other

class Player(Character):
#Creates Data and stats for the Player

def __init__(self, name, health, power, speed, core, max_health, heal, counter, endure):
    super().__init__(health, power, speed, core, max_health)
    #Creates the base for the stats required for the player
    #Super() allows for the parent class in (charecter class) to be called and used to create stats the child class (Player)

    self.name = name
    self.power = power
    self.speed = speed
    self.core = core
    self.max_health = max_health
    self.heal = heal
    self.counter = counter
    self.endure = endure

def attack(self, other):

    action = input("\nWhat move would you like to make (fight, heal or mercy)? ").lower()
    print()
    sleep(1)
    #Asks the user what to do

    if action in ('fight', 'heal', 'mercy'):

        if action == 'heal':

            print("\nYou try to heal your wounds")
            sleep(1)
            self.health += self.heal

            print("You have {0.health} hp.\n".format(self))
            sleep(1)

            return 'heal'
        #Returns that the user has healed that turn and did not attack, allowing wait to remain as 'yes' - unless the user has attacked before


        elif action == 'mercy':
            chance = (random.randint(1, 10))
            response = random.choice(["You tell the {0.name} that you don't want to fight.".format(other),
                                     "You refuse to fight.", "You remain still to show the {0.name} that you don't wan't to fight.",
                                     "You try to give the {0.name} mercy.".format(other)])
            re_response = random.choice(response)
            print(response)
            sleep(1)


            if chance >= other.mercy_count:
                response_fail = random.choice(["But you were unable to convince the {0.name} not to fight.".format(other),
                                             "But the {0.name} didn't believe you.".format(other),
                                             "Yet the {0.name} still wants to fight.".format(other),
                                             "But it didn't work."])
                print(response_fail)
                sleep(1)
                return 'no_mercy'

            elif chance < other.mercy_count:
                response_pass = random.choice(["You were able to convince the {0.name} not to fight.".format(other),
                                             "The {0.name} decided believe you.".format(other),
                                             "As it turns out, the {0.name} didn't want to fight.".format(other),
                                             "It worked."])
                print(response_pass)
                return 'mercy'
                sleep(1)
                #Mercy is based on a selective chance, if the player is able to spare Suru, then it returns 'mercy', causing the battle to end




        elif action == 'fight':
            print("You attack the {0.name}.".format(other))
            other.health -= int(self.power * random.randint(1,3)) 
            sleep(1)
            #other.health = enemy health
            #uses the Player's power to randomly (within reason) generate the damage taken by the enemy
            #Also allows for a way to bypass the problem of not being able to convert player.power to a numeric figure

            return 'attack'
            #Returns attack - stating that the user has chosen to fight - and allows for the code to inishiate Suru's attack pattern

    else:
        print("you stumble...")
        sleep(1)
        #If the entry isn't valid then the message is diplayed and the sequence is conitnued

class Boss(Character):

    def __init__(self, name, health, power, speed, core, max_health, mercy_count):
        super().__init__(health, power, speed, core, max_health)
        self.name = name
        self.power = power
        self.speed = speed
        self.mercy_count = mercy_count
        self.max_health = max_health

    def attack(self, other):

        print("The {0.name} attacks...".format(self))
        sleep(1)
        other.health -= int(self.power * random.randint(1,3)


def boss_battle(player, boss):
#Battle Function

    kind = False
    #variable used for mercy

    wait = 'yes'
    #variable used to determine whether on not Suru is to attack on that turn

    print ("\n{0.name} confronts you!".format(boss))
    sleep(0.5)
    print ("{0.name} has {0.health} hp.".format(boss))
    sleep(1)

    print("\nYour stats are: {0.health} hp {0.power} atk {0.speed} spd\n".format(player))
    sleep(0.75)

    while player.health > 0 and boss.health > 0:
    #Loop runs while both the player and Suru have hp left  

    #The following if code sparks the requested problem
        if player.speed >= boss.speed:
        #If the player's speed is greater than the bosses

            if player.attack(boss)== 'mercy':
                kind = True
                break
            #If the player input returns 'mercy' then the battle will stop
            #However the results don't show as the code moves on to repeat itself in the next line

            elif player.attack(boss) in ('heal'. 'no_mercy'):
                pass
             #If the player chooses to heal then the battle will continue as normal, however Suru won't be able to attack the player that turn
             #The same happens with this line

            elif player.attack(boss)==('attack'):
                wait = 'no'
            #If the player chooses to fight then the battle will commence as normal, however Suru will no be able to attack throughout the rest of the battle
            #This line prints out the results but the results end up being inaccurate as 'mercy' or 'heal' aren't taken into effect

    #End of problem if code

            if boss.health <= 0:
                break
            #If Suru is dead (health lower than 0) then the battle ends

                print ("{0.name} has {0.health} hp.\n".format(boss))
                #Displays a message telling the user the hp stsatus of the enemy
                sleep(0.5)

            if boss.name == 'Suru':
                if wait == 'yes':
                    b_response = random.choice(["Suru is watching you.", "Suru seems hesitant to strike."])
                    print(b_response)
            #Suru skips it's turn


            else:
                boss.attack(player)
                # Suru attacks the player

            if player.health <= 0:
                break
            #If the player is dead (health lower than 0) then the battle ends


            print("You have {0.health} hp.\n".format(boss))
            sleep(1) 
            #Displays the player's health 

    if kind:
        print("\nYou part ways with {0.name}.\n\n".format(boss))
        sleep(1)

    else:
        if player.health > 0:
            print("\nYou killed {0.name}.".format(boss))
            print()
            sleep(1)

        elif boss.health > 0:

            print("\nThe {0.name} has killed you.".format(boss))
            print()



if __name__ == '__main__':
#Allows for the main script to be run and variables to be created and entered



    players = (Player("Hero", 100, 18, 50, 300, 100, 50, 0, 0))
    #Player list allows for the player to have stats that can be changed

    bosses = [Boss("Feng", 100, 15, 70, 50, 100, 8), Boss("Shen", 150, 15, 80, 100, 150, 5),
              Boss("Suru", 200, 20, 20, 200, 200, 3), Boss ("Mlezi", 45, 10, 60, 0, 45, 6)]

    boss_battle(players, bosses[2])
    #Allows for Suru boss battle

代码显示如下: (不知道如何显示图片,抱歉)

苏鲁面对你! 苏鲁有200马力。你知道吗

你的状态是:100点生命18点50点速度

你想采取什么行动(战斗、治疗或怜悯)?战斗(用户输入)

你攻击苏鲁。你知道吗

你想采取什么行动(战斗、治疗或怜悯)?战斗

(由于if代码的第二行而重复,即使它不应该重复)

你攻击苏鲁。你知道吗

你想采取什么行动(战斗、治疗或怜悯)?治愈

(由于if代码的第三行,它会重复第三次,即使它不应该重复)

你试图治愈你的伤口 你有100点生命。你知道吗

苏鲁有110马力。你知道吗

苏鲁在看着你。 你有110马力。你知道吗

(最终显示结果,但与我最初输入的'fight'一样准确,这会导致Suru攻击';但是,我将最终输入更改为'heal',以显示代码如何不接受第一个输入(即使它应该接受),而只接受第三个输入(尽管第三个和第二个输入不应该存在)

你想采取什么行动(战斗、治疗或怜悯)? (下一个转弯时重复)

我已经尝试过在stackflow和其他网站上研究我的问题,使用诸如“how to check multiple conditions in if statement”之类的短语(因为我认为回答我问题的一种方法是让python检查一行中的条件,限制ELIF和玩家攻击())然而,这只出现了使多个if语句/条件更具视觉吸引力的方法)。我尝试的另一个搜索是“if statement in user defined function”(用户定义函数中的if语句),但没有给出我需要的结果(或发现有用的结果)。你知道吗

我真的很感激任何反馈,不仅是对我的代码(然而这是什么主要解决),而且对我可以改善我的整体代码(不那么重要)的方式任何反馈。你知道吗

提前谢谢


Tags: thetonameselfformatifplayerother
1条回答
网友
1楼 · 发布于 2024-09-26 22:43:31

听起来您只是在问如何在变量中存储值:

attack_result = player.attack(boss)

if attack_result == 'mercy':
    # etc.
elif attack_result in ('heal, no_mercy'):
    # etc.
elif attack_result == 'attack':
    # etc.

这样,我们就不用反复调用player.attack(boss),只需调用一次,然后反复使用结果。你知道吗


正如David在一篇评论中指出的那样,当我们在测试时,in ('heal, no_mercy')可能并没有测试您想要的东西。你知道吗

'heal, no_mercy'是单个字符串。所以('heal, no_mercy')是一个用无意义的括号括起来的字符串。它与('heal', 'no_mercy')非常不同,后者是一对字符串。你知道吗

您所写的内容将对healno_mercy执行子字符串搜索,但对mercyal以及任何其他子字符串也是如此。您可能要将其更改为:

elif attack_result in ('heal', 'no_mercy'):

相关问题 更多 >

    热门问题