可遵循的一个流程

Python面向对象编程(OOP)方式实现东西的流程(只是你可以遵守的一种方法):
1. 把要解决的问题写下来,或画出流程图。
2. 将第一条中的关键概念摘录出来并加以研究。
3. 创建一个类和对象的层次结构图。
4. 用代码实现各个类,并写一个测试来运行它们。
5. 重复上述步骤并细化代码。
上述可看做一个“自顶向下”(top down)的流程:从很抽象的概念入手,逐渐细化,直到概念变为具体可用代码实现的东西。

简单游戏分析

利用上述流程实现一个游戏引擎和一个游戏。
游戏名称《来自Percal 25 号行星的哥顿人》,是一款空间冒险游戏。
把问题写下来或画下来
游戏描述:“外星人入侵宇宙飞船,我们的英雄需要通过各种房间组成的迷宫,打败遇到的外星人,这样才能通过救生船回到下面的行星上去。此游戏会与Zork或者Adventure类似,会用文字输出各种有趣的死法。游戏会用到一个引擎,它带动一张充满房间和场景的地图。当玩家进入一个房间时,这个房间会显示出自己的描述,并告诉引擎下一步应到哪个房间去。”
以上对游戏内容和运行方式有了一个很好的概念。下面是描述各个场景。
& 死亡(Death)。 玩家死去的场景,应比较搞笑。
&中央走廊(Central Corridor)。游戏起点,哥顿人已经在这里把守着了,玩家要讲一个笑话才能继续。
&激光武器库(Laser Weapon Armory)。 在这里英雄会找到一个中子弹,在乘坐救生飞船离开时要用它把飞船炸掉。这个房间有一个数字键盘,需猜测密码组合。
&飞船主控仓(The Bridge)。另一个战斗场景,英雄在此埋炸弹。
&救生舱(Escape Pod)。英雄逃离的场景,但需要猜对是哪艘救生船。
至此,已大概画出了它们的关系图,可能还需给每个房间写更详细的描述。
摘录和研究关键概念
有足够信息来摘录一些名词,并分析它们的类层次结构。
1)首先名词列表
外星人(Alien)
玩家(Player)
飞船(Ship)
迷宫(Maze)
房间(Room)
场景(Scene)
哥顿人(Gothon)
救生舱(Escape Pod)
行星(Planet)
地图(Map)
引擎(Engine)
死亡(Death)
中央走廊(Central Corridor)
激光武器库(Laser Weapon Armory)
主控仓(The Bridge)
可能还需摘录动词来看其是否适合做函数名(暂时跳过)。
到此,研究这些概念及其中没弄明白的部分。如,可能会通过玩类似游戏来确认其工作方式;也许会研究飞船怎样设计的,及炸弹是怎样工作的;也许还会研究一些技术细节,如怎样把游戏状态存到数据库里。
等完成这些研究后也许要回到第一步,基于学到的新东西重写游戏描述及重新摘录相关概念。
为各种概念创建类层次结构图和对象关系图
通过思考“和其他东西有哪些类似?”或“哪个其实是某个东西的另一种叫法?”
发现:1)“房间”和“场景”基本是同一个东西,在这个游戏中使用“场景”:“中央走廊”是一个场景,死亡基本也是一个场景,行星也可以是另一个场景 2) “迷宫”和“地图”基本是一个意思,用地图。3)不打算实现一个作战系统,所以“外星人”和“玩家”忽略。
然后,在文本编辑器画一个类的层次结构图。
* map
* Engine
* Scene
* Death
* Central Corridor
* Laser Weapon Armory
* The Bridge
* Escape Pod
再然后,查看描述中的动词部分,从而知道每一样东西上需要什么样的动作。
例如,需要方法来运行游戏引擎,在地图里转到下一个场景,获得初始场景及进入下一个场景。加到结构图里。
* Map
- next_scene
- opening_scene
* Engine
- play
* Scene
-enter
* Death
* Central Corridor
* Laser Weapon Armory
* The Bridge
* Escape Pod
scene下只添加了enter方法,因为具体场景会继承并覆盖这个方法。
编写和运行各个类
完成以上,再在编辑器里打开一个源文件,并为它编写代码。通常只需将上面的树状结构复制到源文件中,把它扩写成各个类就可以了。(初始简单例子),文件最后还包含一点简单测试。
class Scene(object):
def enter(self):
pass
class Engine(object):
def __init__(self, scene_map):
pass
def play(self):
pass
class Death(Scene):
def enter(self):
pass
class CentralCorridor(Scene):
def enter(self):
pass
class LaserWeaponArmory(Scene):
def enter(self):
pass
class TheBridge(Scene):
def enter(self):
pass
class EscapePod(Scene):
def enter(self):
pass
class Map(object):
def __init__(self, start_scene):
pass
def next_scene(self, scene_name):
pass
def opening_scene(self):
pass
a_map = Map('central_corridor')
a_game = Engine(a_map)
a_game.play()
重复和优化

