python模拟狙击手射击恐怖分子


场景需求

闹市中,有一个恐怖分子手持菜刀劫持了一个人质,狙击手接到命令,必须将恐怖分子击毙,这整个流程用python模拟实现,且必须用面向对象的方式来写。

分解需求

假设将狙击手击毙恐怖分子流程分解为:狙击手将子弹装入弹夹,将弹夹装入狙击枪,拿枪对准恐怖分子,扣动扳机,恐怖分子玩完。用面向对象的思维来提取这个流程中的对象,分别为:

  • 狙击手
  • 恐怖分子
  • 弹夹
  • 子弹

当然,你也可以将人质,恐怖分子持的菜刀这些作为对象,不过作为模拟示例,粒度没必要过细

狙击手.jpg

思路流程如下:

#_*_coding:utf8_*_
def main():
    """程序的执行流程"""
    # 创建狙击手sniper

    # 创建枪gun

    # 创建弹夹clip

    # 创建子弹bullet

    # 创建恐怖分子terrorist

    # 狙击手将子弹安装到弹夹中

    # 狙击手将弹夹安装到枪中

    # 狙击手拿起枪

    # 狙击手开枪射杀恐怖分子

if __name__ == '__main__':
    main()

创建对象

提取需求中的对象后,就可以来创建相应的类了:

狙击手和恐怖分子均属于人,只需建一个Person类,枪、弹夹、子弹分别创建独立的类

# 人物类
class Person(object):
    def __init__(self, name):
        super(Person, self).__init__()
        self.name = name

# 枪类
class Gun(object):
    def __init__(self, name):
        super(Gun, self).__init__()
        self.name = name

# 弹夹类
class Clip(object):
    def __init__(self, max_num):
        super(Clip, self).__init__()
        self.max_num = max_num # 表示弹夹能装的子弹数量

# 子弹类
class Bullet(object):
    def __init__(self):
        super(Bullet, self).__init__()

def main():
    """程序的执行流程"""
    # 创建狙击手sniper
    sniper = Person('狙击手')

    # 创建枪gun
    gun = Gun('狙击步枪')

    # 创建弹夹clip
    clip = Clip(15)

    # 创建子弹bullet
    bullet = Bullet()

    # 创建恐怖分子terrorist
    terrorist = Person('恐怖分子')

    #...

将子弹装到弹夹中

子弹是一个独立的对象,要装到弹夹中,就必须在弹夹类中创建一个属性来保存子弹的对象,每个子弹对象表示一颗独立的子弹,而装子弹这个动作是由狙击手发起的,因此在Person类中应新增装子弹的方法

Person 类新增方法: 装子弹

def install_bullet(self, clip, bullet):
    # 将子弹装入弹夹中
    clip.save_bullet(bullet)

Clip 弹夹类新增方法: 保存子弹

class Clip(object):
    def __init__(self, max_num):
        super(Clip, self).__init__()
        self.max_num = max_num # 弹夹的最大容量
        self.bullet_list = [] # 保存子弹对象的引用

    def save_bullet(self, bullet):
        # 将子弹存入弹夹
        self.bullet_list.append(bullet)

main() 中调用装子弹的方法:

def main():
    # ...
    # 狙击手将子弹安装到弹夹中
    sniper.install_bullet(clip, bullet)

狙击手将弹夹装到枪中

Person 类应新增装弹夹的方法,枪类需新增保存弹夹的方法

Person 新增方法:装弹夹

    def install_clip(self, gun, clip):
        # 将弹夹装入枪中
        gun.save_clip(clip)

Gun 枪类新增方法:保存弹夹

class Gun(object):
    def __init__(self, name):
        super(Gun, self).__init__()
        self.name = name
        self.clip = None # 记录弹夹对象的引用

    def save_clip(self, clip):
        self.clip = clip

main() 中调用装子弹的方法:

def main():
    # ...
    # 狙击手将弹夹安装到枪中
    sniper.install_clip(gun, clip)

