【类不类三】来自星星的哥顿人与正则表达式

    这是用类和函数设计的一个小游戏, 我把原文的内容翻译成中文。

    【类不类二】: http://www.cnblogs.com/Ruby517/p/5821540.html

    参考: 习题—43

 

    我删除了Scene类的定义,因为根本就没有什么用,把相应的Scene改成object就行了。

from sys import exit 这句是非必须的,还有P144页那里,第100行return 'finished'

是错的,因为根本就没这个函数,到了那里游戏已经赢了,改成 exit(0)退出脚本就行了!

(不过绕来绕去的变量赋值有点晕)

    类名使用帕斯卡命名法(也叫大驼峰法)。即每个单词首字母大写。小驼峰法即第一个

单词首字母小写,如myDearMom,函数名和变量名写成带下划线连接的形式。并且写

成动词形式比较直观反映它们的功能。(紫色部分现在看起来是当时太年轻了。殊不知在

一大堆代码里面分好模块是很重要的一件事)

 * Map

    - next_scene

    - openning_scene

* Engine

   - play

* Scene(父类)

   - enter

   * Death

   * Central Corridor

   * Laser Weapon Armory

   * The Bridge

   * Escape Pod                                                               ——改自 2016/10.31晚

--------------------------------------------------------------------------------------

 另外,偶把密码打印了出来。不然,绝对没有可能猜中的...

