如何使Python函数交替执行

2024-06-01 14:00:37 发布

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

我写了一个简单的游戏程序(两个战士之间的战斗)。每个战士都有名字,100点生命和伤害点列表。你知道吗

目前,这个程序运行良好,但我编写它是为了每次一个战斗机攻击另一个(“悟空”攻击“科南”)。名为startTheFight的函数实现了这一点。你知道吗

悟空攻击空南。。。 悟空攻击空南。。。 悟空攻击空南。。。 ……等等

如何使该函数交替执行,以便我可以看到谁赢了(“悟空”或“河南”)? 另外,当我调用函数upgradeAttack时,它不工作,我不知道为什么 我想要这样的输出:

悟空攻击空南。。。 空南攻击悟空。。。 悟空攻击空南。。。 空南攻击悟空。。。 ... 你知道吗

代码如下:

import random

class Fighters:

    attackUp = 0

    def __init__(self, name):

        self.name = name
        self.health = 100
        self.damage = [5, 10, 15, 20]

    def upgradeAttack(self, attUp):
        self.attackUp = self.attackUp + attUp
        print(self.attackUp)
        return self.attackUp

    def startTheFight(self, otherFighter):

        while otherFighter.health > 0:

            AttactDamage = random.choice(self.damage) + self.attackUp
            otherFighter.health = otherFighter.health - AttactDamage

            if otherFighter.health > 0:

                print("{} attacts {}! Health -{}hp | {}'s Health: {}hp\n".format(self.name, otherFighter.name,
                                                                       AttactDamage,otherFighter.name, otherFighter.health))
            else:

                otherFighter.health = 0
                print("{} attacts {}! Health -{}hp | {}'s Health: {}hp\n".format(self.name, otherFighter.name,
                                                                       AttactDamage,otherFighter.name, otherFighter.health))

        else:
            if otherFighter.health <= 0:

                otherFighter.health = 0
                print("{} killed {}! | {}'s Health: {}hp\n{} wins!\n\n".format(self.name, otherFighter.name,
                                                                       otherFighter.name, otherFighter.health, self.name))

    def __str__(self):

        return "Fighters name: {}\nFighters health: {}hp\n".format(self.name, self.health)


Goku = Fighters("Goku")
Konan = Fighters("Konan")

#print(Goku)
#print(Konan)

Goku.startTheFight(Konan)

Tags: nameselfformatdefhpprinthealthgoku
2条回答

还有几个建议:一个模拟战斗机的类被称为Fighters是没有意义的。它应该是单数,Fighter。战士没有名字,一个战士有名字。虽然可以想象一个斗士开始战斗,但奇怪的是一个斗士指挥它;我宁愿使用一个静态方法(Fighter.fight(goku, conan)),或者使用一个不同的类Fight,它表示两个人战斗的事件实例。它还将负责报告战斗情况。一个实例对另一个实例进行更改也不是很好;柯南可以命中,但只有小悟空应该对他的健康进行管理。while循环比它需要的更复杂;战斗的结构是攻击者击中防御者,然后他们交换位置。这使得流量控制更加容易。最后,根据Python命名约定,实例变量应该是小写的;人们可能会被欺骗,以为GokuConan是类名。(这只是一个例子,还有其他的案例问题。)所以记住这一点,有点重写:

import random

class Fighter:

    def __init__(self, name):
        self.name = name
        self.health = 100
        self.damage = [5, 10, 15, 20]
        self.strength = 0

    def __str__(self):
        return self.name

    def hit(self, defender):
        attack_damage = random.choice(self.damage) + self.strength
        defender.suffer(attack_damage)
        return attack_damage

    def suffer(self, attack_damage):
        self.health -= attack_damage

    def is_dead(self):
        return self.health <= 0

    def fight(self, other):
        return Fight(self, other)

class Fight:
    def __init__(self, attacker, defender):
        self.attacker = attacker
        self.defender = defender

    def round(self):
        damage = self.attacker.hit(self.defender)

        if self.defender.is_dead():
            print_str = f"{self.attacker} killed {self.defender}! {self.attacker} wins the fight!"
        else:
            print_str = f"{self.attacker} attacks {self.defender}!"
        print_str += f" Hit for {damage} damage | {self.defender}'s Health: {self.defender.health}hp"
        print(print_str, end="\n\n")

        self.attacker, self.defender = self.defender, self.attacker

    def run(self):
        while not self.attacker.is_dead():
            self.round()

