【Python CheckiO 题解】Army Battles


CheckiO 是面向初学者和高级程序员的编码游戏,使用 Python 和 JavaScript 解决棘手的挑战和有趣的任务,从而提高你的编码技能,本博客主要记录自己用 Python 在闯关时的做题思路和实现代码,同时也学习学习其他大神写的代码。

CheckiO 官网:https://checkio.org/

我的 CheckiO 主页:https://py.checkio.org/user/TRHX/

CheckiO 题解系列专栏:https://itrhx.blog.csdn.net/category_9536424.html

CheckiO 所有题解源代码:https://github.com/TRHX/Python-CheckiO-Exercise


题目描述

【Army Battles】:这个题目是 The Warriors 的延伸题目,继上次车夫与爵士进行决斗之后,现在双方都叫了增援,在此任务中,您的任务是向现有的类和函数中添加新的类和函数。新的类别应该是 Army(),并具有 add_units() 方法,用于将选定数量的单位添加到 Army() 中,添加的第一个参数将是第一个参战的部队,第二个参数将是第二个参战的部队,此外,您还需要创建一个带有 fight() 函数的 Battle() 类,这将决定最强大的军队。 战斗按照以下原则进行:

首先,在第一军的一名士兵和第二军的一名士兵之间有一场决斗,士兵战斗时,如果其中一方生命值小于等于 0,则需要让新的士兵加入到战争中,而且新的士兵是和对方上场战斗中活下来的士兵战斗,在这种情况下,如果第一支军队获胜,则 Battle() 函数应返回 True,如果第二支军队获胜则返回 False
在这里插入图片描述
【链接】https://py.checkio.org/mission/army-battles/

【输入】:勇士和军队

【输出】:战斗的结果(True or False)

【范例】

chuck = Warrior()
bruce = Warrior()
carl = Knight()
dave = Warrior()
mark = Warrior()

fight(chuck, bruce) == True
fight(dave, carl) == False
chuck.is_alive == True
bruce.is_alive == False
carl.is_alive == True
dave.is_alive == False
fight(carl, mark) == False
carl.is_alive == False

my_army = Army()
my_army.add_units(Knight, 3)

enemy_army = Army()
enemy_army.add_units(Warrior, 3)

army_3 = Army()
army_3.add_units(Warrior, 20)
army_3.add_units(Knight, 5)

army_4 = Army()
army_4.add_units(Warrior, 30)

battle = Battle()

battle.fight(my_army, enemy_army) == True
battle.fight(army_3, army_4) == False

代码实现

class Army():
    def __init__(self):
        self.health = 0
        self.attack = 0
        self.num = 0

    def add_units(self, x, num):
        self.health = x().health
        self.attack = x().attack
        self.num = num


class Warrior:
    health = 50
    attack = 5
    is_alive = True


class Knight(Warrior):
    attack = 7


def fight(army1, army2):
    while army1.health > 0:
        army2.health -= army1.attack
        army1.health -= army2.attack
    if army2.health > army1.health:
        army1.is_alive = False
        return False
    else:
        army2.is_alive = False
        return True


class Battle:
    def fight(self, army1, army2):
        x2 = y2 = 0
        while army1.num > 0 and army2.num > 0:
            x1 = army1.health if x2 == 0 else x2
            y1 = army2.health if y2 == 0 else y2
            while True:
                y1 -= army1.attack
                if y1 <= 0:
                    x2 = x1
                    y2 = 0
                    army2.num -= 1
                    break
                x1 -= army2.attack
                if x1 <= 0:
                    y2 = y1
                    x2 = 0
                    army1.num -= 1
                    break
        if army1.num:
            return True
        else:
            return False


if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing

    chuck = Warrior()
    bruce = Warrior()
    carl = Knight()
    dave = Warrior()
    mark = Warrior()

    assert fight(chuck, bruce) == True
    assert fight(dave, carl) == False
    assert chuck.is_alive == True
    assert bruce.is_alive == False
    assert carl.is_alive == True
    assert dave.is_alive == False
    assert fight(carl, mark) == False
    assert carl.is_alive == False

    print("Coding complete? Let's try tests!")