【页面最下方有无注释版本】

  1 # coding: utf-8
  2 
  3 # 如果是 import random, 下面就要用random.randint()的格式    
  4 from sys import exit
  5 from random import randint   
  6 
  7 class Engine(object):
  8 
  9     # 如果不需要对象(类的实例)如Map()带参数,可以不用初始化
 10     def __init__(self, scene_map):
 11         # 这里的scene_map就是Map类的对象,也就是a_map,即Map('central_corridor')
 12         self.scene_map = scene_map
 13     
 14     def play(self):
 15         # opening_scene()是Map类的函数,作用是返回next_scene函数,从而获取scens字典的第
 16         # 一个值,即CentralCorridor类
 17         current_scene = self.scene_map.opening_scene()    
 18 
 19         while True:
 20             print "\n---------------------------------"
 21             # 第一个场景是中央走廊, CentralCorridor().enter()之后,选择讲笑话的话就会
 22             # 返回the_bridge
 23             next_scene_name = current_scene.enter()       
 24             # next_scene函数的作用就是获取scenes字典中键名 next_scene_nam 对应的值,选
 25             # 择讲笑话的话就会进入下一个场景
 26             
 27             current_scene = self.scene_map.next_scene(next_scene_name)
 28 
 29 class Death(object):
 30     
 31     quips = [
 32           "You died. You kinda suck at this.", # kinda: 有点; suck: 糟糕
 33           "Your mom would be pround...if she were smarter.",
 34           "Such a luser.",  # luser: 失败者
 35           "I have a small puppy that's better at this." # puppy: 宝宝
 36     ]
 37 
 38     def enter(self):
 39         # 从quips列表4个元素中随机选1个作为死亡时的回答
 40         print Death.quips[randint(0, len(self.quips) - 1)] 
 41         exit(1)
 42 
 43 class CentralCorridor(object): 
 44     
 45     def enter(self):
 46         print u"来自25号行星的哥顿人入侵了你的船队,杀死你的全体船员。你是唯一的幸存者,所 "
 47         print u"以你最后的任务是从武器库拿到中子。打击炸弹。把它带到舰桥,然后在你逃到救生 "
 48         print u"舱前将船炸掉。当一个长满鳞片,满口黑牙,还穿着邪恶小丑服的哥顿人, 令人讨厌 "
 49         print u"地摇摆着跳出来时,你得跑到中央走廊到达武器库。他会堵住到武器库的大门然后将 "
 50         print u"会拿着武器炸死你。"
 51 
 52         action = raw_input("> ")
 53 
 54         if action == "shoot":
 55             print u"你猛地拿起你的炸弹朝着哥顿人开火,他的小丑服飘了起来,导致了你受到干扰。"
 56             print u"你的激光打到了他的衣服上却没有伤到他,倒是完全把他妈妈刚给他买的衣服商。"
 57             print u"标给毁了。气得他上窜下跳,反复地打你的头,直到你死去为止。"  
 58             return 'death'
 59 
 60         elif action == "dodge":
 61             print u"当哥顿人的爆破手发射激光飞过你的头部时,你像一个世界级拳击手一样躲闪和迂"
 62             print u"回前进,成功地溜走和躲了起来。在你艺术性地躲闪时你滑倒了然后狠狠地撞穿了金"
 63             print u"属墙,在你短暂地醒来后大概只有死在把你踩在脚下的哥顿人手里和被吃的命运。"
 64             return 'death'
 65 
 66         elif action == "tell a joke":
 67             print u"幸运的是他们让你尝到了哥顿人在学院学的侮辱别人的方式。你告诉一个哥顿人你所"
 68             print u"知的笑话。哥顿人停了下来强忍着不去笑但最终还是笑得动弹不得。就在他狂笑不止"
 69             print u"时你趁机逃走了,然后射中他的头。把他弄趴下了,然后朝着武器库的大门跑去。"
 70             return 'laser_weapon_armory'
 71 
 72         else:
 73             print "Does not compute!"
 74             return 'central_corridor'
 75 
 76 class LaserWeaponArmory(object):
 77 
 78     def enter(self): 
 79         print u"你做了一个鲤鱼式的翻滚进了武器库, 蹲在大门前扫视着可能躲在暗处的哥顿人。 太安静"
 80         print u"了,你站了起来朝着远离大门的方向跑去,居然让你发现了装着中子炸弹的容器。但是上面"
 81         print u"有密码锁,如果你错误地输入密码超过十次密码锁就会永远锁上那样,你就拿不到炸弹了。"
 82         print u"密码是三位数。"
 83         # randint(1, 9) 随机抽取1-9的任1个数字
 84         code = "%d%d%d" % (randint(1, 9), randint(1, 9), randint(1, 9))    
 85         guess = raw_input("[keypad]> ")
 86         guesses = 0
 87 
 88         while guess != code and guesses < 10:
 89             # 在这里我改了下代码,把密码打印了出来,不然,1-9有9种可能,加起来应有9 * 9 * 9种可能,
 90             # 怎么都猜不中!
 91             print code                                
 92             print "BZZZZEDDD!"
 93             guesses += 1
 94             guess = raw_input("[keypad]> ")
 95         
 96             if guess == code:
 97                 print u"容器按下开关打开了,密封状态解除,气体释放了出来。你拿着中子炸弹使劲地跑,"
 98                 print u"到桥上,你必须将它准确无误地安置在合适的地方。"
 99                 return 'the_bridge'
