技术准备
在开始编码之前,我们需要准备开发环境和相关工具。以下是开发 元素大师 所需的技术栈和资源。
1. 技术栈
- 编程语言:Python 3.x(推荐 3.8 或更高版本)。
- 核心库:
random
:生成随机事件,如实验失败或新任务。time
:控制游戏节奏和实验时间。json
:保存和加载游戏状态。pygame
(可选):用于图形界面和反应可视化。
- 数据存储:
- 使用字典存储元素和反应规则。
- 列表存储任务、库存和实验室状态。
- 用户界面:基于命令行界面(CLI)显示元素、任务和交互,图形界面作为扩展。
- 依赖安装:
random
、time
和json
是 Python 标准库,无需额外安装。pygame
(可选):pip install pygame
。
2. 开发环境
确保已安装 Python(可从 python.org 下载)。推荐使用 Visual Studio Code 或 PyCharm 作为开发工具,提供代码补全和调试支持。本游戏的核心版本基于 CLI,扩展部分引入图形界面。项目结构如下:
element_synthesis_game/
├── main.py # 主程序入口
└── game.py # 游戏逻辑模块
3. 游戏目标
玩家将扮演化学家,目标是在 30 个回合(模拟 30 天)内完成所有实验任务,解锁所有反应并提升实验室等级。游戏采用回合制,每回合代表一天,玩家需要:
- 合成元素:组合基础元素生成新元素或化合物。
- 完成任务:合成指定目标,获得能量点和声誉。
- 升级实验室:提升设备等级,解锁高级反应。
- 管理资源:平衡能量、时间和元素库存。
- 应对事件:处理实验失败或设备故障。
游戏设计与核心功能
1. 游戏结构
我们将游戏分解为多个模块,使用类和函数封装功能,确保代码清晰且易于维护。以下是核心设计:
Element
类:表示化学元素或化合物,包含名称和属性。Reaction
类:定义合成反应规则,如“氢 + 氧 → 水”。Lab
类:管理实验室状态,包括设备等级和能量。Game
类:管理游戏状态、任务、库存和主循环。- 算法:
- 合成检查:验证元素组合是否符合反应规则。
- 任务分配:生成随机任务,引导玩家探索反应。
- 数据结构:
- 元素库存:字典存储元素名称和数量。
- 反应规则:字典映射元素组合到产物。
- 任务:列表存储目标元素和奖励。
- 游戏状态:实验室等级、能量、声誉和回合数。
2. 核心代码实现
以下是游戏的完整代码框架,我们将逐一讲解每个模块的实现细节。
2.1 元素类:Element
Element
类定义化学元素或化合物的属性。
# game.py
class Element:def __init__(self, name, category, energy_cost):"""初始化元素"""self.name = name # 元素或化合物名称self.category = category # Basic, Compoundself.energy_cost = energy_cost # 合成所需能量
说明:
__init__
:初始化元素名称、类别(基础/化合物)和合成能量成本。
2.2 反应类:Reaction
Reaction
类定义合成反应规则。
# game.py (续)
class Reaction:def __init__(self, reactants, product):"""初始化反应"""self.reactants = frozenset(reactants) # 输入元素(不可变集合)self.product = product # 输出元素
说明:
__init__
:定义反应的输入元素和产物,使用frozenset
确保组合顺序无关。
2.3 实验室类:Lab
Lab
类管理实验室状态和合成操作。
# game.py (续)
class Lab:def __init__(self):"""初始化实验室"""self.level = 1 # 实验室等级self.energy = 100 # 初始能量self.inventory = {"Hydrogen": 10, "Oxygen": 10, "Carbon": 5} # 初始库存self.reactions = self.create_reactions()self.unlocked_reactions = {frozenset(["Hydrogen", "Oxygen"]): "Water",frozenset(["Carbon", "Oxygen"]): "CarbonDioxide"} # 已解锁反应def create_reactions(self):"""创建所有反应规则"""return [Reaction(["Hydrogen", "Oxygen"], "Water"),Reaction(["Carbon", "Oxygen"], "CarbonDioxide"),Reaction(["Water", "Carbon"], "Methane"),Reaction(["Water", "CarbonDioxide"], "Glucose")]def synthesize(self, elements):"""尝试合成元素"""key = frozenset(elements)if key not in self.unlocked_reactions:print("未知反应或未解锁!")return Falseproduct = self.unlocked_reactions[key]element_obj = next(e for e in self.create_elements() if e.name == product)if self.energy >= element_obj.energy_cost:for element in elements:if self.inventory.get(element, 0) <= 0:print(f"缺少 {element}!")return Falsefor element in elements:self.inventory[element] -= 1self.inventory[product] = self.inventory.get(product, 0) + 1self.energy -= element_obj.energy_costprint(f"合成成功:{elements} → {product}")return Trueprint("能量不足!")return Falsedef upgrade(self):"""升级实验室"""cost = self.level * 50if self.energy >= cost:self.energy -= costself.level += 1self.unlock_reactions()print(f"实验室升级到等级 {self.level},花费 {cost} 能量。")else:print("能量不足,无法升级!")def unlock_reactions(self):"""解锁新反应"""available_reactions = [r for r in self.reactions if r.reactants not in self.unlocked_reactions]if self.level >= 2 and frozenset(["Water", "Carbon"]) not in self.unlocked_reactions:self.unlocked_reactions[frozenset(["Water", "Carbon"])] = "Methane"print("解锁反应:Water + Carbon → Methane")if self.level >= 3 and frozenset(["Water", "CarbonDioxide"]) not in self.unlocked_reactions:self.unlocked_reactions[frozenset(["Water", "CarbonDioxide"])] = "Glucose"print("解锁反应:Water + CarbonDioxide → Glucose")@staticmethoddef create_elements():"""创建所有元素"""return [Element("Hydrogen", "Basic", 10),Element("Oxygen", "Basic", 10),Element("Carbon", "Basic", 15),Element("Water", "Compound", 20),Element("CarbonDioxide", "Compound", 25),Element("Methane", "Compound", 30),Element("Glucose", "Compound", 40)]
说明:
__init__
:初始化实验室等级、能量、库存和已解锁反应。create_reactions
:定义所有反应规则。synthesize
:验证元素组合,消耗库存和能量,生成产物。upgrade
:消耗能量提升实验室等级,解锁新反应。unlock_reactions
:根据等级解锁高级反应。create_elements
:定义元素及其属性。
2.4 任务类:Task
Task
类定义实验任务。
# game.py (续)
class Task:def __init__(self, id, target_element, reward_energy, reward_reputation):"""初始化任务"""self.id = idself.target_element = target_elementself.reward_energy = reward_energyself.reward_reputation = reward_reputation
说明:
__init__
:初始化任务 ID、目标元素和奖励。
2.5 游戏类:Game
Game
类管理游戏状态和逻辑。
# game.py (续)
import random
import time
import jsonclass Game:def __init__(self):"""初始化游戏"""self.lab = Lab()self.tasks = []self.reputation = 50 # 初始声誉self.turn = 0self.max_turns = 30self.game_over = Falsedef run(self):"""游戏主循环"""print("欢迎来到《元素大师》!目标:在 30 天内完成所有任务并解锁所有反应。")while not self.game_over:self.display_state()self.generate_tasks()action = self.get_action()if action == "synthesize":self.synthesize_elements()elif action == "upgrade_lab":self.lab.upgrade()elif action == "complete_task":self.complete_task()elif action == "save_game":self.save_game()elif action == "load_game":self.load_game()elif action == "end_turn":self.end_turn()if self.check_win():print("恭喜!你完成了所有任务并解锁所有反应!")self.game_over = Trueif self.check_lose():print("游戏结束。未能在 30 天内达成目标,或声誉过低。")self.game_over = Truetime.sleep(1)def display_state(self):"""显示游戏状态"""print(f"\n天数 {self.turn + 1}")print(f"实验室等级: {self.lab.level}")print(f"能量: {self.lab.energy}")print(f"声誉: {self.reputation}")print("库存:", {k: v for k, v in self.lab.inventory.items() if v > 0})print("任务:", [f"ID {t.id}: 合成 {t.target_element}, 奖励 {t.reward_energy} 能量, {t.reward_reputation} 声誉" for t in self.tasks])print("已解锁反应:", [f"{list(k)} → {v}" for k, v in self.lab.unlocked_reactions.items()])def get_action(self):"""获取玩家行动"""print("\n你想做什么?")print("1. 合成元素")print("2. 升级实验室")print("3. 完成任务")print("4. 保存游戏")print("5. 加载游戏")print("6. 结束天数")choice = input("输入选项 (1-6): ")actions = {"1": "synthesize","2": "upgrade_lab","3": "complete_task","4": "save_game","5": "load_game","6": "end_turn"}return actions.get(choice, self.get_action())def synthesize_elements(self):"""合成元素"""print("可用元素:", self.lab.inventory)elements = input("输入要合成的元素(用空格分隔): ").split()if self.lab.synthesize(elements):self.random_event()def generate_tasks(self):"""生成随机任务"""if random.random() < 0.7: # 70% 几率生成任务task_id = len(self.tasks) + 1available_elements = [e.name for e in self.lab.create_elements() if e.name in self.lab.unlocked_reactions.values()]if available_elements:target = random.choice(available_elements)reward_energy = random.randint(20, 50)reward_reputation = random.randint(5, 15)self.tasks.append(Task(task_id, target, reward_energy, reward_reputation))print(f"新任务 ID {task_id}: 合成 {target}, 奖励 {reward_energy} 能量, {reward_reputation} 声誉")def complete_task(self):"""完成任务"""if not self.tasks:print("没有可用任务!")returnprint("可用任务:")for task in self.tasks:print(f"ID {task.id}: 合成 {task.target_element}, 奖励 {task.reward_energy} 能量, {task.reward_reputation} 声誉")try:task_id = int(input("输入任务 ID: "))task = next((t for t in self.tasks if t.id == task_id), None)if not task:print("无效任务 ID!")returnif self.lab.inventory.get(task.target_element, 0) > 0:self.lab.inventory[task.target_element] -= 1self.lab.energy += task.reward_energyself.reputation += task.reward_reputationself.tasks.remove(task)print(f"任务 ID {task_id} 完成!获得 {task.reward_energy} 能量, {task.reward_reputation} 声誉")else:print(f"库存中缺少 {task.target_element}!")except ValueError:print("输入错误,请重试。")def random_event(self):"""随机事件"""event = random.choice(["None", "ExperimentFailure", "EquipmentFailure"])if event == "ExperimentFailure":cost = random.randint(5, 15)self.lab.energy -= costprint(f"实验失败,损失 {cost} 能量!")elif event == "EquipmentFailure":cost = self.lab.level * 20if self.lab.energy >= cost:self.lab.energy -= costprint(f"设备故障,维修费用 {cost} 能量。")else:print("设备故障未修,声誉下降!")self.reputation -= 5def save_game(self):"""保存游戏状态"""state = {"turn": self.turn,"reputation": self.reputation,"lab": {"level": self.lab.level,"energy": self.lab.energy,"inventory": self.lab.inventory,"unlocked_reactions": {str(list(k)): v for k, v in self.lab.unlocked_reactions.items()}},"tasks": [{"id": t.id, "target_element": t.target_element, "reward_energy": t.reward_energy, "reward_reputation": t.reward_reputation} for t in self.tasks]}with open("savegame.json", "w") as f:json.dump(state, f)print("游戏已保存!")def load_game(self):"""加载游戏状态"""try:with open("savegame.json", "r") as f:state = json.load(f)self.turn = state["turn"]self.reputation = state["reputation"]self.lab.level = state["lab"]["level"]self.lab.energy = state["lab"]["energy"]self.lab.inventory = state["lab"]["inventory"]self.lab.unlocked_reactions = {frozenset(eval(k)): v for k, v in state["lab"]["unlocked_reactions"].items()}self.tasks = [Task(t["id"], t["target_element"], t["reward_energy"], t["reward_reputation"]) for t in state["tasks"]]print("游戏已加载!")except FileNotFoundError:print("没有找到存档文件!")def end_turn(self):"""结束当前天数"""self.turn += 1self.lab.energy += 10 # 每日恢复能量for task in self.tasks[:]:if random.random() < 0.2: # 20% 几率任务过期print(f"任务 ID {task.id} 过期,声誉下降!")self.reputation -= 5self.tasks.remove(task)self.random_event()def check_win(self):"""检查胜利条件"""return len(self.lab.unlocked_reactions) >= 4 and not self.tasksdef check_lose(self):"""检查失败条件"""return self.turn > self.max_turns or self.reputation < 0
说明:
__init__
:初始化实验室、任务、声誉和回合数。run
:游戏主循环,显示状态、生成任务、处理行动。display_state
:显示实验室等级、能量、库存、任务和反应。get_action
:提供交互菜单,返回玩家选择。synthesize_elements
:输入元素组合,调用实验室合成。generate_tasks
:随机生成任务,要求合成特定元素。complete_task
:检查库存,完成任务并获得奖励。random_event
:处理实验失败或设备故障。save_game
和load_game
:保存和加载游戏状态。end_turn
:推进天数,恢复能量,处理任务过期。check_win
和check_lose
:检查是否解锁所有反应和任务完成,或失败。
2.6 主程序:main.py
启动游戏的入口文件。
# main.py
from game import Gameif __name__ == "__main__":game = Game()game.run()
运行游戏
1. 启动游戏
在项目目录下运行:
python main.py
2. 游戏流程
- 初始化:
- 玩家从实验室等级 1、100 能量、50 声誉开始,库存包含 Hydrogen、Oxygen 和 Carbon。
- 每回合行动:
- 显示状态:查看实验室等级、能量、库存、任务和反应。
- 合成元素:选择元素组合,尝试生成新产物。
- 升级实验室:消耗能量提升等级,解锁新反应。
- 完成任务:提交目标元素,获得能量和声誉。
- 保存/加载:保存进度或恢复游戏。
- 结束天数:恢复能量,处理随机事件和任务过期。
- 游戏结束:
- 解锁所有反应并完成任务胜利,超过 30 天或声誉为负失败。
3. 示例运行
欢迎来到《元素大师》!目标:在 30 天内完成所有任务并解锁所有反应。天数 1
实验室等级: 1
能量: 100
声誉: 50
库存: {'Hydrogen': 10, 'Oxygen': 10, 'Carbon': 5}
任务: []
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide]
新任务 ID 1: 合成 Water, 奖励 30 能量, 10 声誉你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 1可用元素: {'Hydrogen': 10, 'Oxygen': 10, 'Carbon': 5}
输入要合成的元素(用空格分隔): Hydrogen Oxygen
合成成功:['Hydrogen', 'Oxygen'] → Water天数 1
实验室等级: 1
能量: 90
声誉: 50
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 5, 'Water': 1}
任务: ['ID 1: 合成 Water, 奖励 30 能量, 10 声誉']
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide]你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 3可用任务:
ID 1: 合成 Water, 奖励 30 能量, 10 声誉
输入任务 ID: 1
任务 ID 1 完成!获得 30 能量, 10 声誉天数 1
实验室等级: 1
能量: 120
声誉: 60
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 5}
任务: []
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide]你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 2实验室升级到等级 2,花费 50 能量。
解锁反应:Water + Carbon → Methane天数 1
实验室等级: 2
能量: 70
声誉: 60
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 5}
任务: []
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide, ['Water', 'Carbon'] → Methane]你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 6天数结束,恢复 10 能量。
天数 2
实验室等级: 2
能量: 80
声誉: 60
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 5}
任务: []
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide, ['Water', 'Carbon'] → Methane]
新任务 ID 2: 合成 Methane, 奖励 40 能量, 12 声誉你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 1可用元素: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 5}
输入要合成的元素(用空格分隔): Water Carbon
合成成功:['Water', 'Carbon'] → Methane
实验失败,损失 10 能量!天数 2
实验室等级: 2
能量: 60
声誉: 60
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 4, 'Methane': 1}
任务: ['ID 2: 合成 Methane, 奖励 40 能量, 12 声誉']
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide, ['Water', 'Carbon'] → Methane]你想做什么?
1. 合成元素
2. 升级实验室
3. 完成任务
4. 保存游戏
5. 加载游戏
6. 结束天数
输入选项 (1-6): 3可用任务:
ID 2: 合成 Methane, 奖励 40 能量, 12 声誉
输入任务 ID: 2
任务 ID 2 完成!获得 40 能量, 12 声誉天数 2
实验室等级: 2
能量: 100
声誉: 72
库存: {'Hydrogen': 9, 'Oxygen': 9, 'Carbon': 4}
任务: []
已解锁反应: [['Hydrogen', 'Oxygen'] → Water, ['Carbon', 'Oxygen'] → CarbonDioxide, ['Water', 'Carbon'] → Methane]
分析:
- 第一天合成 Water,消耗 Hydrogen 和 Oxygen,完成任务 1。
- 升级实验室到等级 2,解锁 Methane 反应。
- 第二天合成 Methane,完成任务 2,尽管触发实验失败事件。
- 声誉提升到 72,能量恢复到 100,继续游戏。
游戏机制详解
1. 元素合成
- 基础元素:Hydrogen、Oxygen、Carbon,初始库存丰富。
- 反应规则:
- Hydrogen + Oxygen → Water
- Carbon + Oxygen → CarbonDioxide
- Water + Carbon → Methane(需等级 2)
- Water + CarbonDioxide → Glucose(需等级 3)
- 消耗:每种元素消耗 1 单位,合成需要能量(10-40)。
2. 任务管理
- 生成:70% 几率生成任务,要求合成已解锁的化合物。
- 奖励:完成任务获得 20-50 能量和 5-15 声誉。
- 过期:20% 几率任务过期,声誉 -5。
3. 实验室管理
- 等级:初始 1 级,升级解锁新反应(等级 2:Methane,等级 3:Glucose)。
- 能量:合成、升级和维修消耗能量,每日恢复 10。
- 库存:管理基础元素和化合物,完成任务消耗产物。
4. 随机事件
- 实验失败:损失 5-15 能量。
- 设备故障:维修消耗等级 × 20 能量,未修声誉 -5。
5. 胜利与失败
- 胜利:解锁所有 4 种反应并完成所有任务。
- 失败:超过 30 天或声誉低于 0。
游戏扩展与优化
当前版本是一个功能完整的化学合成游戏原型,我们可以通过以下方式增强游戏性、技术实现和教育价值。
1. 游戏性增强
- 新反应:增加更复杂的化学反应,如有机合成。
- 元素属性:引入摩尔质量、化学性质影响合成。
- 任务类型:添加多步合成任务或限时任务。
- 库存补充:允许购买或采集基础元素。
示例代码:多步任务
class Task:def __init__(self, id, target_element, reward_energy, reward_reputation, steps=1):self.id = idself.target_element = target_elementself.reward_energy = reward_energyself.reward_reputation = reward_reputationself.steps = steps # 合成步骤数class Game:# ... 其他方法保持不变 ...def generate_tasks(self):if random.random() < 0.7:task_id = len(self.tasks) + 1available_elements = [e.name for e in self.lab.create_elements() if e.name in self.lab.unlocked_reactions.values()]if available_elements:target = random.choice(available_elements)reward_energy = random.randint(20, 50)reward_reputation = random.randint(5, 15)steps = 2 if target == "Glucose" else 1self.tasks.append(Task(task_id, target, reward_energy, reward_reputation, steps))print(f"新任务 ID {task_id}: 合成 {target} ({steps} 步), 奖励 {reward_energy} 能量, {reward_reputation} 声誉")def complete_task(self):if not self.tasks:print("没有可用任务!")returnprint("可用任务:")for task in self.tasks:print(f"ID {task.id}: 合成 {task.target_element} ({task.steps} 步), 奖励 {task.reward_energy} 能量, {task.reward_reputation} 声誉")try:task_id = int(input("输入任务 ID: "))task = next((t for t in self.tasks if t.id == task_id), None)if not task:print("无效任务 ID!")returnrequired = task.stepsif self.lab.inventory.get(task.target_element, 0) >= required:self.lab.inventory[task.target_element] -= requiredself.lab.energy += task.reward_energyself.reputation += task.reward_reputationself.tasks.remove(task)print(f"任务 ID {task_id} 完成!获得 {task.reward_energy} 能量, {task.reward_reputation} 声誉")else:print(f"库存中缺少 {task.target_element} 或数量不足(需 {required} 单位)!")except ValueError:print("输入错误,请重试。")
实现效果:
- Glucose 任务要求 2 单位产物,增加挑战性。
- 奖励和难度匹配,鼓励多步合成。
2. 技术优化
- 图形界面:使用 Pygame 显示实验室、元素和反应动画。
- 存档加密:防止玩家修改存档文件。
- 反应可视化:展示化学反应的分子结构。
示例代码:Pygame 界面
import pygameclass GameWithGUI(Game):def __init__(self):super().__init__()pygame.init()self.screen = pygame.display.set_mode((800, 600))pygame.display.set_caption("元素大师")self.font = pygame.font.Font(None, 36)self.element_positions = {"Hydrogen": (100, 100), "Oxygen": (200, 100), "Carbon": (300, 100),"Water": (100, 200), "CarbonDioxide": (200, 200), "Methane": (300, 200),"Glucose": (200, 300)}def display_state(self):"""使用 Pygame 显示状态"""self.screen.fill((255, 255, 255))# 绘制元素库存for element, count in self.lab.inventory.items():if count > 0:pos = self.element_positions.get(element, (400, 100))pygame.draw.circle(self.screen, (0, 0, 255), pos, 20)text = self.font.render(f"{element}: {count}", True, (0, 0, 0))self.screen.blit(text, (pos[0] - 30, pos[1] + 30))# 显示状态texts = [f"天数: {self.turn + 1}",f"实验室等级: {self.lab.level}",f"能量: {self.lab.energy}",f"声誉: {self.reputation}",f"任务: {len(self.tasks)} 个"]for i, text in enumerate(texts):rendered = self.font.render(text, True, (0, 0, 0))self.screen.blit(rendered, (10, 400 + i * 30))pygame.display.flip()super().display_state()def run(self):print("欢迎来到《元素大师》!")running = Truewhile running and not self.game_over:self.display_state()for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseaction = self.get_action()if action == "synthesize":self.synthesize_elements()elif action == "upgrade_lab":self.lab.upgrade()elif action == "complete_task":self.complete_task()elif action == "save_game":self.save_game()elif action == "load_game":self.load_game()elif action == "end_turn":self.end_turn()if self.check_win():print("恭喜!你完成了所有任务并解锁所有反应!")self.game_over = Trueif self.check_lose():print("游戏结束。未能在 30 天内达成目标,或声誉过低。")self.game_over = Truetime.sleep(1)pygame.quit()
实现效果:
- 显示元素库存(圆点表示元素,旁边标注数量)。
- CLI 交互保留,状态在屏幕底部显示。
3. 教育模块
- 反应原理:显示化学方程式,如 2H₂ + O₂ → 2H₂O。
- 元素知识:介绍元素性质,如原子序数、周期表位置。
- 历史背景:讲述化学发现的故事。
示例代码:反应原理
class Lab:# ... 其他方法保持不变 ...def synthesize(self, elements):key = frozenset(elements)if key not in self.unlocked_reactions:print("未知反应或未解锁!")return Falseproduct = self.unlocked_reactions[key]element_obj = next(e for e in self.create_elements() if e.name == product)if self.energy >= element_obj.energy_cost:for element in elements:if self.inventory.get(element, 0) <= 0:print(f"缺少 {element}!")return Falsefor element in elements:self.inventory[element] -= 1self.inventory[product] = self.inventory.get(product, 0) + 1self.energy -= element_obj.energy_costequation = {frozenset(["Hydrogen", "Oxygen"]): "2H₂ + O₂ → 2H₂O",frozenset(["Carbon", "Oxygen"]): "C + O₂ → CO₂",frozenset(["Water", "Carbon"]): "CH₄ (Methane) formed via complex reaction",frozenset(["Water", "CarbonDioxide"]): "6CO₂ + 6H₂O → C₆H₁₂O₆ (Photosynthesis)"}.get(key, "未知反应")print(f"合成成功:{elements} → {product} ({equation})")return Trueprint("能量不足!")return False
实现效果:
- 每次合成显示化学方程式,增强教育性。
游戏策略与玩法分析
1. 玩家策略
- 资源管理:优先合成高价值化合物,保留基础元素。
- 任务优先级:选择高奖励任务,避免过期。
- 实验室升级:尽早升级以解锁高级反应。
- 能量规划:平衡合成和升级的能量消耗。
2. 平衡性
- 初始资源:100 能量和基础元素,适合初期合成。
- 任务难度:简单任务(Water)到复杂任务(Glucose)。
- 随机事件:实验失败和设备故障增加挑战。
- 回合限制:30 天需高效规划。
3. 重玩价值
- 尝试不同合成顺序和任务优先级。
- 应对随机事件,优化资源管理。
- 解锁所有反应,探索化学知识。
总结与未来展望
通过这篇博文,您已经成功构建了一个化学元素合成模拟游戏 元素大师!这个项目展示了如何使用 Python 创建一个科学类游戏,涵盖化学模拟、资源管理和教育内容。以下是回顾和未来方向:
1. 收获
- 掌握了 Python OOP 和数据管理。
- 实现了化学反应模拟和任务系统。
- 体验了科学与策略的结合。
2. 未来扩展
- 图形化:完善 Pygame 界面,显示分子动画。
- 新反应:增加有机化学或核反应。
- 多人模式:支持合作合成或竞赛。
- 教育增强:融入更多化学知识和历史。
3. 动手实践
快去运行代码,探索化学世界吧!您可以尝试:
- 合成复杂化合物,完成高级任务。
- 优化能量和库存管理。
- 实现图形界面,提升用户体验。
希望这篇教程为您打开了化学合成游戏开发的大门!如果您有疑问或建议,请留言,我将进一步完善内容。祝您编程愉快,享受元素大师的科学之美!
附录:完整代码
以下是整合后的完整代码,分为 game.py
和 main.py
,可直接运行。
game.py
import random
import time
import jsonclass Element:def __init__(self, name, category, energy_cost):self.name = nameself.category = categoryself.energy_cost = energy_costclass Reaction:def __init__(self, reactants, product):self.reactants = frozenset(reactants)self.product = productclass Task:def __init__(self, id, target_element, reward_energy, reward_reputation, steps=1):self.id = idself.target_element = target_elementself.reward_energy = reward_energyself.reward_reputation = reward_reputationself.steps = stepsclass Lab:def __init__(self):self.level = 1self.energy = 100self.inventory = {"Hydrogen": 10, "Oxygen": 10, "Carbon": 5}self.reactions = self.create_reactions()self.unlocked_reactions = {frozenset(["Hydrogen", "Oxygen"]): "Water",frozenset(["Carbon", "Oxygen"]): "CarbonDioxide"}def create_reactions(self):return [Reaction(["Hydrogen", "Oxygen"], "Water"),Reaction(["Carbon", "Oxygen"], "CarbonDioxide"),Reaction(["Water", "Carbon"], "Methane"),Reaction(["Water", "CarbonDioxide"], "Glucose")]def create_elements(self):return [Element("Hydrogen", "Basic", 10),Element("Oxygen", "Basic", 10),Element("Carbon", "Basic", 15),Element("Water", "Compound", 20),Element("CarbonDioxide", "Compound", 25),Element("Methane", "Compound", 30),Element("Glucose", "Compound", 40)]def synthesize(self, elements):key = frozenset(elements)if key not in self.unlocked_reactions:print("未知反应或未解锁!")return Falseproduct = self.unlocked_reactions[key]element_obj = next(e for e in self.create_elements() if e.name == product)if self.energy >= element_obj.energy_cost:for element in elements:if self.inventory.get(element, 0) <= 0:print(f"缺少 {element}!")return Falsefor element in elements:self.inventory[element] -= 1self.inventory[product] = self.inventory.get(product, 0) + 1self.energy -= element_obj.energy_costequation = {frozenset(["Hydrogen", "Oxygen"]): "2H₂ + O₂ → 2H₂O",frozenset(["Carbon", "Oxygen"]): "C + O₂ → CO₂",frozenset(["Water", "Carbon"]): "CH₄ (Methane) formed via complex reaction",frozenset(["Water", "CarbonDioxide"]): "6CO₂ + 6H₂O → C₆H₁₂O₆ (Photosynthesis)"}.get(key, "未知反应")print(f"合成成功:{elements} → {product} ({equation})")return Trueprint("能量不足!")return Falsedef upgrade(self):cost = self.level * 50if self.energy >= cost:self.energy -= costself.level += 1self.unlock_reactions()print(f"实验室升级到等级 {self.level},花费 {cost} 能量。")else:print("能量不足,无法升级!")def unlock_reactions(self):available_reactions = [r for r in self.reactions if r.reactants not in self.unlocked_reactions]if self.level >= 2 and frozenset(["Water", "Carbon"]) not in self.unlocked_reactions:self.unlocked_reactions[frozenset(["Water", "Carbon"])] = "Methane"print("解锁反应:Water + Carbon → Methane")if self.level >= 3 and frozenset(["Water", "CarbonDioxide"]) not in self.unlocked_reactions:self.unlocked_reactions[frozenset(["Water", "CarbonDioxide"])] = "Glucose"print("解锁反应:Water + CarbonDioxide → Glucose")class Game:def __init__(self):self.lab = Lab()self.tasks = []self.reputation = 50self.turn = 0self.max_turns = 30self.game_over = Falsedef run(self):print("欢迎来到《元素大师》!目标:在 30 天内完成所有任务并解锁所有反应。")while not self.game_over:self.display_state()self.generate_tasks()action = self.get_action()if action == "synthesize":self.synthesize_elements()elif action == "upgrade_lab":self.lab.upgrade()elif action == "complete_task":self.complete_task()elif action == "save_game":self.save_game()elif action == "load_game":self.load_game()elif action == "end_turn":self.end_turn()if self.check_win():print("恭喜!你完成了所有任务并解锁所有反应!")self.game_over = Trueif self.check_lose():print("游戏结束。未能在 30 天内达成目标,或声誉过低。")self.game_over = Truetime.sleep(1)def display_state(self):print(f"\n天数 {self.turn + 1}")print(f"实验室等级: {self.lab.level}")print(f"能量: {self.lab.energy}")print(f"声誉: {self.reputation}")print("库存:", {k: v for k, v in self.lab.inventory.items() if v > 0})print("任务:", [f"ID {t.id}: 合成 {t.target_element} ({t.steps} 步), 奖励 {t.reward_energy} 能量, {t.reward_reputation} 声誉" for t in self.tasks])print("已解锁反应:", [f"{list(k)} → {v}" for k, v in self.lab.unlocked_reactions.items()])def get_action(self):print("\n你想做什么?")print("1. 合成元素")print("2. 升级实验室")print("3. 完成任务")print("4. 保存游戏")print("5. 加载游戏")print("6. 结束天数")choice = input("输入选项 (1-6): ")actions = {"1": "synthesize","2": "upgrade_lab","3": "complete_task","4": "save_game","5": "load_game","6": "end_turn"}return actions.get(choice, self.get_action())def synthesize_elements(self):print("可用元素:", self.lab.inventory)elements = input("输入要合成的元素(用空格分隔): ").split()if self.lab.synthesize(elements):self.random_event()def generate_tasks(self):if random.random() < 0.7:task_id = len(self.tasks) + 1available_elements = [e.name for e in self.lab.create_elements() if e.name in self.lab.unlocked_reactions.values()]if available_elements:target = random.choice(available_elements)reward_energy = random.randint(20, 50)reward_reputation = random.randint(5, 15)steps = 2 if target == "Glucose" else 1self.tasks.append(Task(task_id, target, reward_energy, reward_reputation, steps))print(f"新任务 ID {task_id}: 合成 {target} ({steps} 步), 奖励 {reward_energy} 能量, {reward_reputation} 声誉")def complete_task(self):if not self.tasks:print("没有可用任务!")returnprint("可用任务:")for task in self.tasks:print(f"ID {task.id}: 合成 {task.target_element} ({task.steps} 步), 奖励 {task.reward_energy} 能量, {task.reward_reputation} 声誉")try:task_id = int(input("输入任务 ID: "))task = next((t for t in self.tasks if t.id == task_id), None)if not task:print("无效任务 ID!")returnrequired = task.stepsif self.lab.inventory.get(task.target_element, 0) >= required:self.lab.inventory[task.target_element] -= requiredself.lab.energy += task.reward_energyself.reputation += task.reward_reputationself.tasks.remove(task)print(f"任务 ID {task_id} 完成!获得 {task.reward_energy} 能量, {task.reward_reputation} 声誉")else:print(f"库存中缺少 {task.target_element} 或数量不足(需 {required} 单位)!")except ValueError:print("输入错误,请重试。")def random_event(self):event = random.choice(["None", "ExperimentFailure", "EquipmentFailure"])if event == "ExperimentFailure":cost = random.randint(5, 15)self.lab.energy -= costprint(f"实验失败,损失 {cost} 能量!")elif event == "EquipmentFailure":cost = self.lab.level * 20if self.lab.energy >= cost:self.lab.energy -= costprint(f"设备故障,维修费用 {cost} 能量。")else:print("设备故障未修,声誉下降!")self.reputation -= 5def save_game(self):state = {"turn": self.turn,"reputation": self.reputation,"lab": {"level": self.lab.level,"energy": self.lab.energy,"inventory": self.lab.inventory,"unlocked_reactions": {str(list(k)): v for k, v in self.lab.unlocked_reactions.items()}},"tasks": [{"id": t.id, "target_element": t.target_element, "reward_energy": t.reward_energy, "reward_reputation": t.reward_reputation, "steps": t.steps} for t in self.tasks]}with open("savegame.json", "w") as f:json.dump(state, f)print("游戏已保存!")def load_game(self):try:with open("savegame.json", "r") as f:state = json.load(f)self.turn = state["turn"]self.reputation = state["reputation"]self.lab.level = state["lab"]["level"]self.lab.energy = state["lab"]["energy"]self.lab.inventory = state["lab"]["inventory"]self.lab.unlocked_reactions = {frozenset(eval(k)): v for k, v in state["lab"]["unlocked_reactions"].items()}self.tasks = [Task(t["id"], t["target_element"], t["reward_energy"], t["reward_reputation"], t["steps"]) for t in state["tasks"]]print("游戏已加载!")except FileNotFoundError:print("没有找到存档文件!")def end_turn(self):self.turn += 1self.lab.energy += 10for task in self.tasks[:]:if random.random() < 0.2:print(f"任务 ID {task.id} 过期,声誉下降!")self.reputation -= 5self.tasks.remove(task)self.random_event()def check_win(self):return len(self.lab.unlocked_reactions) >= 4 and not self.tasksdef check_lose(self):return self.turn > self.max_turns or self.reputation < 0
main.py
from game import Gameif __name__ == "__main__":game = Game()game.run()