代码的实现不是一蹴而就的,需要不断重复前边的流程,不断优化自己所写的内容。不要局限于具体的步骤,哪突然有灵感了可以继续写下去或跳过某步骤也可以,最终是要使你的代码更完善。

自顶向下与自底向上

自顶向下:从最抽象的概念(顶层)下手,一直向下做到具体的代码实现。要多用这种方法分析问题。
自底向上:先从代码开始,一直向上做到抽象概念。

《来自Percal25号行星的哥顿人》的代码

from sys import exit

from random import randint

class Scene(object):

def enter(self):

print "This scene is not yet configured. Subclass it and implement enter()."

exit(1)

class Engine(object):

def __init__(self, scene_map):

self.scene_map = scene_map

def play(self):

current_scene = self.scene_map.opening_scene()

while True:

print "\n--------"

next_scene_name = current_scene.enter()

current_scene = self.scene_map.next_scene(next_scene_name)

class Death(Scene):

quips = [

"You died. You kinda suck at this.",

"Your mom would be proud...if she were smarter.",

"Such a luser.",

"I have a small puppy that's better at this."

]

def enter(self):

print Death.quips[randint(0, len(self.quips)-1)]

exit(1)

class CentralCorridor(Scene):

def enter(self):

print "The Gothons of Planet Percal #25 have invaded your ship and destroyed"

print "your entire crew. You are the last surviving member and your lasr"

print "mission is to get the neutron destruct bomb from the Weapons Armory,"

print "put it in the bridge, and blow the ship up after getting into an "

print "escape pod."

print "\n"

print "You're running down the central corridor to the Weapons Armory when"

print "a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume"

print "flowing around his hate filled body. He's blocking the doot to the"

print "Armory and about to pull a weapon to blast you."

action = raw_input("> ")

if action == "shoot!":

print "Quick on the draw you yank out your blaster and fire it at the Gothon."

print "His clown costume is flowing and moving around his body, which throws"

print "off your aim. Your laser hits his costume but misses him entirely. This"

print "completely ruins his brand new costume his mother bought him, which"

print "makes him fly into a rage and blast you repeatedly in the face until"

print "you are dead, Then he eats you."

return 'death'

elif action == "dodge!":

print "Like a world class boxer you dodge, weave, slip and slide right"

print "as the Gothon's blaster cranks a laser past your head."

print "In the middle of your artful dodge your foot slips and you"

print "bang your head on the metal wall and pass out."

print "You wake up shortly after only to die as the Gothon stomps on"

print "your head and eats you."

return 'death'

elif action == "tell a joke":

print "Lucky for you they made you learn Gothon insults in the academy."

print "You tell the one Gothon joke you know:"

print "Lbhe zbgure vf fb sng, jura fur fvgf nebhag gur ubhfr, fur fvgf nebhap fur ubkd."

print "The Gothon stops, tries not to laugh , then busts out laughing and can't move."

print "While he's laughing you run up and shoot him square in the head"

print "putting him down, then jump through the Weapon Armory door."

return 'laser_weapon_armory'

else:

print "DOES NOT COMPUTE!"

return 'central_corridor'

class LaserWeaponArmory(Scene):

def enter(self):

print "You do a dive roll into the Weapon Armory, crouch and scan the room"

print "for more Gothons that might be hiding. It's dead quiet, too quiet."

print "You stand up and run to the far side of the room and find the "

print "neutron bomb in its container. There's a keypad lock on the box"

print "and you need the code to get the bomh out. If you get the code"