测试枪、弹夹、子弹

测试往弹夹添加一些子弹,打印出弹夹、子弹和枪的相关信息

#_*_coding:utf8_*_
class Person(object):
    def __init__(self, name):
        super(Person, self).__init__()
        self.name = name

    def install_bullet(self, clip, bullet):
        # 将子弹装入弹夹中
        clip.save_bullet(bullet)

    def install_clip(self, gun, clip):
        # 将弹夹装入枪中
        gun.save_clip(clip)

class Gun(object):
    def __init__(self, name):
        super(Gun, self).__init__()
        self.name = name
        self.clip = None # 记录弹夹对象的引用

    def save_clip(self, clip):
        self.clip = clip

    def __str__(self):
        if self.clip:
            return '枪的信息为:%s, %s' % (self.name, self.clip)
        else:
            return '枪的信息为:%s, 没有弹夹' % self.name


class Clip(object):
    def __init__(self, max_num):
        super(Clip, self).__init__()
        self.max_num = max_num # 弹夹的最大容量
        self.bullet_list = [] # 保存子弹对象的引用

    def save_bullet(self, bullet):
        # 将子弹存入弹夹
        self.bullet_list.append(bullet)

    def __str__(self):
        return '弹夹能装%s颗子弹,当前有%s颗子弹' % (self.max_num, len(self.bullet_list))

class Bullet(object):
    def __init__(self):
        super(Bullet, self).__init__()


def main():
    """程序的执行流程"""
    # 创建狙击手sniper
    sniper = Person('狙击手')

    # 创建枪gun
    gun = Gun('狙击步枪')

    # 创建弹夹clip
    clip = Clip(15)

    # 创建子弹bullet
    for i in range(6):
        bullet = Bullet()
        sniper.install_bullet(clip, bullet)

    # 创建恐怖分子terrorist
    terrorist = Person('恐怖分子')

    # 狙击手将子弹安装到弹夹中
    # sniper.install_bullet(clip, bullet)

    # 狙击手将弹夹安装到枪中
    sniper.install_clip(gun, clip)

    # 测试弹夹信息
    print(clip)

    # 测试枪的信息
    print(gun)

    # 狙击手拿起枪

    # 狙击手开枪射杀恐怖分子

if __name__ == '__main__':
    main()

执行结果为:

弹夹能装15颗子弹,当前有6颗子弹
枪的信息为:狙击步枪, 弹夹能装15颗子弹,当前有6颗子弹

狙击手拿起枪

python 类新增方法:拿枪

class Person(object):
    def __init__(self, name):
        super(Person, self).__init__()
        self.name = name
        self.gun = None

    def install_bullet(self, clip, bullet):
        # 将子弹装入弹夹中
        clip.save_bullet(bullet)

    def install_clip(self, gun, clip):
        # 将弹夹装入枪中
        gun.save_clip(clip)

    def hold_gun(self, gun):
        # 举枪
        self.gun = gun

    def __str__(self):
        if self.gun:
            return "这是一个%s, 手持%s" % (self.name, self.gun.name)

塑造恐怖分子形象

狙击手和恐怖分子同属于Person类,在实例化时要有所区分(简单起见,以是否有枪为区分)

def __str__(self):
    if self.gun:
        return "这是一个%s, 手持%s" % (self.name, self.gun.name)
    else:
        return "这是一个恐怖分子,正手持菜刀劫持人质"

狙击手向恐怖分子射击

射击的动作分解为:狙击手发起射击,弹夹弹出最上面的一颗子弹,子弹射向恐怖分子,恐怖分子玩完

整个射击的动作将所有类都调动起来了

