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 == Falsemy_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 = 0self.attack = 0self.num = 0def add_units(self, x, num):self.health = x().healthself.attack = x().attackself.num = numclass Warrior:health = 50attack = 5is_alive = Trueclass Knight(Warrior):attack = 7def fight(army1, army2):while army1.health > 0:army2.health -= army1.attackarmy1.health -= army2.attackif army2.health > army1.health:army1.is_alive = Falsereturn Falseelse:army2.is_alive = Falsereturn Trueclass Battle:def fight(self, army1, army2):x2 = y2 = 0while army1.num > 0 and army2.num > 0:x1 = army1.health if x2 == 0 else x2y1 = army2.health if y2 == 0 else y2while True:y1 -= army1.attackif y1 <= 0:x2 = x1y2 = 0army2.num -= 1breakx1 -= army2.attackif x1 <= 0:y2 = y1x2 = 0army1.num -= 1breakif army1.num:return Trueelse:return Falseif __name__ == '__main__':#These "asserts" using only for self-checking and not necessary for auto-testingchuck = Warrior()bruce = Warrior()carl = Knight()dave = Warrior()mark = Warrior()assert fight(chuck, bruce) == Trueassert fight(dave, carl) == Falseassert chuck.is_alive == Trueassert bruce.is_alive == Falseassert carl.is_alive == Trueassert dave.is_alive == Falseassert fight(carl, mark) == Falseassert carl.is_alive == Falseprint("Coding complete? Let's try tests!")if __name__ == '__main__':#These "asserts" using only for self-checking and not necessary for auto-testing#fight testschuck = Warrior()bruce = Warrior()carl = Knight()dave = Warrior()mark = Warrior()assert fight(chuck, bruce) == Trueassert fight(dave, carl) == Falseassert chuck.is_alive == Trueassert bruce.is_alive == Falseassert carl.is_alive == Trueassert dave.is_alive == Falseassert fight(carl, mark) == Falseassert carl.is_alive == False#battle testsmy_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) == Trueassert battle.fight(army_3, army_4) == Falseprint("Coding complete? Let's try tests!")
大神解答
大神解答 NO.1
class Warrior:def __init__(self):self.health = 50self.attack = 5@propertydef is_alive(self):return self.health > 0class Knight(Warrior):def __init__(self):super().__init__()self.attack = 7def fight(u1, u2):while u1.is_alive and u2.is_alive:u2.health -= u1.attackif u2.is_alive:u1.health -= u2.attackreturn u1.is_aliveclass 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 = 0try:while True:u1, u2 = a1[i1], a2[i2]fight(u1, u2)i1 += not u1.is_alivei2 += not u2.is_aliveexcept 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) - 1j = len(unit_2.a) - 1while 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].atakif unit_2.a[j].hp > 0:unit_1.a[i].hp -= unit_2.a[j].atakif 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) > 0class 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 = 50self.atak = 5if self.hp > 0:self.is_alive = Trueelse:self.is_alive = False passclass Knight(Warrior):def __init__(self):self.hp = 50self.atak = 7if self.hp >= 0:self.is_alive = Trueelse:self.is_alive = Falsedef fight(unit_1, unit_2):n = 0while unit_1.hp > 0 and unit_2.hp > 0:unit_2.hp -= unit_1.atakif unit_2.hp > 0:unit_1.hp -= unit_2.atakif unit_1.hp > 0:unit_1.is_alive = Trueunit_2.is_alive = Falseelse:unit_2.is_alive = Trueunit_1.is_alive = False return unit_1.hp > 0