print "wrong 10 times then the lock closes forever and you can't"

print "get the bomb. The code is 3 digits."

code = "%d%d%d" % (randint(1, 9), randint(1, 9), randint(1, 9))

a = 0

for s in code:

x = int(s)

a = a + x

print "The sum of these 3 digit is %d" % a

guesses = 1

guess = raw_input("[keypad]> ")

while guess != code and guesses < 10:

print "BZZZZEDDD!"

guesses += 1

guess = raw_input("[keypad]> ")

if guess == code:

print "The container clicks open and the seal breaks, letting gas out."

print "You grab the neutron bomb and run as fast as you can to the"

print "bridge where you must place it in the right spot."

return 'the_bridge'

else:

print "The lock buzzes one last time and then you hear a sickening"

print "melting sound as the mechanism is fused together."

print "You decide to sit there, and finally the Gothons blow up the"

print "ship from their ship and you die."

return 'death'

class TheBridge(Scene):

def enter(self):

print "You burst onto the bridge with the netron destruct bomb"

print "under your arm and surprise 5 Gothons who are trying to"

print "take control of the ship. Each of them has an even uglier"

print "clown costume than the last. They haven't pulled their"

print "weapons out yet, as they see the active bomb under your"

print "arm and don't want to set it off."

action = raw_input("> ")

if action == "throw the bomb":

print "In a panic you throw the bomb at the group of Gothons"

print "and make a leap for the door. Right as you drop it a"

print "Gothon shoots you right in the back killing you."

print "As you die you see another Gothon frantically try to disarm"

print "the bomb. You die knowing they will probably blow up when"

print "it goes off."

return 'death'

elif action == "slowly place the bomb":

print "You point your blaster at the bomb under your arm"

print "and the Gothons put their hands up and start to sweat."

print "You inch backward to the door, open it, and the carefully"

print "place the bomb on the floor, pointing your blaster at it."

print "You then jump back through the door, punch the close button"

print "and blast the lock so the Gothons can't get out."

print "Now that the bomb is placed you run to the escape pod to"

print "get off this tin can."

return 'escape_pod'

else:

print "DOES NOT COMPUTE!"

return "the_bridge"

class EscapePod(Scene):

def enter(self):

print "You rush through the ship desperately trying to make it to"

print "the escape pod before the whole ship explodes. It seems like"

print "hardly any Gothons are on the ship, so your run is clear of"

print "interferrnce. You get to the chamber with the escape pods, and"

print "now need to pick one to take. Some of them could be damaged"

print "but you don't have time to look. There's 5 pods, which one"

print "do you take?"

good_pod = randint(1, 5)

guess = raw_input("[pod #]> ")

if int(guess) != good_pod:

print "You jump into pod %s and hit the eject button." % guess

print "The pod escapes out into the void of space, then"

print "implodes as the hull ruptures, crushing your body"

print "into jam jelly."

return 'death'

else:

print "You jump into pod %s and hit the eject button." % guess

print "The pod easily slides out into spase heading to"

print "the planet below. As it flies to the planet, you look"

print "back and see your ship implods then explode like a"

print "bright star, taking out the Gothons ship at the same"

print "time, You win!"

return 'finished'

class Map(object):

scenes = {

'central_corridor': CentralCorridor(),

'laser_weapon_armory': LaserWeaponArmory(),

'the_bridge': TheBridge(),

'escape_pod': EscapePod(),

'death': Death()

}

def __init__(self, start_scene):

self.start_scene = start_scene

def next_scene(self, scene_name):

return Map.scenes.get(scene_name)

def opening_scene(self):

return self.next_scene(self.start_scene)

a_map = Map('central_corridor')

a_game = Engine(a_map)

a_game.play()

附加练习

1 代码中有个bug, 武器库的门锁密码为啥要猜11次而不是10次?

2 解释一下房间切换的原理

3 为难度大的房间添加通过秘籍(一行代码,两个词就可做出来)

4 回到描述和分析部分,为英雄和哥顿人创建一个简单的格斗系统

5 这其实是一个小版本的“有限状态机”(finite state machine)

