# ==========================================
# 🎮 少年侠客闯江湖 - 第 8 课
# 📚 本课知识点:文件读写、json、try-except
# ==========================================
import random
import json
from datetime import datetime
# --- 游戏数据(同第 7 课)---
monsters = [
{"name": "狐妖", "hp": 30, "attack": 8, "silver_drop": 10, "item_drop": "狐妖尾毛"},
{"name": "山魅", "hp": 40, "attack": 12, "silver_drop": 15, "item_drop": "山魅石"},
]
npcs = [
{"name": "白胡老者", "riddle": "什么东西越长越短?", "answer": "蜡烛", "silver_correct": 15, "silver_wrong": 3},
]
# TODO: 定义 save_game(hero) 函数
# 提示:用 json.dump 把 hero 数据保存到 save.json
# TODO: 定义 load_game() 函数
# 提示:用 try-except 处理 FileNotFoundError
# TODO: 游戏开头添加 "1-新游戏 2-继续冒险" 选择
# (以下为第 7 课的函数和主逻辑)
# 🎮 少年侠客闯江湖 - 第 8 课(参考答案)
# 知识点:文件读写、json、try-except | 请先让孩子自己尝试!
import random, json
from datetime import datetime
# --- 游戏数据 ---
monsters = [
{"name": "狐妖", "hp": 30, "attack": 8, "silver_drop": 10, "item_drop": "狐妖尾毛"},
{"name": "山魅", "hp": 40, "attack": 12, "silver_drop": 15, "item_drop": "山魅石"},
{"name": "火鸦", "hp": 50, "attack": 15, "silver_drop": 20, "item_drop": "火鸦羽"},
]
npcs = [
{"name": "白胡老者", "riddle": "什么东西越长越短?", "answer": "蜡烛", "silver_correct": 15, "silver_wrong": 3},
{"name": "书生", "riddle": "四面都是山,中间有个田", "answer": "画", "silver_correct": 12, "silver_wrong": 3},
]
routes = [("忘忧山", "清风鸟语"), ("龙王洞", "阴暗潮湿"), ("幽灵峰", "雷电交加")]
# --- 函数定义 ---
def battle(hero, monster):
"""回合制战斗"""
print(f"\n⚔️ {monster['name']}出现!HP:{monster['hp']} ATK:{monster['attack']}")
while hero["hp"] > 0 and monster["hp"] > 0:
dmg = random.randint(5, hero["attack"])
monster["hp"] -= dmg
print(f"💥 攻击{monster['name']}!伤害 {dmg},剩余 {max(monster['hp'],0)}")
if monster["hp"] <= 0:
break
m_dmg = random.randint(3, monster["attack"])
hero["hp"] -= m_dmg
print(f"👹 {monster['name']}反击!伤害 {m_dmg},剩余 {max(hero['hp'],0)}")
if hero["hp"] > 0:
hero["silver"] += monster["silver_drop"]
hero["battles_won"] += 1
print(f"🎉 击败!+{monster['silver_drop']}银两")
if monster.get("item_drop") and len(hero["backpack"]) < 10:
hero["backpack"].append(monster["item_drop"])
print(f"🎁 获得:{monster['item_drop']}")
return True
return False
def talk_to_npc(hero, npc):
"""NPC 问答"""
riddle = npc['riddle']
print(f"\n🧙 遇到{npc['name']}!'{riddle}'")
if input("答案:") == npc["answer"]:
hero["silver"] += npc["silver_correct"]
print(f"✨ +{npc['silver_correct']}银两")
else:
hero["silver"] += npc["silver_wrong"]
answer = npc['answer']
print(f"😊 答案是'{answer}'。+{npc['silver_wrong']}银两")
def save_game(hero):
"""保存游戏存档"""
save_data = {"hero": hero, "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")}
with open("save.json", "w", encoding="utf-8") as f:
json.dump(save_data, f, ensure_ascii=False, indent=2)
print("💾 存档成功!")
def load_game():
"""加载存档,失败返回 None"""
try:
with open("save.json", "r", encoding="utf-8") as f:
save_data = json.load(f)
print(f"📂 读档成功!欢迎回来,{save_data['hero']['name']}!")
return save_data["hero"]
except FileNotFoundError:
print("❌ 没有找到存档!")
return None
except json.JSONDecodeError:
print("❌ 存档文件损坏!")
return None
def show_status(hero):
"""打印状态卡"""
print(f"\n╔{'═' * 28}╗")
print(f"║ 📋 {hero['name']} HP:{max(hero['hp'],0)}/{hero['max_hp']}")
print(f"║ ATK:{hero['attack']} 💰{hero['silver']} ⚔️{hero['battles_won']}胜")
print(f"║ 🎒 {', '.join(hero['backpack']) or '空'}")
print(f"╚{'═' * 28}╝")
# --- 主程序 ---
print("=" * 40)
print(" ⚔️ 少年侠客闯江湖 ⚔️")
print("=" * 40)
print("\n1. 🆕 新游戏")
print("2. 📂 继续冒险")
start = input("请选择:")
if start == "2":
hero = load_game()
if start != "2" or hero is None:
name = input("\n少年侠客,请赐名:")
hero = {"name": name, "hp": 100, "max_hp": 100, "attack": 15,
"silver": 0, "backpack": [], "battles_won": 0, "adventures": 0}
print(f"\n【{hero['name']}】出发冒险!\n路线:1.忘忧山 2.龙王洞 3.幽灵峰")
c = input("选择(1/2/3):")
r_name = routes[int(c)-1][0] if c in "123" else routes[0][0]
print(f"\n踏上{r_name}...")
for i in range(3):
if hero["hp"] <= 0:
break
print(f"\n--- 第 {i+1} 次遭遇 ---")
if random.choice(["妖怪", "仙人"]) == "妖怪":
if not battle(hero, dict(random.choice(monsters))):
break
else:
talk_to_npc(hero, random.choice(npcs))
hero["adventures"] += 1
show_status(hero)
save_game(hero)