if __name__ == '__main__':
    #These "asserts" using only for self-checking and not necessary for auto-testing
    
    #fight tests
    chuck = Warrior()
    bruce = Warrior()
    carl = Knight()
    dave = Warrior()
    mark = Warrior()

    assert fight(chuck, bruce) == True
    assert fight(dave, carl) == False
    assert chuck.is_alive == True
    assert bruce.is_alive == False
    assert carl.is_alive == True
    assert dave.is_alive == False
    assert fight(carl, mark) == False
    assert carl.is_alive == False

    #battle tests
    my_army = Army()
    my_army.add_units(Knight, 3)
    
    enemy_army = Army()
    enemy_army.add_units(Warrior, 3)

    army_3 = Army()
    army_3.add_units(Warrior, 20)
    army_3.add_units(Knight, 5)
    
    army_4 = Army()
    army_4.add_units(Warrior, 30)

    battle = Battle()

    assert battle.fight(my_army, enemy_army) == True
    assert battle.fight(army_3, army_4) == False
    print("Coding complete? Let's try tests!")

大神解答

大神解答 NO.1

class Warrior:
    def __init__(self):
        self.health = 50
        self.attack = 5
    
    @property
    def is_alive(self):
        return self.health > 0


class Knight(Warrior):
    def __init__(self):
        super().__init__()
        self.attack = 7


def fight(u1, u2):
    while u1.is_alive and u2.is_alive:
        u2.health -= u1.attack
        if u2.is_alive:
            u1.health -= u2.attack
    return u1.is_alive


class Army:
    def __init__(self):
        self._units = []

    def __getitem__(self, index):
        return self._units[index]
        
    def __len__(self):
        return len(self._units)

    def add_units(self, unit, count):
        self._units.extend(unit() for _ in range(count))


class Battle:
    def fight(self, a1, a2):
        i1 = i2 = 0
        try:
            while True:
                u1, u2 = a1[i1], a2[i2]
                fight(u1, u2)
                i1 += not u1.is_alive
                i2 += not u2.is_alive
        except IndexError:
            return any(u.is_alive for u in reversed(a1))

大神解答 NO.2

class Battle:
    def fight(self, unit_1, unit_2):
        i = len(unit_1.a) - 1
        j = len(unit_2.a) - 1
        while i >= 0 and j >= 0:
            while unit_1.a[i].hp > 0 and unit_2.a[j].hp > 0:
                unit_2.a[j].hp -= unit_1.a[i].atak
                if unit_2.a[j].hp > 0:
                    unit_1.a[i].hp -= unit_2.a[j].atak
            if unit_1.a[i].hp > 0:
                unit_2.a.pop()
                j -= 1
                # print(unit_1.a[i].hp)
            else:
                unit_1.a.pop()
                i -=1
                # print(unit_2.a[j].hp)
        return len(unit_1.a) > 0


class Army:
    def __init__(self):
        self.a = []
        
    def add_units(self, cl, n):
        for i in range(n):
            if cl == Warrior:
                n = Warrior()
                self.a.append(n)
            else:
                n = Knight()
                self.a.append(n)


class Warrior:
    def __init__(self):
        self.hp = 50
        self.atak = 5
        if self.hp > 0:
            self.is_alive = True
        else:
            self.is_alive = False      
    pass


class Knight(Warrior):
    def __init__(self):
        self.hp = 50
        self.atak = 7
        if self.hp >= 0:
            self.is_alive = True
        else:
            self.is_alive = False


def fight(unit_1, unit_2):
    n = 0
    while unit_1.hp > 0 and unit_2.hp > 0:
        unit_2.hp -= unit_1.atak
        if unit_2.hp > 0:
            unit_1.hp -= unit_2.atak
    if unit_1.hp > 0:
        unit_1.is_alive = True
        unit_2.is_alive = False
    else:
        unit_2.is_alive = True
        unit_1.is_alive = False        
    return unit_1.hp > 0
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值