goku = Fighter("Goku")
konan = Fighter("Konan")
goku.strength = 3

goku.fight(konan).run()

从这里开始,一个高级的练习就是把战斗变成一个发电机,这样你就可以更容易地一轮一轮地运行它。你知道吗

我已经用一种黑客的方式修改了你下面的代码。Working example here。注意事项:

  • 你的__str__方法过于复杂,使用不当(实际上永远不应该直接print
  • 我怀疑(但不知道)这是家庭作业。如果你依赖作业来获得答案,你就不会在作业上取得好成绩。。。即使我在下面提供给你的不是我认为的“好”,而是“更好”。如果我真的想解决问题,我会去HackerRank或类似的网站,而不是为别人做家庭作业。你知道吗
  • 你错过了“打击”和“战斗”之间的逻辑分界,而这正是我所做的
  • 你用第一架战斗机的命中方法对两架战斗机进行命中,这对我来说很奇怪/反模式。这样做的好处是(有一个Fighters.hit()方法)你可以给不同的战斗机分配不同的伤害数组,理论上代码应该仍然像预期的那样工作。你知道吗
  • 对我来说,一个fighter实例的startTheFight方法被用来在两个实例之间创建一个争斗(这本身并没有错,但我个人更希望startFight是一个类方法)。你知道吗
  • 如果可以的话,您应该使用f"{var_name}"(仅在python3.6+中),并且您应该确保您的string方法是有意义的——与在整个函数中使用一堆随机语句给出输出相比,“构建”最终输出(要打印的string、list、dict等)通常更容易/更明智/更容易阅读。你知道吗
  • 最后,你是不是希望战斗结束后血量恢复到满的?你知道吗

代码:

import random

class Fighters:

    def __init__(self, name):

        self.name = name
        self.health = 100
        self.damage = [5, 10, 15, 20]

    def __str__(self):

        return self.name

    def hit(attacking_fighter, defending_fighter):

      attack_damage = random.choice(attacking_fighter.damage)
      defending_fighter.health -= attack_damage

      if defending_fighter.health > 0:
        print_str = f"{attacking_fighter} attacks {defending_fighter}!"
      else:
        print_str = f"{attacking_fighter} killed {defending_fighter}! {attacking_fighter} wins the fight!"

      print_str +=  f" Hit for {attack_damage} damage | {defending_fighter}'s Health: {defending_fighter.health}hp"

      print(print_str, end="\n\n")

      return

    def startTheFight(self, otherFighter):

        while otherFighter.health > 0 and self.health > 0:
          self.hit(otherFighter)
          if otherFighter.health <= 0 or self.health <= 0:
            break
          otherFighter.hit(self)

Goku = Fighters("Goku")
Konan = Fighters("Konan")

#print(Goku)
#print(Konan)

Goku.startTheFight(Konan)

输出示例:

Goku attacks Konan! Hit for 10 damage | Konan's Health: 90hp

Konan attacks Goku! Hit for 10 damage | Goku's Health: 90hp

Goku attacks Konan! Hit for 5 damage | Konan's Health: 85hp

Konan attacks Goku! Hit for 10 damage | Goku's Health: 80hp

Goku attacks Konan! Hit for 5 damage | Konan's Health: 80hp

Konan attacks Goku! Hit for 20 damage | Goku's Health: 60hp

Goku attacks Konan! Hit for 10 damage | Konan's Health: 70hp

Konan attacks Goku! Hit for 15 damage | Goku's Health: 45hp

Goku attacks Konan! Hit for 10 damage | Konan's Health: 60hp

Konan attacks Goku! Hit for 20 damage | Goku's Health: 25hp

Goku attacks Konan! Hit for 5 damage | Konan's Health: 55hp

Konan attacks Goku! Hit for 10 damage | Goku's Health: 15hp

Goku attacks Konan! Hit for 10 damage | Konan's Health: 45hp

Konan killed Goku! Konan wins the fight! Hit for 15 damage | Goku's Health: 0hp

相关问题 更多 >