笨方法学Python—ex43:基本的面向对象分析和设计相关推荐

  1. 《 笨方法学 Python 》_ 目录

    < 笨方法学 Python >(第 3 版)书中代码是 Python 2 版本,本着学习 Python 3 的目的,用 Python 3 完成本书的习题,代码也已上传到 Github. 作 ...

  2. 笔记 | 笨方法学Python

    整理 | 阿司匹林 出品 | 人工智能头条(公众号ID:AI_Thinker) Python 有多好应该不用多说了,毕竟它是"钦定的"最接近 AI 的语言.(当然,PHP 才是最好 ...

  3. 笨方法学Python(二)

    笨方法学Python,习题16 - 21 版本:3.8.0 编辑器:Visual Studio Code 习题16到21讲的是文件的读写和函数的基础,可以通过一个实例来同时练习他们.在下列情景中,我将 ...

  4. 笨方法学python 习题37

    还是在笨方法学python中... 本节的习题是看一下作者列出的python中的各种运算符,尝试来理解这些符号. 在这里,我只列出了一些自己不会的,通过查百度得到得答案,这里来列举一下. (另外有不怎 ...

  5. 笨方法学python 15章疑问

    ** 笨方法学python 15章疑问 在15张中教我们读取文件,但是当我测试能否打开我之前写的py格式的文本时出现了这一幕 文件打开后然后又出现了 File "15.py", l ...

  6. 《笨方法学python》_《笨办法学Python》 第46课手记

    <笨办法学Python> 第46课手记 这节课制作了一个Python的项目骨架,花了我一个晚上和一个早上的时间,原因是我下载的pdf里面只有OX S的命令行,而没有win下的.我为此在知道 ...

  7. 笨方法学python习题4

    变量和命名 #笨方法学python_习题4#定义变量 cars = 100 space_in_a_car = 4.0 drivers = 30 passengers = 90#计算 cars_not_ ...

  8. 《笨方法学 Python 3》43.基本的面向对象分析和设计

    这章断断续续续写了一周,今天放出来......主要是翻译那些场景描述很烦人,毕竟0级英语. 面向对象的分析和设计的基本流程: 把要解决的问题写下来,或者画下来 将第一条的关键概念提取出来并加以研究 创 ...

  9. 笨方法学python第四版当当_“笨办法”学Python(第3版)

    ZedShaw完善了这个堪称世上较好的Python学习系统.只要跟着学习,你就会和迄今为止数十万Zed教过的初学者一样获得成功. 在这本书中,你将通过完成52个精心设计的习题来学会Python.阅读这 ...

最新文章

  1. LeetCode Contains Duplicate
  2. CentOS 安装MySQL rpm方式安装
  3. 以经济周期的角度来看世界
  4. pycharm上传代码到github
  5. 【死磕 Spring】----- IOC 之解析 bean 标签:解析自定义标签
  6. CF79D Password(P3943 星空)
  7. DNN使用非80端口和总是跳转到http://localhost问题的解决
  8. Bootstrap使用后笔记
  9. 函数式编程:如何高效简洁地对数据查询与变换
  10. hive 操作(三)——hive 的数据模型
  11. 试试看读一下Zepto源码
  12. 【JAVA】在jar文件中引用图片等外部资源的问题
  13. SM2算法全套(基于GMSSL)
  14. FPGA入门 Xilinx暑期学校学习Day4
  15. java web 常见面试题_2019最新Javaweb面试题及答案
  16. 《数据库原理与应用》复习总结
  17. [深度学习]动手学深度学习笔记-11
  18. curse库的使用总结
  19. 第八十七篇 朴素贝叶斯
  20. AI英雄出少年!奔赴星辰,他们正在创造黄金时代

热门文章

  1. 【408计算机考研】计算机网络——第1章 计算机网络体系结构
  2. matplotlib之pyplot模块plot函数基础二(线条外观:格式字符串fmt)
  3. 【展讯】安卓修改音量等级曲线
  4. 考健身教练证要学历吗
  5. 数学分析 曲面积分与场论初步(第22章)
  6. 卡塞格林光学系统_卡塞格林系统光学装调技术研究
  7. 飞机订票系统c语言大作业,C语言知识学习飞机订票系统
  8. 使用网络调试助手连接阿里云平台
  9. 利用springcloud搭建一个简易的分布式简历展示系统
  10. java HttpURLConnection类的disconnect方法与http长连接