#_*_coding:utf8_*_
class Person(object):
    def __init__(self, name):
        super(Person, self).__init__()
        self.name = name
        self.gun = None

    def install_bullet(self, clip, bullet):
        # 将子弹装入弹夹中
        clip.save_bullet(bullet)

    def install_clip(self, gun, clip):
        # 将弹夹装入枪中
        gun.save_clip(clip)

    def hold_gun(self, gun):
        # 举枪
        self.gun = gun

    def __str__(self):
        if self.gun:
            return "这是一个%s, 手持%s" % (self.name, self.gun.name)
        else:
            return "这是一个恐怖分子,正手持菜刀劫持人质"

    def shoot(self, terrorist):
        # 向恐怖分子发起射击
        print('%s向%s射击' % (self.name, terrorist.name))
        self.gun.fire(terrorist)

    def game_over(self):
        # 被击中,玩完了
        print("%s被击中,已玩完" % self.name)

class Gun(object):
    def __init__(self, name):
        super(Gun, self).__init__()
        self.name = name
        self.clip = None # 记录弹夹对象的引用

    def save_clip(self, clip):
        self.clip = clip

    def __str__(self):
        if self.clip:
            return '枪的信息为:%s, %s' % (self.name, self.clip)
        else:
            return '枪的信息为:%s, 没有弹夹' % self.name

    def fire(self, terrorist):
        # 枪从弹夹中获取一发子弹,子弹向恐怖分子发射过去
        
        # 从弹夹取出一发子弹
        bullet = self.clip.pop_bullet()

        if bullet:
            bullet.hit(terrorist)
        else:
            print('坑啊,竟然没子弹了')
        


class Clip(object):
    def __init__(self, max_num):
        super(Clip, self).__init__()
        self.max_num = max_num # 弹夹的最大容量
        self.bullet_list = [] # 保存子弹对象的引用

    def save_bullet(self, bullet):
        # 将子弹存入弹夹
        self.bullet_list.append(bullet)

    def __str__(self):
        return '弹夹能装%s颗子弹,当前有%s颗子弹' % (self.max_num, len(self.bullet_list))

    def pop_bullet(self):
        # 弹出最上面的子弹
        if self.bullet_list:
            return self.bullet_list.pop()
        else:
            return None

class Bullet(object):
    def __init__(self):
        super(Bullet, self).__init__()

    def hit(self, terrorist):
        terrorist.game_over()



def main():
    """程序的执行流程"""
    # 创建狙击手sniper
    sniper = Person('狙击手')

    # 创建枪gun
    gun = Gun('狙击步枪')

    # 创建弹夹clip
    clip = Clip(15)

    # 创建子弹bullet
    for i in range(6):
        bullet = Bullet()
        # 狙击手将子弹安装到弹夹中
        sniper.install_bullet(clip, bullet)

    # 狙击手将弹夹安装到枪中
    sniper.install_clip(gun, clip)

    # 测试弹夹信息
    print(clip)

    # 测试枪的信息
    print(gun)

    # 狙击手拿起枪
    sniper.hold_gun(gun)
    print(sniper)

    # 创建恐怖分子terrorist
    terrorist = Person('恐怖分子')
    print(terrorist)

    # 狙击手开枪射杀恐怖分子
    sniper.shoot(terrorist)

if __name__ == '__main__':
    main()

执行结果为:

弹夹能装15颗子弹,当前有6颗子弹
枪的信息为:狙击步枪, 弹夹能装15颗子弹,当前有6颗子弹
这是一个狙击手, 手持狙击步枪
这是一个恐怖分子,正手持菜刀劫持人质
狙击手向恐怖分子射击
恐怖分子被击中,已玩完

总结

  • 面向对象是解决现实复杂问题的良好方式,可以将复杂问题分解为由各种对象交互传递消息,从而使问题简单化
  • 对象通常用属性来保存其他对象的引用,实现相互之间的关联

源码下载

源码包

优质内容筛选与推荐>>
1、win10家庭版设置移动热点出现“我们无法设置移动热点”
2、Linux的一些基础命令
3、10420 - List of Conquests
4、《21天学会C++》学习笔记第7章控制程序流程
5、操作Jexus


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号