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

总结

  • 面向对象是解决现实复杂问题的良好方式,可以将复杂问题分解为由各种对象交互传递消息,从而使问题简单化

  • 对象通常用属性来保存其他对象的引用,实现相互之间的关联

源码下载

源码包

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360