【类不类三】来自星星的哥顿人与正则表达式
这是用类和函数设计的一个小游戏, 我把原文的内容翻译成中文。
【类不类二】: 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)
方法二:
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匹配不到正则表达式的内容时,会输出空白符,所以在管道符
号这里不能有多个括号(最外边的那个是必须的), 不然会返回元组列表而导致出错,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(断网,次日晚补充)