技術準備

在開始編碼之前,我們需要準備開發環境和相關工具。以下是開發 細胞探秘 所需的技術棧和資源。

1. 技術棧

  • 編程語言:Python 3.x(推薦 3.8 或更高版本)。
  • 核心庫
  • random:生成隨機事件,如細胞突變或任務生成。
  • time:控制遊戲節奏和實驗時間。
  • json:保存和加載遊戲狀態。
  • pygame(可選):用於圖形界面和細胞結構可視化。
  • 數據存儲
  • 使用字典存儲細胞器和實驗數據。
  • 列表存儲任務、庫存和實驗室狀態。
  • 用户界面:基於命令行界面(CLI)顯示細胞器、任務和交互,圖形界面作為擴展。
  • 依賴安裝
  • randomtime 和 json 是 Python 標準庫,無需額外安裝。
  • pygame(可選):pip install pygame

2. 開發環境

確保已安裝 Python(可從 python.org 下載)。推薦使用 Visual Studio Code 或 PyCharm 作為開發工具,提供代碼補全和調試支持。本遊戲的核心版本基於 CLI,擴展部分引入圖形界面。項目結構如下:

cell_exploration_game/
├── main.py           # 主程序入口
└── game.py           # 遊戲邏輯模塊

3. 遊戲目標

玩家將扮演細胞生物學家,目標是在 30 個回合(模擬 30 天)內完成所有研究任務,解鎖所有細胞器功能並提升實驗室等級。遊戲採用回合制,每回合代表一天,玩家需要:

  • 探索細胞器:研究細胞核、線粒體等,解鎖功能。
  • 完成任務:完成實驗目標,如合成蛋白質或修復 DNA。
  • 升級實驗室:提升設備等級,解鎖高級研究。
  • 管理資源:平衡能量、樣本和研究點。
  • 應對事件:處理細胞突變或病毒入侵。

遊戲設計與核心功能

1. 遊戲結構

我們將遊戲分解為多個模塊,使用類和函數封裝功能,確保代碼清晰且易於維護。以下是核心設計:

  • Organelle 類:表示細胞器,包含名稱、功能和研究成本。
  • Task 類:定義研究任務,如合成蛋白質或修復細胞。
  • Lab 類:管理實驗室狀態,包括設備等級和資源。
  • CellGame 類:管理遊戲狀態、任務、庫存和主循環。
  • 算法
  • 研究檢查:驗證資源是否足夠完成任務。
  • 任務分配:生成隨機任務,引導玩家探索細胞器。
  • 數據結構
  • 細胞器:字典存儲名稱、功能和狀態。
  • 任務:列表存儲目標和獎勵。
  • 資源:能量、樣本和研究點。
  • 遊戲狀態:實驗室等級、資源、聲譽和回合數。

2. 核心代碼實現

以下是遊戲的完整代碼框架,我們將逐一講解每個模塊的實現細節。

2.1 細胞器類:Organelle

Organelle 類定義細胞器的屬性。

# game.py
class Organelle:
    def __init__(self, name, function, energy_cost, research_points):
        """初始化細胞器"""
        self.name = name  # 細胞器名稱
        self.function = function  # 功能描述
        self.energy_cost = energy_cost  # 研究所需能量
        self.research_points = research_points  # 解鎖所需研究點
        self.unlocked = False  # 是否解鎖

説明

  • __init__:初始化細胞器名稱、功能、能量成本和研究點。

2.2 任務類:Task

Task 類定義研究任務。

# game.py (續)
class Task:
    def __init__(self, id, target_organelle, target_action, reward_energy, reward_reputation):
        """初始化任務"""
        self.id = id
        self.target_organelle = target_organelle  # 目標細胞器
        self.target_action = target_action  # 任務目標(如“合成蛋白質”)
        self.reward_energy = reward_energy
        self.reward_reputation = reward_reputation

説明

  • __init__:初始化任務 ID、目標細胞器、任務目標和獎勵。

2.3 實驗室類:Lab

Lab 類管理實驗室狀態和研究操作。