100             else:
101                 print u"密码锁最后一次叫了起来,然后你听到令人作呕混合着机械装置融化和融合的声音."
102                 print u"你决定坐在那儿,最后哥顿人从他们的船上被炸了出来,就这样你死了."
103                 return 'death'
104  
105 class TheBridge(object):
106     
107     def enter(self):
108         print u"在你用中子炸弹炸毁了桥梁后,5个吃惊的哥顿人尝试控制飞船,他们中的每一个人比起之前"
109         print u"那个哥顿人都有着更加丑陋的衣服, 当他们看到你手中将要爆炸的炸弹时,他们甚至没有拿起"
110         print u"他们的武器,也不想关闭它。" 
111         
112         action = raw_input("> ")
113         
114         if action == "throw the bomb":
115             print u"在一片恐慌中你把炸弹扔到了人群中,然后跳出了在大门,就在你逃跑时一个哥顿人从背"
116             print u"后朝你开了一桥,就这样,你死了。临死前,你看到了其他哥顿人疯狂地试着解除炸弹,"
117             print u"你知道当炸弹熄灭时他们很有可能会被炸死。"
118             return 'death'
119 
120         elif action == "slowly place the bomb":
121             print u"你用你的冲击波对着你手下的炸弹,那些哥顿人把他们的手都举了起来, 接着开始不停地冒"
122             print u"汗。你打开背后的大门,小心地把炸弹放到地上,然后用你的冲击波对着它,接着跳出大门"
123             print u"按下最近的按钮,关上在大门。这些哥顿人就无法逃出去了。现在,炸弹已经被你放置好,"
124             print u"所以你逃往救生舱去摆脱它。"
125             return 'escape_pod'
126 
127         else:
128             print "Does not compute!"
129             return "the_bridge"
130 
131 class EscapePod(object):
132     
133     def enter(self):
134         print u"你拼命地朝着救生舱跑去,想在炸弹爆炸前逃离。这会看起来像从来没有哥顿人来过船上一样,"
135         print u"所以你几乎没受到干扰。你用救生舱到达室内。现在你需要选择一个去使用。有5个可选,你想 "
136         print u"选择哪个呢?" 
137 
138         good_pod = randint(1,5)
139         guess = raw_input("[pod #]> ")
140         
141         print good_pod   # 1-5五种可能, 选中几率难, 所以显示好的逃生舱数字
142 
143         if int(guess) != good_pod:
144             print u" 你跳进救生舱%s然后按下发射按钮。" % guess
145             print u" 救生舱飞往外太空。然后爆炸使船体破裂,你的身体碎成果酱。"
146             return 'death'
147         else:          
148             print u"你跳进舱%s内然后按下发射按钮。" % guess
149             print u"救生舱轻易地滑进太空,前往外星球。当它飞到行星时,你往看到你的飞船爆炸的样子。像 "
150             print u"一颗耀眼的恒星。同时带走哥顿人。你赢了!"      
151             return 'finished'
152 
153 class Map(object):
154 
155     scenes = {
156          'central_corridor': CentralCorridor(),
157          'laser_weapon_armory': LaserWeaponArmory(),
158          'the_bridge': TheBridge(),
159          'escape_pod': EscapePod(),
160          'death': Death()
161     }
162 
163     # Map类带不带参数取决于是否初始化,或者初始化时参数是否多于1个
164     def __init__(self, start_scene):
165         self.start_scene = start_scene
166 
167     def next_scene(self, scene_name):
168         return Map.scenes.get(scene_name)
169 
170     # 该函数的作用是返回next_scene函数,其实就是执行next_scene函数,所以
171     def opening_scene(self):                     
172         return self.next_scene(self.start_scene)
173 
174 a_map = Map("central_corridor")
175 a_game = Engine(a_map)
176 a_game.play()
点我

 

