专栏首页codingpython模拟狙击手射击恐怖分子

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颗子弹
这是一个狙击手, 手持狙击步枪
这是一个恐怖分子,正手持菜刀劫持人质
狙击手向恐怖分子射击
恐怖分子被击中,已玩完

总结

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

源码下载

源码包

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 2018年swoole实战3-异步毫秒定时器服务端客户端启动服务

    项目中需要使用定时器时,crontab是常用的选择,不过crontab的粒度太大,最小时间单位是分钟级别,如果我们要设置秒级,甚至毫秒级的定时器,crontab...

    章鱼喵
  • vue 使用 cli 工具构建项目

    章鱼喵
  • 用单元测试让你的python代码更靠谱测试函数单元测试和测试用例测试类

    要学习测试,得有要测试的代码。下面是一个简单的函数,它接受名和姓并返回整洁的姓名:

    章鱼喵
  • python 日志封装

    写python项目时,需要用到日志类,需求为:日志信息可配置,提供几种类型不同的配置,并且日志既可以写到文本也可以写到数据库中。 实现时日志类直接使用pyt...

    py3study
  • Python中动态创建类的方法

    在Python中,类也是作为一种对象存在的,因此可以在运行时动态创建类,这也是Python灵活性的一种体现。

    drunkdream
  • Python中动态创建类的方法

    在Python中,类也是作为一种对象存在的,因此可以在运行时动态创建类,这也是Python灵活性的一种体现。

    drunkdream
  • Airflow自定义插件, 使用datax抽数

    Airflow之所以受欢迎的一个重要因素就是它的插件机制。Python成熟类库可以很方便的引入各种插件。在我们实际工作中,必然会遇到官方的一些插件不足够满足需求...

    Ryan-Miao
  • 【leetcode刷题】T147-两数之和 IV - 输入 BST

    https://leetcode-cn.com/problems/two-sum-iv-input-is-a-bst

    木又AI帮
  • Python 魔法属性

    Devops海洋的渔夫
  • Python中我刚知道的秘密

    简单、

扫码关注云+社区

领取腾讯云代金券