💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[Toc] # 第9章 IO流 又是一个周末。小墨使用最新学的函数知识丰富了《小墨历险记》: * 在游戏开始加入了墨家村英雄榜供玩家选择角色; * 加入了关卡,整个游戏设置了5个boss,难度逐渐升级; * 你需要一直战斗,但是每过一个关卡会奖励和关卡难度相对应的生命值。 最后在加入保存游戏进度功能的过程中出现了问题。看墨哥哥也在家,小墨就来找哥哥了。 最新的一款小墨历险记究竟什么样?小墨遇到的问题,墨哥哥又是如何解决的呢?一起来看看吧。 时间:又一个周末 地点:小墨家 小墨:墨哥哥,我又做了一款新的小墨历险记,加入了你之前讲的一些情节。但是现在遇到了点问题,你有时间了帮我看看吧? 墨哥哥:好啊小墨,现在就有时间。 小墨:那我先说说我做了哪些功能。 ## 9.1 又一版小墨历险记 小墨:首先,我定义了一个方法叫background,交代故事背景 ``` # 背景介绍 def background(): print("游戏开始……") print("欢迎来到墨家村,如今是妖兽的地盘") ``` 这一款和前面小墨历险记不同的是,游戏的主角不再是小墨,而是由玩家来选择。这里我定义好了一堆角色的数据,用于玩家选择角色: ``` hero_list = [ {'index': 1, 'name': '墨小小', 'hp': 1000, 'mp': 800, 'ap': 45, 'dp': 20, 'skills': ['一墨横空', '墨渡迷津', '墨之纵横', '墨下乾坤'], 'skills_hp': [20, 45, 75, 100], 'is_warrior': True, 'is_mage': False, 'is_hunter': False, }, {'index': 2, 'name': '墨小妹', 'hp': 1200, 'mp': 700, 'ap': 35, 'dp': 21, 'skills': ['貂蝉拜月', '西施捧心', '昭君出塞', '贵妃醉酒'], 'skills_hp': [18, 23, 47, 82], 'is_warrior': True, 'is_mage': True, 'is_hunter': False, }, {'index': 3, 'name': '墨大元', 'hp': 1100, 'mp': 600, 'ap': 38, 'dp': 17, 'skills': ['千里横行', '寒刀断水', '狂龙破日', '天地无情'], 'skills_hp': [26, 51, 80, 102], 'is_warrior': True, 'is_mage': False, 'is_hunter': True, }, {'index': 4, 'name': '墨当归', 'hp': 900, 'mp': 1100, 'ap': 44, 'dp': 17, 'skills': ['流水行云', '披云戴月', '翻云覆雨', '排山倒海'], 'skills_hp': [23, 45, 80, 97], 'is_warrior': False, 'is_mage': True, 'is_hunter': False, }, {'index': 5, 'name': '墨鱼儿', 'hp': 1000, 'mp': 1000, 'ap': 42, 'dp': 23, 'skills': ['小楫轻舟', '扁舟一叶', '大江似练', '沧波万顷'], 'skills_hp': [19, 39, 68, 92], 'is_warrior': False, 'is_mage': False, 'is_hunter': True, } ] ``` # [插画:一共5个角色供玩家选择,角色名称如下:] 其实就是把墨家村英雄榜的数据拿过来丰富了一下,添加了index和skills_hp字段。这里index表示角色的编号,skills_hp表示技能列表skills对应的伤害列表。 玩家有多种方式选择角色,可以直接输入角色编号直接选择;也可以输入角色职业比如“战士”,程序就列出所有的战士角色供玩家选择;当然也输入姓名的一部分进行模糊查询来选择: ``` # 选择角色 def select_role(hero_list): print('请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。') for hero in hero_list: print('编号:%s,姓名:%s' % (hero.get('index'), hero.get('name'))) while True: ni = input() if ni == '1' or ni == '2' or ni == '3' or ni == '4' or ni == '5': hero = hero_list[int(ni) - 1] print('你选择了%s' % hero.get('name')) return hero elif ni == '战士': select_roles_by_career(hero_list, 'is_warrior') continue elif ni == '法师': select_roles_by_career(hero_list, 'is_mage') continue elif ni == '猎人': select_roles_by_career(hero_list, 'is_hunter') continue else: select_role_by_name(hero_list, ni) continue ``` 有可能玩家挑挑选选了多次才最终下了决心选哪个角色,所以这里我使用了死循环,能够让玩家一直挑。而如果玩家输入了1-5中的一个,就将某个角色信息打印并使用return返回。这样就挑选好了一个角色了。 墨哥哥:这里的select_roles_by_career和select_role_by_name就是根据职业和根据名字查找角色了对吧? 小墨:是的,这是我独立出来的两个方法。select_roles_by_career是按照职业选择角色,会列出对应职业的角色。它有两个参数,第一个是角色的列表也即所有角色,第二个是职业的标志: ``` # 列出所有该职业的角色 def select_roles_by_career(hero_list, career): for x in hero_list: if x.get(career): print('编号:%s,姓名:%s' % (x.get('index'), x.get('name'))) ``` select_role_by_name是模糊查询,根据输入的内容ni进行模糊匹配: ``` # 模糊查询所有和输入匹配的角色信息 def select_role_by_name(hero_list, name_like): flag = False for x in hero_list: if name_like in x.get('name'): print('编号:%s,姓名:%s' % (x.get('index'), x.get('name'))) flag = True if not flag: print('没有找到对应的角色') print('请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。') ``` 这里我定义了一个flag标志位,用于如果没有任何一个角色的名字和输入的内容相匹配的情况。比如玩家输入了“天”,5个角色中没有名字中含“天”的,此时就提醒用户没有找到对应的角色,让他重新挑选。 墨哥哥:运行看看结果。 ``` 游戏开始…… 欢迎来到墨家村,如今是妖兽的地盘 请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。 编号:1,姓名:墨小小 编号:2,姓名:墨小妹 编号:3,姓名:墨大元 编号:4,姓名:墨当归 编号:5,姓名:墨鱼儿 战士 编号:1,姓名:墨小小 编号:2,姓名:墨小妹 编号:3,姓名:墨大元 法师 编号:2,姓名:墨小妹 编号:4,姓名:墨当归 大 编号:3,姓名:墨大元 天 没有找到对应的角色 请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。 墨 编号:1,姓名:墨小小 编号:2,姓名:墨小妹 编号:3,姓名:墨大元 编号:4,姓名:墨当归 编号:5,姓名:墨鱼儿 1 你选择了墨小小 ``` 嗯,看起来不错嘛。 小墨:哈哈,再接着来看我的战斗过程。之前是和狂风战斗,这一版我也改了,改成了一共5个关卡,每个关卡都有一个boss守着,玩家需要连续战胜5个boss才能夺回墨家村。5个boss相关的数据是这样的: ``` boss_list = [ {'mission_index': 1, 'mission_name': '呼啸山谷', 'name': '狂风', 'hp': 100, 'max_attack': 200, 'min_attack': 100}, {'mission_index': 2, 'mission_name': '暴雨中的十里铺', 'name': '狂雨', 'hp': 200, 'max_attack': 200, 'min_attack': 20}, {'mission_index': 3, 'mission_name': '雷暴下的墨河下游', 'name': '狂雷', 'hp': 500, 'max_attack': 100, 'min_attack': 90}, {'mission_index': 4, 'mission_name': '雷暴下的墨河上游', 'name': '狂电', 'hp': 1000, 'max_attack': 220, 'min_attack': 50}, {'mission_index': 5, 'mission_name': '燃烧的墨家村', 'name': '狂火', 'hp': 10000, 'max_attack': 20, 'min_attack': 10} ] ``` 其中mission_index表示关卡编号,mission_name表示关卡名字,name表示这一关的boss的名字,max_attack表示这一关boss的最大攻击力,min_attack是最小攻击力,也就是说每一关大的boss都会随机攻击,范围就是这两个值之间。 墨哥哥:嗯,剧情不错,原来你也很能编故事。 小墨:这不都是跟你学的嘛。 接着我定义了一个方法,用于和boss战斗: ``` # 战斗:某一关卡 def fight(hero, boss): print('你来到了第%s关:%s。本关boss:%s' % (boss.get('mission_index'), boss.get('mission_name'), boss.get('name'))) # 根据传入的角色,获取角色的技能列表、技能伤害列表和角色的血量 skills = hero.get('skills') skills_hp = hero.get('skills_hp') hp_player = hero.get('hp') # 根据传入的boss,获取boss的名称和boss的血量 name_boss = boss.get('name') hp_boss = boss.get('hp') while True: print('快输入数字攻击他!') # 介绍角色技能 for i in range(len(skills)): print('输入数字%s释放第%s个技能:%s' % (i + 1, i + 1, skills[i])) # 接收用户输入的数字 input_ni = int(input()) # 如果是1-5 if input_ni == 1 or input_ni == 2 or input_ni == 3 or input_ni == 4 or input_ni == 5: # 玩家的随机攻击伤害值:技能对应的伤害加上1-50的随机值 attack_player = random.randint(1, 50) + skills_hp[input_ni - 1] # boss扣血 hp_boss -= attack_player # 如果boss血量在被攻击之后小于0了则将血量置为0,防止输出boss血量为负的情况 if hp_boss < 0: hp_boss = 0 print( "你使用%s击中了%s,打出了%s点的伤害,%s剩余血量%s" % (skills[input_ni - 1], name_boss, attack_player, name_boss, hp_boss)) if hp_boss > 0: # 判断boss是否已死,血量大于0说明还活着,活着就会反击 # boss的随机反击伤害值 attack_boss = random.randint(boss.get('min_attack'), boss.get('max_attack')) # 玩家扣血 hp_player -= attack_boss # 如果玩家血量在被攻击之后小于0了则将血量置为0,防止输出血量为负的情况 if hp_player < 0: hp_player = 0 print("愤怒的%s发起了反击,对你造成了%s点伤害,你当前剩余血量%s" % (name_boss, attack_boss, hp_player)) if hp_player == 0: # 判断玩家是否已死 return False else: # 更新角色血量 hero['hp'] = hp_player else: print("%s,恭喜你,击败了%s!完成了本关卡的挑战" % (hero.get('name'), name_boss)) # 如果过关,奖励本关编号*200的血量 hero['hp'] = hp_player + int(boss.get('mission_index')) * 200 print('*' * 50) return True # 如果用户输入的不是1-5,则提醒用户 else: print('快输入数字键1-5攻击%s!' % name_boss) ``` 这个方法接收两个参数,一个hero表示用户选择的角色,这个实际调用时候传入挑选好的角色就行了。第二个参数是boss,也即boss列表中的某一个。这个方法只是和1个boss进行战斗,想跟所有boss都战斗一遍,还是用循环,我定义了fight_all_boss的方法: ``` # 战斗:所有关卡 def fight_all_boss(hero, boss_list): for boss in boss_list: if not fight(hero, boss): print("很遗憾,你未能完成冒险,请休息片刻重新开始。。。") break # 结束游戏 ``` 在和某一个boss战斗过程中,肯定会有失败的情况,这个时候游戏就应该结束了。所以我在fight方法中,如果用户血量小于0,就返回False,结束fight方法。在fight_all_boss中,如果not fight,也即fight返回False的情况,就结束游戏。而如果fight没有返回False,则说明过关了,fight_all_boss就继续循环,从而玩家继续战斗。 打斗结果如下: ``` 你来到了第1关:呼啸山谷。本关boss:狂风 快输入数字攻击他! 输入数字1释放第1个技能:一墨横空 输入数字2释放第2个技能:墨渡迷津 输入数字3释放第3个技能:墨之纵横 输入数字4释放第4个技能:墨下乾坤 4 你使用墨下乾坤击中了狂风,打出了143点的伤害,狂风剩余血量0 墨小小,恭喜你,击败了狂风!完成了本关卡的挑战 ************************************************** 你来到了第2关:暴雨中的十里铺。本关boss:狂雨 快输入数字攻击他! 输入数字1释放第1个技能:一墨横空 输入数字2释放第2个技能:墨渡迷津 输入数字3释放第3个技能:墨之纵横 输入数字4释放第4个技能:墨下乾坤 4 你使用墨下乾坤击中了狂雨,打出了145点的伤害,狂雨剩余血量55 愤怒的狂雨发起了反击,对你造成了129点伤害,你当前剩余血量1071 快输入数字攻击他! 输入数字1释放第1个技能:一墨横空 输入数字2释放第2个技能:墨渡迷津 输入数字3释放第3个技能:墨之纵横 输入数字4释放第4个技能:墨下乾坤 4 你使用墨下乾坤击中了狂雨,打出了141点的伤害,狂雨剩余血量0 墨小小,恭喜你,击败了狂雨!完成了本关卡的挑战 ************************************************** 你来到了第3关:雷暴下的墨河下游。本关boss:狂雷 快输入数字攻击他! 输入数字1释放第1个技能:一墨横空 输入数字2释放第2个技能:墨渡迷津 输入数字3释放第3个技能:墨之纵横 输入数字4释放第4个技能:墨下乾坤 …… (篇幅原因,这里不再全部列出) ``` 为了游戏的趣味性和平衡性,我还在每一关卡过关的时候奖励玩家关卡编号乘以200的血量。 墨哥哥:整体来说还是很不错的。不过你这个应该还没有做完吧,按照目前的代码,玩家一直输入4攻击boss就行了,因为技能4是伤害最大的。 小墨:嗯我还没有做完呢。你看角色有个mp,表示角色的魔法量,释放技能是需要消耗魔法的,后面会从这一块做限制。另外现在玩家是随机攻击,后面攻击力也会去使用ap的值,那是定义的攻击力。还有dp表示防御力,这个我得想想怎么个计算法,让防御力能抵消boss的部分伤害。 墨哥哥:嗯那样的话就完整多了。对了,你要问我什么问题来着? 小墨:是这样的,除了上面需要做的完善之外,我还想加入个保存游戏的功能,比如游戏开始玩家选择了墨小小,此时玩家应该能保存游戏进度,这样下次进来就能继续使用墨小小了;再比如玩家已经探险到第3关了,这时他有事要出去,就需要保存下游戏进度,要不然下次进来又要从第一关开始了。想问的就是,这个保存游戏怎么做? 墨哥哥:程序运行之后,所有的数据都在内存中,程序运行结束之后数据也就从内存中清除了。只有硬盘上的东西是一直存在的,你看你每天开机关机,硬盘上的文件一直存在吧。 小墨:也就是说想要保存的话就是保存到硬盘上的文件里,这样才能一直存在对吗? 墨哥哥:是的。 小墨:那如何将程序中的内容保存到文件中呢? 墨哥哥:这就要用到Python中IO流方面的知识了。 ## 9.2 IO流 墨哥哥:所谓IO流,就是输入(In)输出(Out)流的简写。流是个什么东西呢?以你现在想做的保存玩家数据的功能来说。本来玩家数据在程序里,现在你想把它保存在文件中,如果你把程序看做一个湖,把文件也看做是一个湖,那么问题就变成了如何将程序湖中的水“放”到文件湖中。如何放呢?很简单,我们在两个湖之间挖条小河,让程序湖中的水经过这条小河流到文件湖中就可以了。这条小河就是“流”。 # [插画:两个湖,被一条河连接了起来] 小墨:那什么是输入输出流呢? 墨哥哥:所谓输入输出,其实就是这条河中水流的方向。如果我们以程序湖为参照物,那么从程序湖流向文件湖就称为输出,对应这条小河就是输出流;从文件湖流向程序湖,就称为输入,对应小河就是输入流。而如果我们以文件湖为参照物,那么程序湖流向文件湖就是输入,文件湖流向程序湖就是输出。 小墨:参照物不同,叫法也不同。 墨哥哥:嗯为了避免参照物混乱导致名称混乱,只要固定一方为参照物就行了。由于我们是程序的编写者,就固定程序为参照物。 小墨:那也就是说从程序到文件的称为输出流、从文件到程序的叫输入流。 墨哥哥:是的。另外从程序中拿文件中的内容的过程,称为“读”,对应的将程序中的内容放入文件中的过程,称为“写”。 小墨:明白了。 墨哥哥:在Python中,想使用输出流,也即想把程序中的内容保存到文件中,使用with open语法就可以了: ``` with open('D:/file/role.txt', 'w') as f: f.write('1') ``` 这里的open是Python自带的一个函数,它既可以用来建立输入流也可以用来建立输出流。它的第一个参数是要读或写的文件的路径,第二个参数w是write的简写,表示建立输出流。as用来给open('D://file//role.txt', 'w')起个别名,f就是我起的名字,可以任意。这样一句之后,f就表示建立好的输出流了。接着调用f的write方法就可以将内容写到文件中了。 小墨:我来运行一下。啊,悲剧了…… ``` Traceback (most recent call last): File "D:/my_python/write_demo.py", line 1, in <module> with open('D:/file/role.txt', 'w') as f: FileNotFoundError: [Errno 2] No such file or directory: 'D:/file/role.txt' ``` 墨哥哥:这是因为你D盘下没有file这个文件夹。输出流会自动帮你建立好要输出的文件,但是并不会新建文件夹。另外需要注意的是,在windows系统中,路径可以写作“D:/file/role.txt”或“D:\\\file\\\role.txt”,而不能写成“D:\file\role.txt”。 小墨:这个是转义字符,我曾经听博士说过。现在我在电脑D盘新建一个文件夹,名字叫file,然后再运行,这次可以了!file中多了个role.txt,里面有个数字1。 墨哥哥:和写数据类似,读程序也非常简单: ``` with open('D://file//role.txt', 'r') as f: print(f.read()) ``` 这里open的第二个参数r就是read的意思,表示从文件中读取数据。需要注意的是,读取的文件需要存在,要不然也会出错的。 小墨:好的我已经明白了。我这就去把我的游戏添加存储数据的功能。 先来定义一个方法,用于存储用户数据,只存储用户的编号就行了,拿到编号就可以从角色列表中拿到角色对应的所有数据了: ``` def save_role(save_path, role_index): with open(save_path, 'w') as f: f.write(role_index) ``` 然后定义一个方法,用于将存储的用户编号取出来: ``` def get_role_index(save_path): with open(save_path, 'r') as f: return f.read() ``` 然后在游戏开始的时候加个判断,判断玩家是想重新开始游戏重新挑选角色,还是想从存储的文件中获取角色编号,然后从角色列表中获取该角色。同时需要注意下可能文件是空的里面什么都没有,这时候玩家只能重新挑选角色了: ``` print('重新开始请输入Y,取出存储的角色请输入Q') input_str = input(); if input_str == 'Y': hero = select_role(hero_list) elif input_str == 'Q': # 获取存储角色编号 index = get_role_index("D://file/role.txt") if len(index) == 0: # 文件中内容为空,也即没有存储角色数据 print('没有存储的角色') hero = select_role(hero_list) else: print('进度读取成功') hero = hero_list[int(index) - 1] print('编号:%s,姓名:%s' % (hero.get('index'), hero.get('name'))) ``` 好了,这样我的游戏就加入了保存角色的功能了。 # [插画:进度条:游戏正在存档中……] 完整代码如下: ``` import random # 背景介绍 def background(): print("游戏开始……") print("欢迎来到墨家村,如今是妖兽的地盘") # 选择角色 def select_role(hero_list): print('请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。') for hero in hero_list: print('编号:%s,姓名:%s' % (hero.get('index'), hero.get('name'))) while True: ni = input() if ni == '1' or ni == '2' or ni == '3' or ni == '4' or ni == '5': hero = hero_list[int(ni) - 1] print('你选择了%s' % hero.get('name')) # 存储角色数据 save_role('D://file/role.txt', str(hero.get('index'))) return hero elif ni == '战士': select_roles_by_career(hero_list, 'is_warrior') continue elif ni == '法师': select_roles_by_career(hero_list, 'is_mage') continue elif ni == '猎人': select_roles_by_career(hero_list, 'is_hunter') continue else: select_role_by_name(hero_list, ni) continue def select_roles_by_career(hero_list, career): for x in hero_list: if x.get(career): print('编号:%s,姓名:%s' % (x.get('index'), x.get('name'))) def select_role_by_name(hero_list, name_like): flag = False for x in hero_list: if name_like in x.get('name'): print('编号:%s,姓名:%s' % (x.get('index'), x.get('name'))) flag = True if not flag: print('没有找到对应的角色') print('请输入角色职业或角色姓名查找角色列表、输入角色编号选择角色。') # 打斗 def fight(hero, boss): print('你来到了第%s关:%s。本关boss:%s' % (boss.get('mission_index'), boss.get('mission_name'), boss.get('name'))) skills = hero.get('skills') skills_hp = hero.get('skills_hp') hp_player = hero.get('hp') name_boss = boss.get('name') hp_boss = boss.get('hp') while True: print('快输入数字攻击他!') # 介绍角色技能 for i in range(len(skills)): print('输入数字%s释放第%s个技能:%s' % (i + 1, i + 1, skills[i])) # 接收用户输入的数字 input_ni = int(input()) # 如果是1-5 if input_ni == 1 or input_ni == 2 or input_ni == 3 or input_ni == 4 or input_ni == 5: # 玩家的随机攻击伤害值:技能对应的伤害加上1-5的随机值 attack_player = random.randint(1, 50) + skills_hp[input_ni - 1] # boss扣血 hp_boss -= attack_player # 如果boss血量在被攻击之后小于0了则将血量置为0,防止输出boss血量为负的情况 if hp_boss < 0: hp_boss = 0 print( "你使用%s击中了%s,打出了%s点的伤害,%s剩余血量%s" % (skills[input_ni - 1], name_boss, attack_player, name_boss, hp_boss)) if hp_boss > 0: # 判断boss是否已死,血量大于0说明还活着,活着就会反击 # boss的随机反击伤害值 attack_boss = random.randint(boss.get('min_attack'), boss.get('max_attack')) # 玩家扣血 hp_player -= attack_boss # 如果玩家血量在被攻击之后小于0了则将血量置为0,防止输出血量为负的情况 if hp_player < 0: hp_player = 0 print("愤怒的%s发起了反击,对你造成了%s点伤害,你当前剩余血量%s" % (name_boss, attack_boss, hp_player)) if hp_player == 0: # 判断玩家是否已死 return False else: # 更新角色血量 hero['hp'] = hp_player else: print("%s,恭喜你,击败了%s!完成了本关卡的挑战" % (hero.get('name'), name_boss)) # 如果过关,奖励本关*200的血量 hero['hp'] = hp_player + int(boss.get('mission_index')) * 200 # 保存本关 print('*' * 50) return True # 如果用户输入的不是1-5,则提醒用户 else: print('快输入数字键1-5攻击%s!' % name_boss) def fight_all_boss(hero, boss_list): for boss in boss_list: if not fight(hero, boss): print("很遗憾,你未能完成冒险,请休息片刻重新开始。。。") break # 结束游戏 def get_role_index(save_path): with open(save_path, 'r') as f: return f.read() def save_role(save_path, role_index): with open(save_path, 'w') as f: f.write(role_index) def main(): background() hero_list = [ {'index': 1, 'name': '墨小小', 'hp': 1000, 'mp': 800, 'ap': 45, 'dp': 20, 'skills': ['一墨横空', '墨渡迷津', '墨之纵横', '墨下乾坤'], 'skills_hp': [20, 45, 75, 100], 'is_warrior': True, 'is_mage': False, 'is_hunter': False, }, {'index': 2, 'name': '墨小妹', 'hp': 1200, 'mp': 700, 'ap': 35, 'dp': 21, 'skills': ['貂蝉拜月', '西施捧心', '昭君出塞', '贵妃醉酒'], 'skills_hp': [18, 23, 47, 82], 'is_warrior': True, 'is_mage': True, 'is_hunter': False, }, {'index': 3, 'name': '墨大元', 'hp': 1100, 'mp': 600, 'ap': 38, 'dp': 17, 'skills': ['千里横行', '寒刀断水', '狂龙破日', '天地无情'], 'skills_hp': [26, 51, 80, 102], 'is_warrior': True, 'is_mage': False, 'is_hunter': True, }, {'index': 4, 'name': '墨当归', 'hp': 900, 'mp': 1100, 'ap': 44, 'dp': 17, 'skills': ['流水行云', '披云戴月', '翻云覆雨', '排山倒海'], 'skills_hp': [23, 45, 80, 97], 'is_warrior': False, 'is_mage': True, 'is_hunter': False, }, {'index': 5, 'name': '墨鱼儿', 'hp': 1000, 'mp': 1000, 'ap': 42, 'dp': 23, 'skills': ['小楫轻舟', '扁舟一叶', '大江似练', '沧波万顷'], 'skills_hp': [19, 39, 68, 92], 'is_warrior': False, 'is_mage': False, 'is_hunter': True, } ] print('重新开始请输入Y,取出存储的角色请输入Q') input_str = input(); if input_str == 'Y': hero = select_role(hero_list) elif input_str == 'Q': # 获取存储角色编号 index = get_role_index("D://file/role.txt") if len(index) == 0: print('没有存储的角色') hero = select_role(hero_list) else: print('进度读取成功') hero = hero_list[int(index) - 1] print('编号:%s,姓名:%s' % (hero.get('index'), hero.get('name'))) boss_list = [ {'mission_index': 1, 'mission_name': '呼啸山谷', 'name': '狂风', 'hp': 100, 'max_attack': 200, 'min_attack': 100}, {'mission_index': 2, 'mission_name': '暴雨中的十里铺', 'name': '狂雨', 'hp': 200, 'max_attack': 200, 'min_attack': 20}, {'mission_index': 3, 'mission_name': '雷暴下的墨河下游', 'name': '狂雷', 'hp': 500, 'max_attack': 100, 'min_attack': 90}, {'mission_index': 4, 'mission_name': '雷暴下的墨河上游', 'name': '狂电', 'hp': 1000, 'max_attack': 220, 'min_attack': 50}, {'mission_index': 5, 'mission_name': '燃烧的墨家村', 'name': '狂火', 'hp': 10000, 'max_attack': 20, 'min_attack': 10} ] fight_all_boss(hero, boss_list) # 调用main方法 main() ``` 墨哥哥:写的挺快的嘛!今天天色还早,你继续完善你的游戏吧。 ## 9.3 本章小结 墨哥哥总结:本章主要学习了两方面的内容: * 一是函数的使用。在上一章中墨博士说过,学习函数之后解决问题的思路就变了:把大问题分成小问题,小问题解决了大问题就解决了。但是思路的形成并不是一朝一夕就可以的,这个还需要你多多练习才是。 * 二是IO流的使用,这个最重要的是搞清水流的方向。 最后,在本章中小墨的《小墨历险记》还有一些功能没有完成,小读者们,你能和小墨一起来完成吗?