-------------------------下面是用正则表达式匹配原代码的内容---------------------------------

        如果大家觉得上面的代码有点凌乱, 可以把里面的中文抓出来对照着看(为了整齐

被我调整了行数,不过每一部分的中文与代码都是对应的 !

        此外有个要注意的地方, 就是中文解码那里, 目前我发现控制台(powershell)只

能显示经过解码然后再转码过的str型或者经由utf-8解码为unicode的中文 !

 

假设我们的代码保存在ta.py文件中

 1 # coding: utf-8
 2 
 3 # 导入正则表达式 regex: (regular expression)
 4 import re
 5 
 6 file = open("ta.py")
 7 content = file.read()
 8 
 9 # findall可以我们要匹配的对象以列表的形式输出, '.' 匹配任意字符1次, '+' 匹配
10 # 前面的字符1到多次, 该正则表达式表示把文本里面的"print u"(注意转义双引号")后面双引号包围的内容匹配出来 
11 list = re.findall(u"print u\"(.+)\"", content.decode("utf-8"))
12 
13 for eachline in list:
14     print eachline
提取中文

只想匹配注释的话

 1 # coding: utf-8
 2 
 3 # re: (regex—regular expression)正则表达式
 4 import re
 5 
 6 file = open("ta.py")
 7 content = file.read()
 8 
 9 # findall可以我们要匹配的对象以列表的形式输出, '.' 匹配任意字符1次, '+' 匹配
10 # 前面的字符1到多次, 该正则表达式表示把文本里面的"# "(注意空格)后面的内容匹配出来 
11 list = re.findall(u"# .+", content.decode("utf-8"))
12 
13 for eachline in list:
14     print eachline
提取注释

由于中文字符在列表中是以内部编码的形式显示的,所以要用for语句把它们从列表中取出来!

                                                                                            

                                                                                       ——改自2016/8.28晚

只想把注释在的那行取消掉的话

先从简单的开始, 这是我切身的教训,当要删除一大串文本中的某些内容时,删除就等于替换

由于第一句编码声明会给删掉,所以大家自个加上去吧!

方法一:

 1 # coding: utf-8
 2 
 3 import re
 4 
 5 f = open("ta.py")
 6 content = f.read()
 7 
 8 # 井号后面一定要有空格,因为我们代码中有一句
 9 # guess = raw_input("[pod #]> ")是带井号的
10 
11 for eachline in content.split("\n"):
12     print re.sub("# .+", "", eachline)
用sub()替换

方法二:

 1 # coding: utf-8
 2 
 3 # re: regx(regular expression)正则表达式
 4 import re
 5 
 6 f = open("ta.py")
 7 content = f.read()
 8 
 9 # re.findall()将匹配结果以列表的形式输出
10 # join()将列表或元组以字符串的形式输出
11 
12 for eachline in content.split("\n"):
13     
14     if "#" in eachline:
15         list = re.findall("(.+guess.+|.+(?=# .+))", eachline)
16         print "".join(list)
用findall()替换

        此处又有坑,由于findall匹配不到正则表达式的内容时,会输出空白符,所以在管道符

号这里不能有多个括号(最外边的那个是必须的), 不然会返回元组列表而导致出错,join()只

能处理列表或者元组,对于元组列表它无能为力~

------------------------------------------------------------------------------------------

删掉注册行     

      这又是一个难点,替换掉注释不难,但要同时删除注释行就难了,特别是在各种注释风格

混合的时候 。

      注意,此处用re.split(" (?=#.+)", eachline)表示分割掉#前面的空格,也就是说,这

句神奇的代码可以把带#的代码如

3     # 如果不需要对象(类的实例)如Map()带参数,可以不用初始化 ——> ["   ", "# ..."]
141         print good_pod   # 1-5五种可能, 选中几率难, 所以显示好的逃生舱数字 ——> ["        print...", "# "]

 

        用另一个for语句把它们迭代出来,把不符合条件的"# ..." 或者是"       "给去掉,set()

函数就是把重复的字符串去掉重复的部分,或者把列表元素给去掉重复的,所以就会出现下面

list(set(each))= [" "] 这种情况,也是要剔除的对象 ! ! !

 1 # coding: utf-8
 2 
 3 # 导入正则表达式(regex)模块
 4 import re
 5 
 6 f = open("2.py")
 7 content = f.read()
 8 
 9 # 按行划分成列表
10 content = content.split("\n")
11 
12 for eachline in content:
13     
14     # 这里井号加空格同样是为了避免匹配 guess = raw_input("[pod #]> ") 
15     if "# " in eachline:
16         newlist = re.split(" (?=#.+)", eachline)
17         for each in newlist:
18             # pass语句就是起到防止if语句下面不加代码出错而已
19             if "#" in each or list(set(each)) == [" "]:
20                 pass
21             else:
22                 print each
23     else:
24         print eachline
删除注释行

        假设我们的代码保存在"1.py"文件里

-----------------------------------------------------------------------------------------------

无注释版

  1 # coding: utf-8
  2 
  3 from sys import exit
  4 from random import randint   
  5 
  6 class Engine(object):
  7 
  8     def __init__(self, scene_map):
  9         self.scene_map = scene_map
 10     
 11     def play(self):
 12         current_scene = self.scene_map.opening_scene()    
 13 
 14         while True:
 15             print "\n---------------------------------"
 16             next_scene_name = current_scene.enter()       
 17             
 18             current_scene = self.scene_map.next_scene(next_scene_name)
 19 
 20 class Death(object):
 21     
 22     quips = [
 23           "You died. You kinda suck at this.",
 24           "Your mom would be pround...if she were smarter.",
 25           "Such a luser.", 
 26           "I have a small puppy that's better at this."
 27     ]
 28 
 29     def enter(self):
 30         print Death.quips[randint(0, len(self.quips) - 1)] 
 31         exit(1)
 32 
 33 class CentralCorridor(object): 
 34     
 35     def enter(self):
 36         print u"来自25号行星的哥顿人入侵了你的船队,杀死你的全体船员。你是唯一的幸存者,所 "
 37         print u"以你最后的任务是从武器库拿到中子。打击炸弹。把它带到舰桥,然后在你逃到救生 "
 38         print u"舱前将船炸掉。当一个长满鳞片,满口黑牙,还穿着邪恶小丑服的哥顿人, 令人讨厌 "
 39         print u"地摇摆着跳出来时,你得跑到中央走廊到达武器库。他会堵住到武器库的大门然后将 "
 40         print u"会拿着武器炸死你。"
 41 
 42         action = raw_input("> ")
 43 
 44         if action == "shoot":
 45             print u"你猛地拿起你的炸弹朝着哥顿人开火,他的小丑服飘了起来,导致了你受到干扰。"
 46             print u"你的激光打到了他的衣服上却没有伤到他,倒是完全把他妈妈刚给他买的衣服商。"
 47             print u"标给毁了。气得他上窜下跳,反复地打你的头,直到你死去为止。"  
 48             return 'death'
 49 
 50         elif action == "dodge":
 51             print u"当哥顿人的爆破手发射激光飞过你的头部时,你像一个世界级拳击手一样躲闪和迂"
 52             print u"回前进,成功地溜走和躲了起来。在你艺术性地躲闪时你滑倒了然后狠狠地撞穿了金"
 53             print u"属墙,在你短暂地醒来后大概只有死在把你踩在脚下的哥顿人手里和被吃的命运。"
 54             return 'death'
 55 
 56         elif action == "tell a joke":
 57             print u"幸运的是他们让你尝到了哥顿人在学院学的侮辱别人的方式。你告诉一个哥顿人你所"
 58             print u"知的笑话。哥顿人停了下来强忍着不去笑但最终还是笑得动弹不得。就在他狂笑不止"
 59             print u"时你趁机逃走了,然后射中他的头。把他弄趴下了,然后朝着武器库的大门跑去。"
 60             return 'laser_weapon_armory'
 61 
 62         else:
 63             print "Does not compute!"
 64             return 'central_corridor'
 65 
 66 class LaserWeaponArmory(object):
 67 
 68     def enter(self): 
 69         print u"你做了一个鲤鱼式的翻滚进了武器库, 蹲在大门前扫视着可能躲在暗处的哥顿人。 太安静"
 70         print u"了,你站了起来朝着远离大门的方向跑去,居然让你发现了装着中子炸弹的容器。但是上面"
 71         print u"有密码锁,如果你错误地输入密码超过十次密码锁就会永远锁上那样,你就拿不到炸弹了。"
 72         print u"密码是三位数。"
 73         code = "%d%d%d" % (randint(1, 9), randint(1, 9), randint(1, 9))    
 74         guess = raw_input("[keypad]> ")
 75         guesses = 0
 76 
 77         while guess != code and guesses < 10:
 78             print code                                
 79             print "BZZZZEDDD!"
 80             guesses += 1
 81             guess = raw_input("[keypad]> ")
 82         
 83             if guess == code:
 84                 print u"容器按下开关打开了,密封状态解除,气体释放了出来。你拿着中子炸弹使劲地跑,"
 85                 print u"到桥上,你必须将它准确无误地安置在合适的地方。"
 86                 return 'the_bridge'
 87             else:
 88                 print u"密码锁最后一次叫了起来,然后你听到令人作呕混合着机械装置融化和融合的声音."
 89                 print u"你决定坐在那儿,最后哥顿人从他们的船上被炸了出来,就这样你死了."
 90                 return 'death'
 91  
 92 class TheBridge(object):
 93     
 94     def enter(self):
 95         print u"在你用中子炸弹炸毁了桥梁后,5个吃惊的哥顿人尝试控制飞船,他们中的每一个人比起之前"
 96         print u"那个哥顿人都有着更加丑陋的衣服, 当他们看到你手中将要爆炸的炸弹时,他们甚至没有拿起"
 97         print u"他们的武器,也不想关闭它。" 
 98         
 99         action = raw_input("> ")
100         
101         if action == "throw the bomb":
102             print u"在一片恐慌中你把炸弹扔到了人群中,然后跳出了在大门,就在你逃跑时一个哥顿人从背"
103             print u"后朝你开了一桥,就这样,你死了。临死前,你看到了其他哥顿人疯狂地试着解除炸弹,"
104             print u"你知道当炸弹熄灭时他们很有可能会被炸死。"
105             return 'death'
106 
107         elif action == "slowly place the bomb":
108             print u"你用你的冲击波对着你手下的炸弹,那些哥顿人把他们的手都举了起来, 接着开始不停地冒"
109             print u"汗。你打开背后的大门,小心地把炸弹放到地上,然后用你的冲击波对着它,接着跳出大门"
110             print u"按下最近的按钮,关上在大门。这些哥顿人就无法逃出去了。现在,炸弹已经被你放置好,"
111             print u"所以你逃往救生舱去摆脱它。"
112             return 'escape_pod'
113 
114         else:
115             print "Does not compute!"
116             return "the_bridge"
117 
118 class EscapePod(object):
119     
120     def enter(self):
121         print u"你拼命地朝着救生舱跑去,想在炸弹爆炸前逃离。这会看起来像从来没有哥顿人来过船上一样,"
122         print u"所以你几乎没受到干扰。你用救生舱到达室内。现在你需要选择一个去使用。有5个可选,你想 "
123         print u"选择哪个呢?" 
124 
125         good_pod = randint(1,5)
126         guess = raw_input("[pod #]> ")
127         
128         print good_pod  
129 
130         if int(guess) != good_pod:
131             print u" 你跳进救生舱%s然后按下发射按钮。" % guess
132             print u" 救生舱飞往外太空。然后爆炸使船体破裂,你的身体碎成果酱。"
133             return 'death'
134         else:          
135             print u"你跳进舱%s内然后按下发射按钮。" % guess
136             print u"救生舱轻易地滑进太空,前往外星球。当它飞到行星时,你往看到你的飞船爆炸的样子。像 "
137             print u"一颗耀眼的恒星。同时带走哥顿人。你赢了!"      
138             return 'finished'
139 
140 class Map(object):
141 
142     scenes = {
143          'central_corridor': CentralCorridor(),
144          'laser_weapon_armory': LaserWeaponArmory(),
145          'the_bridge': TheBridge(),
146          'escape_pod': EscapePod(),
147          'death': Death()
148     }
149 
150     def __init__(self, start_scene):
151         self.start_scene = start_scene
152 
153     def next_scene(self, scene_name):
154         return Map.scenes.get(scene_name)
155 
156     def opening_scene(self):                     
157         return self.next_scene(self.start_scene)
158 
159 a_map = Map("central_corridor")
160 a_game = Engine(a_map)
161 a_game.play()
无注释版

                                                                                       ——2016/9.7晚23:30(断网,次日晚补充)

 

posted @ 2016-08-01 00:13  坏小孩D_R  阅读(293)  评论(0编辑  收藏  举报