在之前的两个小节里面,我们学习了如何定义一个类,以及如何使用类,并且介绍了类的封装,继承,多态等特性,在这一小节里,我们将利用所学的知识来建立一个小小的虚拟斗争游戏类
故事背景:传说在上古时代,有四大凶兽--饕餮,混沌,梼杌和穷奇,同时存在着正义的化身四大神兽--青龙、白虎、朱雀、玄武,他们之间武义相当, 突然有一天四大神兽中的青龙遇上了饕餮,于是他们之间展开了生死决斗,他们分别使用以下技能:
-
青龙:必杀技飞羽升天攻击力100(10%), 大招神龙摆尾攻击力40(30%),普通攻击10(60%)
-
饕餮:必杀技冰封绝技攻击力90(15%), 大招吞噬万物攻击力35(30%), 普通攻击20(55%)
假设他们最开始较量的时候血量均为400,那么最后会是谁胜利呢? 要求:
- 分别定义两个基类 Monster, HolyBeast,中间有类的名称定义(name),攻击方式(attack),血量值HP, 但是HolyBeast自带回血buff,5%的几率回复2%血量,其余均回复10点血量,他们初始血量假设均为400
- 在基类的基础上定义青龙和饕餮,分别实现其攻击方式
- 他们之间进行斗争,输出每个回合他们之间的HP值,并进行判断哪一个胜利
首先,第一步,我们应该要定义两个基类,利用之前介绍过的封装特性以及抽象类和抽象函数的定义 ,我们可以十分简单的写出下面的代码:
import random
class Monster(metaclass=ABCMeta):
"""
凶兽的基类,为抽象类
"""
def __init__(self, name):
"""初始化凶兽的名称,血量"""
self._name = name
self._HP = 400
@property
def HP(self):
return self._HP
@HP.setter
def HP(self, HP):
self._HP = HP
@property
def name(self):
return self._name
@abstractmethod
def attack(self):
"""抽象的方法"""
pass
def alive(self):
return self._HP > 0
class HolyBeast(metaclass=ABCMeta):
def __init__(self, name):
"""初始化圣兽的名称,血量"""
self._name = name
self._HP = 400
@property
def HP(self):
return self._HP
@HP.setter
def HP(self, HP):
self._HP = HP
@property
def name(self):
return self._name
@abstractmethod
def attack(self):
pass
def resume(self):
"""自我恢复,使用随机模块来判定几率大小"""
rand = random.random()
if rand > 0.95:
self._HP += int(0.02*self._HP)
else:
self.HP += 10
def alive(self):
return self._HP > 0
复制代码
在上面的代码中,我们定义了两个基类,Monster表示凶兽,HolyBeast表示圣兽,运用所讲过的装饰器,我们将类中的属性进行封装并向外提高接口;使用abstractmethod
我们将其定义成抽象方法,并由子类提供实现,在HolyBeast中我们使用random
模块生成的随机生成的数字进行概率判断,并回复其血量
接下来,我们将利用上面的两个基类进行扩展,在其基础之上加上子类所需要的方法,我们写来看看饕餮如何实现吧
class TaoTie(Monster):
def __init__(self, name):
"""调用父类的初始化方法"""
super().__init__(name)
def attack(self):
"""实现攻击时所攻击的血量,其余功能由beat实现"""
rand = random.random()
if rand > 0.85:
kill_blood = 90
elif rand > 0.55:
kill_blood = 35
else:
kill_blood = 20
return kill_blood
def beat(self, other):
kill_blood = self.attack()
print("凶兽{} 击杀 圣兽{} {} HP".format(self.name, other.name, kill_blood))
other.HP -= kill_blood
复制代码
首先我们调用父类的初始化方法,对子类进行初始化,然后attack方法实现获取攻击消耗对方的血量,最后由beat函数调用attack函数并实现攻击,并同时消耗对方的血量,同理,我们可以写出QingLong类,只是需要注意在其攻击之后要使用恢复技能即可
class QingLong(HolyBeast):
def __init__(self, name):
super().__init__(name)
def attack(self):
rand = random.random()
if rand > 0.9:
kill_blood = 100
elif rand > 0.6:
kill_blood = 40
else:
kill_blood = 10
return kill_blood
def beat(self, other):
kill_blood = self.attack()
print("圣兽{} 击杀 凶兽{} {} HP".format(self.name, other.name, kill_blood))
other.HP -= kill_blood
self.resume()
复制代码
这样,我们便已经定义好了我们需要的类了,于是接下来,我们便需要实现其相互绝斗的部分了。
当然第一步,我们应该实例化具体对象,然后利用对象的beat方法实现决斗,当其中一个血量消耗完全的时候,我们便不再进行,所以我们可采用
while
循环来实现这一点,并在循环中输出相关的血量信息,回合次数,我们在把他们包装到main函数里面即可, 代码如下:
def main():
ql = QingLong("青龙")
tt = TaoTie("饕餮")
num = 0
while ql.alive() and tt.alive():
ql.beat(tt)
tt.beat(ql)
if ql.alive() and tt.alive():
print("-----------回合{}------------".format(num))
print("{}血量为:{},{}血量为:{}".format(ql.name, ql.HP, tt.name, tt.HP))
time.sleep(0.5)
else:
print("")
if ql.alive():
print("{}血量为:{},{}血量为:0".format(ql.name, ql.HP, tt.name))
print(">{}< 胜利".format(ql.name))
else:
print("{}血量为:0,{}血量为:{}".format(ql.name, tt.name, tt.HP))
print(">{}< 胜利".format(tt.name))
num += 1
复制代码
在最后我们只需要调用main函数,便可以实现青龙和饕餮之间的决斗了,完整代码发送fight
到公众号后台获取下载链接