[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流的使用,这个最重要的是搞清水流的方向。
最后,在本章中小墨的《小墨历险记》还有一些功能没有完成,小读者们,你能和小墨一起来完成吗?