# game.py (續)
class Lab:
    def __init__(self):
        """初始化實驗室"""
        self.level = 1  # 實驗室等級
        self.energy = 100  # 初始能量
        self.samples = {"DNA": 10, "Protein": 5, "Lipid": 5}  # 初始樣本庫存
        self.research_points = 0  # 研究點
        self.organelles = self.create_organelles()
        self.organelles["Nucleus"].unlocked = True  # 初始解鎖細胞核

    def create_organelles(self):
        """創建所有細胞器"""
        return {
            "Nucleus": Organelle("Nucleus", "Controls cell activities and stores DNA", 10, 0),
            "Mitochondrion": Organelle("Mitochondrion", "Produces energy (ATP)", 20, 50),
            "Ribosome": Organelle("Ribosome", "Synthesizes proteins", 15, 30),
            "EndoplasmicReticulum": Organelle("EndoplasmicReticulum", "Processes proteins and lipids", 25, 70),
            "GolgiApparatus": Organelle("GolgiApparatus", "Packages and distributes molecules", 30, 100)
        }

    def research_organelle(self, organelle_name):
        """研究細胞器"""
        organelle = self.organelles.get(organelle_name)
        if not organelle:
            print("無效細胞器!")
            return False
        if organelle.unlocked:
            print(f"{organelle_name} 已解鎖!")
            return False
        if self.energy >= organelle.energy_cost and self.research_points >= organelle.research_points:
            self.energy -= organelle.energy_cost
            self.research_points -= organelle.research_points
            organelle.unlocked = True
            print(f"成功解鎖 {organelle_name}:{organelle.function}")
            return True
        print("能量或研究點不足!")
        return False

    def upgrade(self):
        """升級實驗室"""
        cost = self.level * 50
        if self.energy >= cost:
            self.energy -= cost
            self.level += 1
            print(f"實驗室升級到等級 {self.level},花費 {cost} 能量。")
        else:
            print("能量不足,無法升級!")

    def perform_action(self, organelle_name, action):
        """執行細胞器動作"""
        organelle = self.organelles.get(organelle_name)
        if not organelle or not organelle.unlocked:
            print(f"{organelle_name} 未解鎖或無效!")
            return False
        actions = {
            "Nucleus": {"Analyze DNA": ("DNA", -1, 5, 2)},
            "Mitochondrion": {"Produce ATP": ("", 0, 10, 0)},
            "Ribosome": {"Synthesize Protein": ("DNA", -1, 0, 5)},
            "EndoplasmicReticulum": {"Process Lipid": ("Lipid", -1, 0, 7)},
            "GolgiApparatus": {"Package Molecule": ("Protein", -1, 0, 10)}
        }
        if organelle_name in actions and action in actions[organelle_name]:
            sample, sample_change, energy_gain, points_gain = actions[organelle_name][action]
            if sample and self.samples.get(sample, 0) <= 0:
                print(f"缺少 {sample}!")
                return False
            cost = organelle.energy_cost
            if self.energy >= cost:
                self.energy -= cost
                if sample:
                    self.samples[sample] += sample_change
                self.energy += energy_gain
                self.research_points += points_gain
                self.samples[sample] = self.samples.get(sample, 0)
                print(f"{organelle_name} 執行 {action} 成功,獲得 {points_gain} 研究點,{energy_gain} 能量")
                return True
            print("能量不足!")
            return False
        print("無效動作!")
        return False

説明

  • __init__:初始化實驗室等級、能量、樣本庫存和細胞器。
  • create_organelles:定義細胞器及其功能。
  • research_organelle:消耗能量和研究點解鎖細胞器。
  • upgrade:消耗能量提升實驗室等級。
  • perform_action:執行細胞器特定動作(如合成蛋白質),消耗樣本並獲得研究點。

2.4 遊戲類:CellGame

CellGame 類管理遊戲狀態和邏輯。

# game.py (續)
import random
import time
import json

class CellGame:
    def __init__(self):
        """初始化遊戲"""
        self.lab = Lab()
        self.tasks = []
        self.reputation = 50  # 初始聲譽
        self.turn = 0
        self.max_turns = 30
        self.game_over = False

    def run(self):
        """遊戲主循環"""
        print("歡迎來到《細胞探秘》!目標:在 30 天內完成所有任務並解鎖所有細胞器。")
        while not self.game_over:
            self.display_state()
            self.generate_tasks()
            action = self.get_action()
            if action == "research_organelle":
                self.research_organelle()
            elif action == "perform_action":
                self.perform_action()
            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 = True
            if self.check_lose():
                print("遊戲結束。未能在 30 天內達成目標,或聲譽過低。")
                self.game_over = True
            time.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(f"研究點: {self.lab.research_points}")
        print("樣本庫存:", {k: v for k, v in self.lab.samples.items() if v > 0})
        print("細胞器:", [f"{k} ({'已解鎖' if v.unlocked else '未解鎖'})" for k, v in self.lab.organelles.items()])
        print("任務:", [f"ID {t.id}: {t.target_organelle} - {t.target_action}, 獎勵 {t.reward_energy} 能量, {t.reward_reputation} 聲譽" for t in self.tasks])

    def get_action(self):
        """獲取玩家行動"""
        print("\n你想做什麼?")
        print("1. 研究細胞器")
        print("2. 執行細胞器動作")
        print("3. 升級實驗室")
        print("4. 完成任務")
        print("5. 保存遊戲")
        print("6. 加載遊戲")
        print("7. 結束天數")
        choice = input("輸入選項 (1-7): ")
        actions = {
            "1": "research_organelle",
            "2": "perform_action",
            "3": "upgrade_lab",
            "4": "complete_task",
            "5": "save_game",
            "6": "load_game",
            "7": "end_turn"
        }
        return actions.get(choice, self.get_action())

    def research_organelle(self):
        """研究細胞器"""
        print("可研究細胞器:")
        for name, organelle in self.lab.organelles.items():
            if not organelle.unlocked:
                print(f"{name}: 需要 {organelle.energy_cost} 能量, {organelle.research_points} 研究點")
        organelle_name = input("輸入細胞器名稱:")
        self.lab.research_organelle(organelle_name)

    def perform_action(self):
        """執行細胞器動作"""
        print("可用細胞器和動作:")
        for name, organelle in self.lab.organelles.items():
            if organelle.unlocked:
                actions = {
                    "Nucleus": ["Analyze DNA"],
                    "Mitochondrion": ["Produce ATP"],
                    "Ribosome": ["Synthesize Protein"],
                    "EndoplasmicReticulum": ["Process Lipid"],
                    "GolgiApparatus": ["Package Molecule"]
                }.get(name, [])
                print(f"{name}: {actions}")
        organelle_name = input("輸入細胞器名稱:")
        action = input("輸入動作:")
        if self.lab.perform_action(organelle_name, action):
            self.random_event()

    def generate_tasks(self):
        """生成隨機任務"""
        if random.random() < 0.7:
            task_id = len(self.tasks) + 1
            unlocked_organelles = [name for name, o in self.lab.organelles.items() if o.unlocked]
            if unlocked_organelles:
                organelle = random.choice(unlocked_organelles)
                actions = {
                    "Nucleus": ["Analyze DNA"],
                    "Mitochondrion": ["Produce ATP"],
                    "Ribosome": ["Synthesize Protein"],
                    "EndoplasmicReticulum": ["Process Lipid"],
                    "GolgiApparatus": ["Package Molecule"]
                }.get(organelle, [])
                action = random.choice(actions)
                reward_energy = random.randint(20, 50)
                reward_reputation = random.randint(5, 15)
                self.tasks.append(Task(task_id, organelle, action, reward_energy, reward_reputation))
                print(f"新任務 ID {task_id}: {organelle} - {action}, 獎勵 {reward_energy} 能量, {reward_reputation} 聲譽")

    def complete_task(self):
        """完成任務"""
        if not self.tasks:
            print("沒有可用任務!")
            return
        print("可用任務:")
        for task in self.tasks:
            print(f"ID {task.id}: {task.target_organelle} - {task.target_action}, 獎勵 {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!")
                return
            required_samples = {"Analyze DNA": "DNA", "Synthesize Protein": "Protein", "Process Lipid": "Lipid", "Package Molecule": "Protein"}
            sample = required_samples.get(task.target_action)
            if not sample or self.lab.samples.get(sample, 0) > 0:
                if sample:
                    self.lab.samples[sample] -= 1
                self.lab.energy += task.reward_energy
                self.reputation += task.reward_reputation
                self.tasks.remove(task)
                print(f"任務 ID {task_id} 完成!獲得 {task.reward_energy} 能量, {task.reward_reputation} 聲譽")
            else:
                print(f"庫存中缺少 {sample}!")
        except ValueError:
            print("輸入錯誤,請重試。")

    def random_event(self):
        """隨機事件"""
        event = random.choice(["None", "CellMutation", "VirusInvasion"])
        if event == "CellMutation":
            cost = random.randint(5, 15)
            self.lab.energy -= cost
            print(f"細胞突變,損失 {cost} 能量!")
        elif event == "VirusInvasion":
            cost = self.lab.level * 20
            if self.lab.energy >= cost:
                self.lab.energy -= cost
                print(f"病毒入侵,修復費用 {cost} 能量。")
            else:
                print("病毒入侵未修復,聲譽下降!")
                self.reputation -= 5

    def save_game(self):
        """保存遊戲狀態"""
        state = {
            "turn": self.turn,
            "reputation": self.reputation,
            "lab": {
                "level": self.lab.level,
                "energy": self.lab.energy,
                "samples": self.lab.samples,
                "research_points": self.lab.research_points,
                "organelles": {name: o.unlocked for name, o in self.lab.organelles.items()}
            },
            "tasks": [{"id": t.id, "target_organelle": t.target_organelle, "target_action": t.target_action, "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.samples = state["lab"]["samples"]
            self.lab.research_points = state["lab"]["research_points"]
            for name, unlocked in state["lab"]["organelles"].items():
                self.lab.organelles[name].unlocked = unlocked
            self.tasks = [Task(t["id"], t["target_organelle"], t["target_action"], t["reward_energy"], t["reward_reputation"]) for t in state["tasks"]]
            print("遊戲已加載!")
        except FileNotFoundError:
            print("沒有找到存檔文件!")

    def end_turn(self):
        """結束當前天數"""
        self.turn += 1
        self.lab.energy += 10
        self.lab.research_points += 5
        for task in self.tasks[:]:
            if random.random() < 0.2:
                print(f"任務 ID {task.id} 過期,聲譽下降!")
                self.reputation -= 5
                self.tasks.remove(task)
        self.random_event()

    def check_win(self):
        """檢查勝利條件"""
        return all(o.unlocked for o in self.lab.organelles.values()) and not self.tasks

    def check_lose(self):
        """檢查失敗條件"""
        return self.turn > self.max_turns or self.reputation < 0

説明

  • __init__:初始化實驗室、任務、聲譽和回合數。
  • run:遊戲主循環,顯示狀態、生成任務、處理行動。
  • display_state:顯示實驗室等級、能量、樣本、細胞器和任務。
  • get_action:提供交互菜單,返回玩家選擇。
  • research_organelle:選擇並解鎖細胞器。
  • perform_action:執行細胞器動作,獲取資源。
  • generate_tasks:生成隨機任務,要求特定細胞器動作。
  • complete_task:檢查樣本,完成任務並獲得獎勵。
  • random_event:處理細胞突變或病毒入侵。
  • save_game 和 load_game:保存和加載遊戲狀態。
  • end_turn:推進天數,恢復能量和研究點,處理任務過期。
  • check_win 和 check_lose:檢查是否解鎖所有細胞器並完成任務,或失敗。

2.5 主程序:main.py

啓動遊戲的入口文件。

# main.py
from game import CellGame

if __name__ == "__main__":
    game = CellGame()
    game.run()

運行遊戲

1. 啓動遊戲

在項目目錄下運行:

python main.py

2. 遊戲流程

  1. 初始化
  • 玩家從實驗室等級 1、100 能量、50 聲譽開始,初始解鎖細胞核。
  1. 每回合行動
  • 顯示狀態:查看實驗室等級、能量、樣本、細胞器和任務。
  • 研究細胞器:解鎖新細胞器(如線粒體、核糖體)。
  • 執行動作:使用細胞器完成任務(如合成蛋白質)。
  • 升級實驗室:提升等級,降低研究成本。
  • 完成任務:提交目標成果,獲得能量和聲譽。
  • 保存/加載:保存進度或恢復遊戲。
  • 結束天數:恢復能量和研究點,處理隨機事件和任務過期。
  1. 遊戲結束
  • 解鎖所有細胞器並完成任務勝利,超過 30 天或聲譽為負失敗。

3. 示例運行

歡迎來到《細胞探秘》!目標:在 30 天內完成所有任務並解鎖所有細胞器。

天數 1
實驗室等級: 1
能量: 100
聲譽: 50
研究點: 0
樣本庫存: {'DNA': 10, 'Protein': 5, 'Lipid': 5}
細胞器: ['Nucleus (已解鎖)', 'Mitochondrion (未解鎖)', 'Ribosome (未解鎖)', 'EndoplasmicReticulum (未解鎖)', 'GolgiApparatus (未解鎖)']
任務: []
新任務 ID 1: Nucleus - Analyze DNA, 獎勵 30 能量, 10 聲譽

你想做什麼?
1. 研究細胞器
2. 執行細胞器動作
3. 升級實驗室
4. 完成任務
5. 保存遊戲
6. 加載遊戲
7. 結束天數
輸入選項 (1-7): 2

可用細胞器和動作:
Nucleus: ['Analyze DNA']
輸入細胞器名稱:Nucleus
輸入動作:Analyze DNA
Nucleus 執行 Analyze DNA 成功,獲得 2 研究點,5 能量

天數 1
實驗室等級: 1
能量: 95
聲譽: 50
研究點: 2
樣本庫存: {'DNA': 9, 'Protein': 5, 'Lipid': 5}
細胞器: ['Nucleus (已解鎖)', 'Mitochondrion (未解鎖)', 'Ribosome (未解鎖)', 'EndoplasmicReticulum (未解鎖)', 'GolgiApparatus (未解鎖)']
任務: ['ID 1: Nucleus - Analyze DNA, 獎勵 30 能量, 10 聲譽']

你想做什麼?
1. 研究細胞器
2. 執行細胞器動作
3. 升級實驗室
4. 完成任務
5. 保存遊戲
6. 加載遊戲
7. 結束天數
輸入選項 (1-7): 4

可用任務:
ID 1: Nucleus - Analyze DNA, 獎勵 30 能量, 10 聲譽
輸入任務 ID: 1
任務 ID 1 完成!獲得 30 能量, 10 聲譽

天數 1
實驗室等級: 1
能量: 125
聲譽: 60
研究點: 2
樣本庫存: {'DNA': 8, 'Protein': 5, 'Lipid': 5}
細胞器: ['Nucleus (已解鎖)', 'Mitochondrion (未解鎖)', 'Ribosome (未解鎖)', 'EndoplasmicReticulum (未解鎖)', 'GolgiApparatus (未解鎖)']
任務: []

你想做什麼?
1. 研究細胞器
2. 執行細胞器動作
3. 升級實驗室
4. 完成任務
5. 保存遊戲
6. 加載遊戲
7. 結束天數
輸入選項 (1-7): 3

實驗室升級到等級 2,花費 50 能量。

天數 1
實驗室等級: 2
能量: 75
聲譽: 60
研究點: 2
樣本庫存: {'DNA': 8, 'Protein': 5, 'Lipid': 5}
細胞器: ['Nucleus (已解鎖)', 'Mitochondrion (未解鎖)', 'Ribosome (未解鎖)', 'EndoplasmicReticulum (未解鎖)', 'GolgiApparatus (未解鎖)']
任務: []

你想做什麼?
1. 研究細胞器
2. 執行細胞器動作
3. 升級實驗室
4. 完成任務
5. 保存遊戲
6. 加載遊戲
7. 結束天數
輸入選項 (1-7): 7

天數結束,恢復 10 能量。
細胞突變,損失 10 能量!
天數 2
實驗室等級: 2
能量: 75
聲譽: 60
研究點: 7
樣本庫存: {'DNA': 8, 'Protein': 5, 'Lipid': 5}
細胞器: ['Nucleus (已解鎖)', 'Mitochondrion (未解鎖)', 'Ribosome (未解鎖)', 'EndoplasmicReticulum (未解鎖)', 'GolgiApparatus (未解鎖)']
任務: []
新任務 ID 2: Nucleus - Analyze DNA, 獎勵 40 能量, 12 聲譽

分析

  • 第一天通過細胞核分析 DNA,完成任務 1,獲得能量和聲譽。
  • 升級實驗室到等級 2,消耗 50 能量。
  • 第二天觸發細胞突變,損失能量,但生成新任務。

遊戲機制詳解

1. 細胞器探索

  • 細胞器
  • 細胞核:分析 DNA,消耗 DNA 獲得研究點。
  • 線粒體:產生 ATP,增加能量。
  • 核糖體:合成蛋白質,消耗 DNA。
  • 內質網:加工脂質,消耗脂質。
  • 高爾基體:包裝分子,消耗蛋白質。
  • 解鎖:消耗能量和研究點解鎖新細胞器。

2. 任務管理

  • 生成:70% 機率生成任務,要求特定細胞器動作。
  • 獎勵:完成任務獲得 20-50 能量和 5-15 聲譽。
  • 過期:20% 機率任務過期,聲譽 -5。

3. 實驗室管理

  • 等級:初始 1 級,升級降低研究成本。
  • 資源
  • 能量:用於研究、動作和升級,每日恢復 10。
  • 樣本:DNA、蛋白質、脂質,用於任務和動作。
  • 研究點:解鎖細胞器,每日增加 5。

4. 隨機事件

  • 細胞突變:損失 5-15 能量。
  • 病毒入侵:修復消耗等級 × 20 能量,未修聲譽 -5。

5. 勝利與失敗

  • 勝利:解鎖所有 5 種細胞器並完成任務。
  • 失敗:超過 30 天或聲譽低於 0。

遊戲擴展與優化

當前版本是一個功能完整的細胞探索遊戲原型,我們可以通過以下方式增強遊戲性、技術實現和教育價值。

1. 遊戲性增強

  • 新細胞器:添加溶酶體、細胞膜等。
  • 任務類型:引入多步任務或限時任務。
  • 樣本採集:允許從環境中獲取樣本。
  • 動態環境:模擬細胞分裂或凋亡。

示例代碼:多步任務

class Task:
    def __init__(self, id, target_organelle, target_action, reward_energy, reward_reputation, steps=1):
        self.id = id
        self.target_organelle = target_organelle
        self.target_action = target_action
        self.reward_energy = reward_energy
        self.reward_reputation = reward_reputation
        self.steps = steps

class CellGame:
    # ... 其他方法保持不變 ...

    def generate_tasks(self):
        if random.random() < 0.7:
            task_id = len(self.tasks) + 1
            unlocked_organelles = [name for name, o in self.lab.organelles.items() if o.unlocked]
            if unlocked_organelles:
                organelle = random.choice(unlocked_organelles)
                actions = {
                    "Nucleus": ["Analyze DNA"],
                    "Mitochondrion": ["Produce ATP"],
                    "Ribosome": ["Synthesize Protein"],
                    "EndoplasmicReticulum": ["Process Lipid"],
                    "GolgiApparatus": ["Package Molecule"]
                }.get(organelle, [])
                action = random.choice(actions)
                reward_energy = random.randint(20, 50)
                reward_reputation = random.randint(5, 15)
                steps = 2 if organelle == "GolgiApparatus" else 1
                self.tasks.append(Task(task_id, organelle, action, reward_energy, reward_reputation, steps))
                print(f"新任務 ID {task_id}: {organelle} - {action} ({steps} 步), 獎勵 {reward_energy} 能量, {reward_reputation} 聲譽")

    def complete_task(self):
        if not self.tasks:
            print("沒有可用任務!")
            return
        print("可用任務:")
        for task in self.tasks:
            print(f"ID {task.id}: {task.target_organelle} - {task.target_action} ({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!")
                return
            required_samples = {"Analyze DNA": "DNA", "Synthesize Protein": "Protein", "Process Lipid": "Lipid", "Package Molecule": "Protein"}
            sample = required_samples.get(task.target_action)
            if not sample or self.lab.samples.get(sample, 0) >= task.steps:
                if sample:
                    self.lab.samples[sample] -= task.steps
                self.lab.energy += task.reward_energy
                self.reputation += task.reward_reputation
                self.tasks.remove(task)
                print(f"任務 ID {task_id} 完成!獲得 {task.reward_energy} 能量, {task.reward_reputation} 聲譽")
            else:
                print(f"庫存中缺少 {sample} 或數量不足(需 {task.steps} 單位)!")
        except ValueError:
            print("輸入錯誤,請重試。")

實現效果

  • 高爾基體任務要求 2 單位蛋白質,增加挑戰性。
  • 獎勵與難度匹配,鼓勵多步研究。

2. 技術優化

  • 圖形界面:使用 Pygame 顯示細胞結構和實驗動畫。
  • 存檔加密:防止修改存檔文件。
  • 細胞可視化:展示細胞器位置和動態過程。

示例代碼:Pygame 界面

import pygame

class CellGameWithGUI(CellGame):
    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.organelle_positions = {
            "Nucleus": (400, 300),
            "Mitochondrion": (500, 200),
            "Ribosome": (300, 200),
            "EndoplasmicReticulum": (350, 400),
            "GolgiApparatus": (450, 400)
        }

    def display_state(self):
        """使用 Pygame 顯示狀態"""
        self.screen.fill((255, 255, 255))
        # 繪製細胞背景
        pygame.draw.circle(self.screen, (200, 200, 255), (400, 300), 200, 2)
        # 繪製細胞器
        for name, organelle in self.lab.organelles.items():
            pos = self.organelle_positions[name]
            color = (0, 255, 0) if organelle.unlocked else (255, 0, 0)
            pygame.draw.circle(self.screen, color, pos, 20)
            text = self.font.render(name, 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"研究點: {self.lab.research_points}",
            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 = True
        while running and not self.game_over:
            self.display_state()
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
            action = self.get_action()
            if action == "research_organelle":
                self.research_organelle()
            elif action == "perform_action":
                self.perform_action()
            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 = True
            if self.check_lose():
                print("遊戲結束。未能在 30 天內達成目標,或聲譽過低。")
                self.game_over = True
            time.sleep(1)
        pygame.quit()

實現效果

  • 顯示細胞結構(圓形表示細胞,細胞器為彩色圓點)。
  • CLI 交互保留,狀態在屏幕底部顯示。

3. 教育模塊

  • 細胞器功能:詳細介紹每個細胞器的生物學作用。
  • 實驗原理:展示蛋白質合成或能量產生的過程。
  • 歷史背景:講述細胞生物學的發展歷程。

示例代碼:細胞器功能

class Lab:
    # ... 其他方法保持不變 ...

    def research_organelle(self, organelle_name):
        organelle = self.organelles.get(organelle_name)
        if not organelle:
            print("無效細胞器!")
            return False
        if organelle.unlocked:
            print(f"{organelle_name} 已解鎖!")
            return False
        if self.energy >= organelle.energy_cost and self.research_points >= organelle.research_points:
            self.energy -= organelle.energy_cost
            self.research_points -= organelle.research_points
            organelle.unlocked = True
            info = {
                "Nucleus": "細胞核是細胞的控制中心,儲存遺傳信息 (DNA)。",
                "Mitochondrion": "線粒體是能量工廠,通過氧化磷酸化產生 ATP。",
                "Ribosome": "核糖體負責翻譯 mRNA,合成蛋白質。",
                "EndoplasmicReticulum": "內質網加工蛋白質和脂質,分為粗糙和光滑內質網。",
                "GolgiApparatus": "高爾基體修飾、包裝和運輸分子到細胞內外。"
            }.get(organelle_name, "未知功能")
            print(f"成功解鎖 {organelle_name}:{organelle.function}\n{info}")
            return True
        print("能量或研究點不足!")
        return False

實現效果

  • 解鎖細胞器時顯示生物學知識,增強教育性。

遊戲策略與玩法分析

1. 玩家策略

  • 資源管理:優先執行高收益動作,保留樣本。
  • 任務優先級:選擇高獎勵任務,避免過期。
  • 實驗室升級:儘早升級以降低研究成本。
  • 細胞器解鎖:平衡解鎖順序,優先線粒體以增加能量。

2. 平衡性

  • 初始資源:100 能量和基礎樣本,適合初期研究。
  • 任務難度:簡單任務(Analyze DNA)到複雜任務(Package Molecule)。
  • 隨機事件:細胞突變和病毒入侵增加挑戰。
  • 回合限制:30 天需高效規劃。

3. 重玩價值

  • 嘗試不同解鎖順序和任務優先級。
  • 應對隨機事件,優化資源管理。
  • 學習細胞生物學知識。

附錄:完整代碼

以下是整合後的完整代碼,分為 game.pymain.py,可直接運行。

game.py

import random
import time
import json

class Organelle:
    def __init__(self, name, function, energy_cost, research_points):
        self.name = name
        self.function = function
        self.energy_cost = energy_cost
        self.research_points = research_points
        self.unlocked = False

class Task:
    def __init__(self, id, target_organelle, target_action, reward_energy, reward_reputation, steps=1):
        self.id = id
        self.target_organelle = target_organelle
        self.target_action = target_action
        self.reward_energy = reward_energy
        self.reward_reputation = reward_reputation
        self.steps = steps

class Lab:
    def __init__(self):
        self.level = 1
        self.energy = 100
        self.samples = {"DNA": 10, "Protein": 5, "Lipid": 5}
        self.research_points = 0
        self.organelles = self.create_organelles()
        self.organelles["Nucleus"].unlocked = True

    def create_organelles(self):
        return {
            "Nucleus": Organelle("Nucleus", "Controls cell activities and stores DNA", 10, 0),
            "Mitochondrion": Organelle("Mitochondrion", "Produces energy (ATP)", 20, 50),
            "Ribosome": Organelle("Ribosome", "Synthesizes proteins", 15, 30),
            "EndoplasmicReticulum": Organelle("EndoplasmicReticulum", "Processes proteins and lipids", 25, 70),
            "GolgiApparatus": Organelle("GolgiApparatus", "Packages and distributes molecules", 30, 100)
        }

    def research_organelle(self, organelle_name):
        organelle = self.organelles.get(organelle_name)
        if not organelle:
            print("無效細胞器!")
            return False
        if organelle.unlocked:
            print(f"{organelle_name} 已解鎖!")
            return False
        if self.energy >= organelle.energy_cost and self.research_points >= organelle.research_points:
            self.energy -= organelle.energy_cost
            self.research_points -= organelle.research_points
            organelle.unlocked = True
            info = {
                "Nucleus": "細胞核是細胞的控制中心,儲存遺傳信息 (DNA)。",
                "Mitochondrion": "線粒體是能量工廠,通過氧化磷酸化產生 ATP。",
                "Ribosome": "核糖體負責翻譯 mRNA,合成蛋白質。",
                "EndoplasmicReticulum": "內質網加工蛋白質和脂質,分為粗糙和光滑內質網。",
                "GolgiApparatus": "高爾基體修飾、包裝和運輸分子到細胞內外。"
            }.get(organelle_name, "未知功能")
            print(f"成功解鎖 {organelle_name}:{organelle.function}\n{info}")
            return True
        print("能量或研究點不足!")
        return False

    def upgrade(self):
        cost = self.level * 50
        if self.energy >= cost:
            self.energy -= cost
            self.level += 1
            print(f"實驗室升級到等級 {self.level},花費 {cost} 能量。")
        else:
            print("能量不足,無法升級!")

    def perform_action(self, organelle_name, action):
        organelle = self.organelles.get(organelle_name)
        if not organelle or not organelle.unlocked:
            print(f"{organelle_name} 未解鎖或無效!")
            return False
        actions = {
            "Nucleus": {"Analyze DNA": ("DNA", -1, 5, 2)},
            "Mitochondrion": {"Produce ATP": ("", 0, 10, 0)},
            "Ribosome": {"Synthesize Protein": ("DNA", -1, 0, 5)},
            "EndoplasmicReticulum": {"Process Lipid": ("Lipid", -1, 0, 7)},
            "GolgiApparatus": {"Package Molecule": ("Protein", -1, 0, 10)}
        }
        if organelle_name in actions and action in actions[organelle_name]:
            sample, sample_change, energy_gain, points_gain = actions[organelle_name][action]
            if sample and self.samples.get(sample, 0) <= 0:
                print(f"缺少 {sample}!")
                return False
            cost = organelle.energy_cost
            if self.energy >= cost:
                self.energy -= cost
                if sample:
                    self.samples[sample] += sample_change
                self.energy += energy_gain
                self.research_points += points_gain
                self.samples[sample] = self.samples.get(sample, 0)
                print(f"{organelle_name} 執行 {action} 成功,獲得 {points_gain} 研究點,{energy_gain} 能量")
                return True
            print("能量不足!")
            return False
        print("無效動作!")
        return False

class CellGame:
    def __init__(self):
        self.lab = Lab()
        self.tasks = []
        self.reputation = 50
        self.turn = 0
        self.max_turns = 30
        self.game_over = False

    def run(self):
        print("歡迎來到《細胞探秘》!目標:在 30 天內完成所有任務並解鎖所有細胞器。")
        while not self.game_over:
            self.display_state()
            self.generate_tasks()
            action = self.get_action()
            if action == "research_organelle":
                self.research_organelle()
            elif action == "perform_action":
                self.perform_action()
            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 = True
            if self.check_lose():
                print("遊戲結束。未能在 30 天內達成目標,或聲譽過低。")
                self.game_over = True
            time.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(f"研究點: {self.lab.research_points}")
        print("樣本庫存:", {k: v for k, v in self.lab.samples.items() if v > 0})
        print("細胞器:", [f"{k} ({'已解鎖' if v.unlocked else '未解鎖'})" for k, v in self.lab.organelles.items()])
        print("任務:", [f"ID {t.id}: {t.target_organelle} - {t.target_action} ({t.steps} 步), 獎勵 {t.reward_energy} 能量, {t.reward_reputation} 聲譽" for t in self.tasks])

    def get_action(self):
        print("\n你想做什麼?")
        print("1. 研究細胞器")
        print("2. 執行細胞器動作")
        print("3. 升級實驗室")
        print("4. 完成任務")
        print("5. 保存遊戲")
        print("6. 加載遊戲")
        print("7. 結束天數")
        choice = input("輸入選項 (1-7): ")
        actions = {
            "1": "research_organelle",
            "2": "perform_action",
            "3": "upgrade_lab",
            "4": "complete_task",
            "5": "save_game",
            "6": "load_game",
            "7": "end_turn"
        }
        return actions.get(choice, self.get_action())

    def research_organelle(self):
        print("可研究細胞器:")
        for name, organelle in self.lab.organelles.items():
            if not organelle.unlocked:
                print(f"{name}: 需要 {organelle.energy_cost} 能量, {organelle.research_points} 研究點")
        organelle_name = input("輸入細胞器名稱:")
        self.lab.research_organelle(organelle_name)

    def perform_action(self):
        print("可用細胞器和動作:")
        for name, organelle in self.lab.organelles.items():
            if organelle.unlocked:
                actions = {
                    "Nucleus": ["Analyze DNA"],
                    "Mitochondrion": ["Produce ATP"],
                    "Ribosome": ["Synthesize Protein"],
                    "EndoplasmicReticulum": ["Process Lipid"],
                    "GolgiApparatus": ["Package Molecule"]
                }.get(name, [])
                print(f"{name}: {actions}")
        organelle_name = input("輸入細胞器名稱:")
        action = input("輸入動作:")
        if self.lab.perform_action(organelle_name, action):
            self.random_event()

    def generate_tasks(self):
        if random.random() < 0.7:
            task_id = len(self.tasks) + 1
            unlocked_organelles = [name for name, o in self.lab.organelles.items() if o.unlocked]
            if unlocked_organelles:
                organelle = random.choice(unlocked_organelles)
                actions = {
                    "Nucleus": ["Analyze DNA"],
                    "Mitochondrion": ["Produce ATP"],
                    "Ribosome": ["Synthesize Protein"],
                    "EndoplasmicReticulum": ["Process Lipid"],
                    "GolgiApparatus": ["Package Molecule"]
                }.get(organelle, [])
                action = random.choice(actions)
                reward_energy = random.randint(20, 50)
                reward_reputation = random.randint(5, 15)
                steps = 2 if organelle == "GolgiApparatus" else 1
                self.tasks.append(Task(task_id, organelle, action, reward_energy, reward_reputation, steps))
                print(f"新任務 ID {task_id}: {organelle} - {action} ({steps} 步), 獎勵 {reward_energy} 能量, {reward_reputation} 聲譽")

    def complete_task(self):
        if not self.tasks:
            print("沒有可用任務!")
            return
        print("可用任務:")
        for task in self.tasks:
            print(f"ID {task.id}: {task.target_organelle} - {task.target_action} ({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!")
                return
            required_samples = {"Analyze DNA": "DNA", "Synthesize Protein": "Protein", "Process Lipid": "Lipid", "Package Molecule": "Protein"}
            sample = required_samples.get(task.target_action)
            if not sample or self.lab.samples.get(sample, 0) >= task.steps:
                if sample:
                    self.lab.samples[sample] -= task.steps
                self.lab.energy += task.reward_energy
                self.reputation += task.reward_reputation
                self.tasks.remove(task)
                print(f"任務 ID {task_id} 完成!獲得 {task.reward_energy} 能量, {task.reward_reputation} 聲譽")
            else:
                print(f"庫存中缺少 {sample} 或數量不足(需 {task.steps} 單位)!")
        except ValueError:
            print("輸入錯誤,請重試。")

    def random_event(self):
        event = random.choice(["None", "CellMutation", "VirusInvasion"])
        if event == "CellMutation":
            cost = random.randint(5, 15)
            self.lab.energy -= cost
            print(f"細胞突變,損失 {cost} 能量!")
        elif event == "VirusInvasion":
            cost = self.lab.level * 20
            if self.lab.energy >= cost:
                self.lab.energy -= cost
                print(f"病毒入侵,修復費用 {cost} 能量。")
            else:
                print("病毒入侵未修復,聲譽下降!")
                self.reputation -= 5

    def save_game(self):
        state = {
            "turn": self.turn,
            "reputation": self.reputation,
            "lab": {
                "level": self.lab.level,
                "energy": self.lab.energy,
                "samples": self.lab.samples,
                "research_points": self.lab.research_points,
                "organelles": {name: o.unlocked for name, o in self.lab.organelles.items()}
            },
            "tasks": [{"id": t.id, "target_organelle": t.target_organelle, "target_action": t.target_action, "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.samples = state["lab"]["samples"]
            self.lab.research_points = state["lab"]["research_points"]
            for name, unlocked in state["lab"]["organelles"].items():
                self.lab.organelles[name].unlocked = unlocked
            self.tasks = [Task(t["id"], t["target_organelle"], t["target_action"], t["reward_energy"], t["reward_reputation"], t["steps"]) for t in state["tasks"]]
            print("遊戲已加載!")
        except FileNotFoundError:
            print("沒有找到存檔文件!")

    def end_turn(self):
        self.turn += 1
        self.lab.energy += 10
        self.lab.research_points += 5
        for task in self.tasks[:]:
            if random.random() < 0.2:
                print(f"任務 ID {task.id} 過期,聲譽下降!")
                self.reputation -= 5
                self.tasks.remove(task)
        self.random_event()

    def check_win(self):
        return all(o.unlocked for o in self.lab.organelles.values()) and not self.tasks

    def check_lose(self):
        return self.turn > self.max_turns or self.reputation < 0

main.py

from game import CellGame

if __name__ == "__main__":
    game = CellGame()
    game.run()