技术准备

在开始编码之前,我们需要准备开发环境和相关工具。以下是开发 PoetryCraftGame 所需的技术栈和资源。

1. 技术栈

  • 编程语言:Python 3.x(推荐 3.8 或更高版本)。
  • 核心库
  • numpy:处理词嵌入向量。
  • nltk:进行分词、词性标注和情感分析。
  • textblob:进行简单的情感分析。
  • random:生成随机诗歌结构和观众反应。
  • pygame:实现游戏图形界面和诗歌可视化。
  • json:保存和加载诗歌与游戏状态。
  • 数据存储
  • 列表存储诗歌、任务和观众评分。
  • 字典存储词库、情感和风格模板。
  • JSON 文件存储游戏进度。
  • 用户界面:基于 Pygame 的图形界面,显示诗歌、诗会场景和任务。
  • 依赖安装
  • numpypip install numpy
  • nltkpip install nltk(需下载数据:python -m nltk.downloader punkt vader_lexicon
  • textblobpip install textblob(需下载数据:python -m textblob.download_corpora
  • pygamepip install pygame
  • random 和 json 是 Python 标准库,无需额外安装。

2. 开发环境

确保已安装 Python(可从 python.org 下载)。推荐使用 Visual Studio Code 或 PyCharm 作为开发工具,提供代码补全和调试支持。项目结构如下:

poetrycraftgame/
├── main.py           # 主程序入口
├── game.py           # 游戏逻辑模块
├── poetry_generator.py # 诗歌生成与情感分析模块
└── data/            # 存储词库和模板├── word_bank.json # 词库├── templates.json # 诗歌模板

3. 游戏目标

玩家将扮演一名诗匠,目标是在 30 天内(游戏中的时间单位)创作出高质量的诗歌,达成以下目标:

  • 诗歌质量:平均观众评分 > 80 分。
  • 任务完成:完成至少 10 个创作任务。
  • 情感匹配:诗歌情感与任务要求匹配度 > 90%。 游戏采用回合制,每回合代表一天,玩家需要:
  • 创作诗歌:输入关键词、选择风格和情感。
  • 优化诗歌:调整韵律、词汇或结构。
  • 参与诗会:展示诗歌,获取评分。
  • 完成任务:达成主题、情感或韵律目标。
  • 可视化创作:观察诗歌生成和情感分析结果。
  • 学习科普知识:了解NLP和诗歌创作原理。
  • 保存/加载:保存诗歌和游戏进度。

游戏设计与核心功能

1. 游戏结构

我们将游戏分解为多个模块,使用类和函数封装功能,确保代码清晰且易于维护。以下是核心设计:

  • PoetryGenerator 类:生成诗歌并进行情感分析。
  • Poem 类:表示一首诗歌,存储内容、情感和评分。
  • Audience 类:模拟诗会观众,生成评分。
  • Task 类:定义创作任务和奖励。
  • PoetryCraftGame 类:管理游戏状态、诗歌和主循环。
  • 算法
  • 诗歌生成:基于模板和词库,结合用户输入生成诗歌。
  • 情感分析:使用 TextBlob 和 NLTK 分析诗歌情感。
  • 观众评分:根据诗歌质量、情感匹配和任务完成度评分。
  • 数据结构
  • 诗歌:列表存储诗句、情感和评分。
  • 词库:JSON 文件存储按情感和词性分类的词汇。
  • 模板:JSON 文件存储诗歌结构(五言、七言、自由诗)。
  • 任务:字典存储目标和奖励。
  • 游戏状态:天数、诗歌列表、任务和评分。

2. 核心代码实现

以下是游戏的完整代码框架,我们将逐一讲解每个模块的实现细节。

2.1 数据准备

首先生成词库和诗歌模板,保存为 JSON 文件。

# data/generate_data.py
import jsondef generate_word_bank():"""生成词库"""word_bank = {"positive": {"noun": ["sun", "flower", "hope", "dream", "love"],"verb": ["shine", "bloom", "soar", "smile", "embrace"],"adjective": ["bright", "warm", "joyful", "gentle", "serene"]},"negative": {"noun": ["storm", "shadow", "sorrow", "night", "tear"],"verb": ["fall", "fade", "wander", "weep", "shatter"],"adjective": ["dark", "cold", "lonely", "bleak", "silent"]},"neutral": {"noun": ["wind", "river", "sky", "path", "time"],"verb": ["flow", "drift", "rise", "walk", "wait"],"adjective": ["calm", "vast", "clear", "quiet", "steady"]}}with open("data/word_bank.json", "w") as f:json.dump(word_bank, f, indent=2)print("词库已生成!")def generate_templates():"""生成诗歌模板"""templates = {"five_syllable": ["{adjective} {noun}, {verb} {adjective}.","{noun} {verb}, {adjective} {noun}."],"seven_syllable": ["{adjective} {noun} {verb}, {adjective} {noun}.","{noun} {verb} {adjective}, {noun} {verb}."],"free_verse": ["{adjective} {noun}, {verb} through {noun}.","In {adjective} {noun}, {verb} {adjective} {noun}."]}with open("data/templates.json", "w") as f:json.dump(templates, f, indent=2)print("模板已生成!")if __name__ == "__main__":generate_word_bank()generate_templates()

说明

  • word_bank.json:按情感(积极、消极、中性)和词性(名词、动词、形容词)组织词汇。
  • templates.json:定义五言、七言和自由诗的句式模板。

2.2 诗歌生成类:PoetryGenerator

PoetryGenerator 类生成诗歌并分析情感。

# poetry_generator.py
import json
import random
from textblob import TextBlob
import nltk
nltk.download('vader_lexicon')
from nltk.sentiment.vader import SentimentIntensityAnalyzerclass PoetryGenerator:def __init__(self, word_bank_path="data/word_bank.json", templates_path="data/templates.json"):"""初始化诗歌生成器"""with open(word_bank_path, "r") as f:self.word_bank = json.load(f)with open(templates_path, "r") as f:self.templates = json.load(f)self.sid = SentimentIntensityAnalyzer()def generate_poem(self, keywords, style, emotion, lines=4):"""生成诗歌"""poem = []template_key = style if style in self.templates else "free_verse"templates = self.templates[template_key]for _ in range(lines):template = random.choice(templates)words = {}for word_type in ["noun", "verb", "adjective"]:if random.random() < 0.3 and keywords:words[word_type] = random.choice(keywords)else:words[word_type] = random.choice(self.word_bank[emotion][word_type])poem.append(template.format(**words))return poemdef analyze_sentiment(self, poem):"""分析诗歌情感"""text = " ".join(poem)scores = self.sid.polarity_scores(text)return scores["compound"]  # -1(消极)到 1(积极)

说明

  • __init__:加载词库和模板,初始化情感分析器。
  • generate_poem:根据关键词、风格和情感生成诗歌。
  • analyze_sentiment:使用 VADER 分析诗歌情感得分。

2.3 诗歌类:Poem

Poem 类表示一首诗歌。

# game.py
class Poem:def __init__(self, content, style, emotion):"""初始化诗歌"""self.content = contentself.style = styleself.emotion = emotionself.score = 0self.sentiment = 0

说明

  • __init__:存储诗歌内容、风格、情感、评分和情感分析结果。

2.4 观众类:Audience

Audience 类模拟诗会观众。

# game.py (续)
import randomclass Audience:def __init__(self):"""初始化观众"""self.preferences = {"style": random.choice(["five_syllable", "seven_syllable", "free_verse"]),"emotion": random.choice(["positive", "negative", "neutral"])}def evaluate_poem(self, poem, task_emotion=None):"""评估诗歌"""score = 50  # 基础分if poem.style == self.preferences["style"]:score += 20if poem.emotion == self.preferences["emotion"]:score += 20if task_emotion and poem.emotion == task_emotion:score += 10score += random.randint(-10, 10)  # 随机波动return max(0, min(100, score))

说明

  • __init__:初始化观众对风格和情感的偏好。
  • evaluate_poem:根据诗歌风格、情感和任务要求评分。

2.5 任务类:Task

Task 类定义创作任务。

# game.py (续)
class Task:def __init__(self, id, target, target_value, reward):"""初始化任务"""self.id = idself.target = target  # 目标(风格、情感、评分)self.target_value = target_valueself.reward = reward  # 奖励(资源或灵感值)self.created_day = 0

说明

  • __init__:初始化任务 ID、目标、目标值和奖励。

2.6 游戏类:PoetryCraftGame

PoetryCraftGame 类管理游戏状态和逻辑。

# game.py (续)
import pygame
import json
from poetry_generator import PoetryGeneratorclass PoetryCraftGame:def __init__(self):"""初始化游戏"""pygame.init()self.screen = pygame.display.set_mode((800, 600))pygame.display.set_caption("PoetryCraftGame")self.font = pygame.font.Font(None, 24)self.clock = pygame.time.Clock()self.generator = PoetryGenerator()self.day = 0self.max_days = 30self.poems = []self.tasks = []self.audience = Audience()self.resources = 100  # 灵感值self.game_over = Falseself.current_keywords = []self.current_style = "free_verse"self.current_emotion = "neutral"self.input_text = ""def run(self):"""游戏主循环"""print("欢迎来到《PoetryCraftGame》!目标:在 30 天内创作诗歌(评分 > 80,完成 10 个任务,情感匹配 > 90%)。")running = Truewhile running and not self.game_over:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:if self.input_text:self.current_keywords = self.input_text.split()self.input_text = ""elif event.key == pygame.K_BACKSPACE:self.input_text = self.input_text[:-1]elif event.key == pygame.K_s:self.save_game()elif event.key == pygame.K_l:self.load_game()elif event.key == pygame.K_1:self.current_style = "five_syllable"elif event.key == pygame.K_2:self.current_style = "seven_syllable"elif event.key == pygame.K_3:self.current_style = "free_verse"elif event.key == pygame.K_p:self.current_emotion = "positive"elif event.key == pygame.K_n:self.current_emotion = "negative"elif event.key == pygame.K_m:self.current_emotion = "neutral"elif event.key == pygame.K_SPACE and self.resources >= 20:self.create_poem()else:self.input_text += event.unicodeself.step()self.display_state()self.clock.tick(30)if self.check_win():print("恭喜!你成为诗匠大师!")self.game_over = Trueif self.check_lose():print("游戏结束。未能达成目标。")self.game_over = Truepygame.quit()def create_poem(self):"""创作诗歌"""poem = Poem(self.generator.generate_poem(self.current_keywords, self.current_style, self.current_emotion),self.current_style, self.current_emotion)poem.sentiment = self.generator.analyze_sentiment(poem.content)poem.score = self.audience.evaluate_poem(poem, self.get_task_emotion())self.poems.append(poem)self.resources -= 20print(f"创作诗歌:\n{'\n'.join(poem.content)}\n情感:{poem.emotion},评分:{poem.score}")def get_task_emotion(self):"""获取当前任务的情感要求"""for task in self.tasks:if task.target == "Emotion":return task.target_valuereturn Nonedef step(self):"""单步更新"""self.day += 1self.resources = min(100, self.resources + 5)  # 每日恢复灵感self.audience = Audience()  # 更新观众偏好self.generate_task()self.complete_tasks()def generate_task(self):"""生成任务"""if random.random() < 0.3:task_id = len(self.tasks) + 1target = random.choice(["Style", "Emotion", "Score"])target_value = random.choice(["five_syllable", "seven_syllable", "free_verse"]) if target == "Style" else \random.choice(["positive", "negative", "neutral"]) if target == "Emotion" else 80reward = {"resources": 30} if target != "Style" else {"resources": 20}task = Task(task_id, target, target_value, reward)task.created_day = self.dayself.tasks.append(task)print(f"任务 ID {task_id}: {target} 达到 {target_value},奖励 {reward}")def complete_tasks(self):"""完成任务"""for poem in self.poems[-1:]:  # 只检查最新诗歌for task in self.tasks[:]:if task.target == "Style" and poem.style == task.target_value:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif task.target == "Emotion" and poem.emotion == task.target_value and abs(poem.sentiment - {"positive": 0.5, "negative": -0.5, "neutral": 0.0}[task.target_value]) < 0.1:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif task.target == "Score" and poem.score >= task.target_value:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif self.day - task.created_day >= 5:print(f"任务 ID {task.id} 过期!")self.tasks.remove(task)def display_state(self):"""显示游戏状态"""self.screen.fill((255, 255, 255))# 显示诗歌if self.poems:poem = self.poems[-1]for i, line in enumerate(poem.content):rendered = self.font.render(line, True, (0, 0, 0))self.screen.blit(rendered, (50, 50 + i * 30))rendered = self.font.render(f"Style: {poem.style}, Emotion: {poem.emotion}, Score: {poem.score}", True, (0, 0, 0))self.screen.blit(rendered, (50, 50 + len(poem.content) * 30))# 显示状态texts = [f"Day: {self.day}/{self.max_days}",f"Resources: {self.resources:.1f}",f"Input Keywords: {self.input_text}",f"Style: {self.current_style} (1: Five, 2: Seven, 3: Free)",f"Emotion: {self.current_emotion} (P: Positive, N: Negative, M: Neutral)",f"Tasks Completed: {len([t for t in self.tasks if not t.created_day])}",f"Press SPACE to create poem (cost 20 resources)",f"Press S to save, L to load"]for i, text in enumerate(texts):rendered = self.font.render(text, True, (0, 0, 0))self.screen.blit(rendered, (10, 300 + i * 30))if self.tasks:for i, task in enumerate(self.tasks):text = f"Task {task.id}: {task.target} {task.target_value}"rendered = self.font.render(text, True, (0, 0, 0))self.screen.blit(rendered, (10, 500 + i * 30))pygame.display.flip()# CLI 输出print(f"\nDay {self.day}")print(f"资源: {self.resources:.1f}")print(f"当前风格: {self.current_style}, 情感: {self.current_emotion}")if self.poems:print(f"最新诗歌:\n{'\n'.join(self.poems[-1].content)}\n评分:{self.poems[-1].score}")def save_game(self):"""保存游戏状态"""state = {"day": self.day,"resources": self.resources,"poems": [{"content": p.content, "style": p.style, "emotion": p.emotion, "score": p.score, "sentiment": p.sentiment} for p in self.poems],"tasks": [{"id": t.id, "target": t.target, "target_value": t.target_value, "reward": t.reward, "created_day": t.created_day} for t in self.tasks],"current_keywords": self.current_keywords,"current_style": self.current_style,"current_emotion": self.current_emotion}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.day = state["day"]self.resources = state["resources"]self.poems = [Poem(p["content"], p["style"], p["emotion"]) for p in state["poems"]]for p, data in zip(self.poems, state["poems"]):p.score = data["score"]p.sentiment = data["sentiment"]self.tasks = [Task(t["id"], t["target"], t["target_value"], t["reward"]) for t in state["tasks"]]for t in self.tasks:t.created_day = state["tasks"][self.tasks.index(t)]["created_day"]self.current_keywords = state["current_keywords"]self.current_style = state["current_style"]self.current_emotion = state["current_emotion"]print("游戏已加载!")except FileNotFoundError:print("没有找到存档文件!")def check_win(self):"""检查胜利条件"""avg_score = sum(p.score for p in self.poems) / len(self.poems) if self.poems else 0tasks_completed = len([t for t in self.tasks if not t.created_day])sentiment_match = all(abs(p.sentiment - {"positive": 0.5, "negative": -0.5, "neutral": 0.0}[p.emotion]) < 0.1 for p in self.poems[-3:]) if len(self.poems) >= 3 else Falsereturn self.day >= self.max_days and avg_score > 80 and tasks_completed >= 10 and sentiment_matchdef check_lose(self):"""检查失败条件"""return self.day >= self.max_days and not self.check_win()

说明

  • __init__:初始化 Pygame、诗歌生成器、观众和游戏状态。
  • run:游戏主循环,处理输入、更新状态和渲染界面。
  • create_poem:生成并评估诗歌。
  • step:更新天数、资源和任务。
  • generate_task 和 complete_tasks:生成和完成任务。
  • display_state:绘制诗歌、状态和任务。
  • save_game 和 load_game:保存和加载游戏状态。
  • check_win 和 check_lose:检查胜利和失败条件。

2.7 主程序:main.py

启动游戏的入口文件。

# main.py
from game import PoetryCraftGameif __name__ == "__main__":game = PoetryCraftGame()game.run()

运行游戏

1. 准备数据

首先生成词库和模板:

mkdir data
python data/generate_data.py

2. 启动游戏

确保安装了依赖,在项目目录下运行:

pip install numpy nltk textblob pygame
python -m nltk.downloader punkt vader_lexicon
python -m textblob.download_corpora
python main.py

3. 游戏流程

  1. 初始化
  • 加载词库和模板。
  • 初始化资源(100 灵感值)。
  1. 每日循环
  • 输入:输入关键词(回车确认),选择风格(1/2/3)和情感(P/N/M)。
  • 创作:按空格键消耗 20 资源生成诗歌。
  • 诗会:观众根据风格和情感评分。
  • 任务:完成风格、情感或评分任务。
  • 可视化:显示诗歌、状态和任务。
  1. 游戏结束
  • 平均评分 > 80,完成 10 个任务,情感匹配 > 90% 胜利。
  • 30 天未达标失败。

4. 示例运行

欢迎来到《PoetryCraftGame》!目标:在 30 天内创作诗歌(评分 > 80,完成 10 个任务,情感匹配 > 90%)。Day 1
资源: 100.0
当前风格: free_verse, 情感: neutral
任务 ID 1: Style 达到 five_syllable,奖励 {'resources': 20}Day 2
资源: 85.0
当前风格: five_syllable, 情感: positive
创作诗歌:
Bright sun, shine gentle.
Hope blooms, joyful dream.
最新诗歌:
Bright sun, shine gentle.
Hope blooms, joyful dream.
评分:85
任务 ID 1 完成!资源增加 20Day 3
资源: 90.0
当前风格: seven_syllable, 情感: negative
创作诗歌:
Dark storm weeps, lonely shadow.
Sorrow falls, bleak night fades.
评分:75

分析

  • 第一天:生成风格任务。
  • 第二天:切换风格为五言,创作积极诗歌,完成任务。
  • 第三天:创作七言消极诗歌,评分略低。

游戏机制详解

1. 诗歌生成

  • 模板:五言、七言或自由诗,随机填充词汇。
  • 关键词:玩家输入的词有 30% 概率融入。
  • 情感:根据玩家选择从对应情感词库选词。
  • 生成:每行基于模板,随机选择词汇。

2. 情感分析

  • 工具:NLTK VADER,输出 -1(消极)到 1(积极)的得分。
  • 匹配:情感得分需接近目标(正 0.5,负 -0.5,中性 0.0)。

3. 观众评分

  • 规则
  • 基础分 50。
  • 风格匹配 +20,情感匹配 +20,任务情感匹配 +10。
  • 随机波动 ±10。
  • 偏好:每日随机更新观众偏好。

4. 任务系统

  • 风格任务:使用指定风格,奖励 20 资源。
  • 情感任务:匹配指定情感,奖励 30 资源。
  • 评分任务:达到 80 分,奖励 30 资源。
  • 过期:5 天未完成移除。

5. 可视化

  • 诗歌:显示最新诗歌内容、风格、情感和评分。
  • 状态:显示天数、资源、输入关键词、风格和情感。
  • 任务:显示当前任务和目标。

6. 胜利与失败

  • 胜利:30 天后平均评分 > 80,完成 10 个任务,情感匹配 > 90%。
  • 失败:30 天未达标。

游戏扩展与优化

当前版本是一个功能完整的互动诗歌生成器游戏原型,我们可以通过以下方式增强游戏性、技术实现和教育价值。

1. 游戏性增强

  • 新风格:添加古体诗、现代诗等模板。
  • 动态词库:支持玩家添加自定义词汇。
  • 多人模式:玩家轮流创作,竞争评分。
  • 交互编辑:允许玩家直接修改诗句。

示例代码:动态词库

class PoetryGenerator:def add_word(self, word, emotion, word_type):"""添加自定义词汇"""self.word_bank[emotion][word_type].append(word)with open("data/word_bank.json", "w") as f:json.dump(self.word_bank, f, indent=2)print(f"添加词汇:{word} ({emotion}, {word_type})")

实现效果

  • 玩家可添加词汇,丰富词库。

2. 技术优化

  • 生成模型:使用预训练模型(如 GPT-2)生成更自然的诗歌。
  • 韵律分析:添加韵脚和节奏检测。
  • 并行计算:加速情感分析。
  • 存档加密:防止修改存档文件。

示例代码:韵脚检测

class PoetryGenerator:def check_rhyme(self, poem):"""检测韵脚"""vowels = "aeiou"last_words = [line.split()[-1].lower() for line in poem]endings = [''.join(c for c in word if c in vowels) for word in last_words]return len(set(endings)) == 1

实现效果

  • 检测诗歌是否押韵,提升创作质量。

3. 教育模块

  • NLP科普:介绍分词、词性标注和情感分析。
  • 诗歌科普:解释五言、七言和自由诗的结构。
  • 创作技巧:分享如何选择词汇和表达情感。

示例代码:科普提示

class PoetryCraftGame:def display_state(self):self.screen.fill((255, 255, 255))# 显示诗歌和状态(同上)if self.day % 5 == 0:tips = ["情感分析通过词汇的情感极性判断诗歌语气。","五言诗每行五个字,节奏鲜明。","关键词能让诗歌更贴近你的创意!"]tip = random.choice(tips)rendered = self.font.render(tip, True, (255, 165, 0))self.screen.blit(rendered, (10, 550))pygame.display.flip()# CLI 输出(同上)

实现效果

  • 每 5 天显示一个随机科普提示。

游戏策略与玩法分析

1. 玩家策略

  • 关键词选择:输入与情感相关的词提升匹配度。
  • 风格调整:根据任务和观众偏好选择风格。
  • 情感管理:确保诗歌情感与任务一致。
  • 资源管理:平衡创作和任务完成。

2. 平衡性

  • 初始资源:100 灵感值足够早期创作。
  • 任务概率:30% 提供适度挑战。
  • 评分波动:随机性增加重玩价值。
  • 时间限制:30 天需高效创作。

3. 重玩价值

  • 尝试不同风格和情感。
  • 优化关键词选择。
  • 学习 NLP 和诗歌创作知识。

总结与未来展望

通过这篇博文,您已经成功构建了一个互动诗歌生成器游戏 PoetryCraftGame!这个项目展示了如何使用 Python 创建一个结合 NLP、创意写作和游戏开发的复杂项目。以下是回顾和未来方向:

1. 收获

  • 掌握了 Python OOP、NLP 和情感分析。
  • 实现了诗歌生成、诗会和可视化系统。
  • 体验了创意写作与技术的结合。

2. 未来扩展

  • 复杂模型:引入 GPT 或 BERT 生成更自然的诗歌。
  • 动态模板:支持自定义诗歌结构。
  • 社交功能:分享诗歌到虚拟社区。
  • 教育增强:增加更多 NLP 和诗歌科普。

3. 动手实践

快去运行代码,创作你的诗篇吧!您可以尝试:

  • 创作高评分诗歌。
  • 优化情感匹配。
  • 实现动态词库或韵脚检测。

希望这篇教程为您打开了互动诗歌生成游戏开发的大门!如果您有疑问或建议,请留言,我将进一步完善内容。祝您编程愉快,享受 PoetryCraftGame 的诗意冒险!


附录:完整代码

以下是整合后的完整代码,分为 generate_data.pypoetry_generator.pygame.pymain.py,可直接运行。

data/generate_data.py

import jsondef generate_word_bank():word_bank = {"positive": {"noun": ["sun", "flower", "hope", "dream", "love"],"verb": ["shine", "bloom", "soar", "smile", "embrace"],"adjective": ["bright", "warm", "joyful", "gentle", "serene"]},"negative": {"noun": ["storm", "shadow", "sorrow", "night", "tear"],"verb": ["fall", "fade", "wander", "weep", "shatter"],"adjective": ["dark", "cold", "lonely", "bleak", "silent"]},"neutral": {"noun": ["wind", "river", "sky", "path", "time"],"verb": ["flow", "drift", "rise", "walk", "wait"],"adjective": ["calm", "vast", "clear", "quiet", "steady"]}}with open("data/word_bank.json", "w") as f:json.dump(word_bank, f, indent=2)print("词库已生成!")def generate_templates():templates = {"five_syllable": ["{adjective} {noun}, {verb} {adjective}.","{noun} {verb}, {adjective} {noun}."],"seven_syllable": ["{adjective} {noun} {verb}, {adjective} {noun}.","{noun} {verb} {adjective}, {noun} {verb}."],"free_verse": ["{adjective} {noun}, {verb} through {noun}.","In {adjective} {noun}, {verb} {adjective} {noun}."]}with open("data/templates.json", "w") as f:json.dump(templates, f, indent=2)print("模板已生成!")if __name__ == "__main__":generate_word_bank()generate_templates()

poetry_generator.py

import json
import random
from textblob import TextBlob
import nltk
nltk.download('vader_lexicon')
from nltk.sentiment.vader import SentimentIntensityAnalyzerclass PoetryGenerator:def __init__(self, word_bank_path="data/word_bank.json", templates_path="data/templates.json"):with open(word_bank_path, "r") as f:self.word_bank = json.load(f)with open(templates_path, "r") as f:self.templates = json.load(f)self.sid = SentimentIntensityAnalyzer()def generate_poem(self, keywords, style, emotion, lines=4):poem = []template_key = style if style in self.templates else "free_verse"templates = self.templates[template_key]for _ in range(lines):template = random.choice(templates)words = {}for word_type in ["noun", "verb", "adjective"]:if random.random() < 0.3 and keywords:words[word_type] = random.choice(keywords)else:words[word_type] = random.choice(self.word_bank[emotion][word_type])poem.append(template.format(**words))return poemdef analyze_sentiment(self, poem):text = " ".join(poem)scores = self.sid.polarity_scores(text)return scores["compound"]

game.py

import pygame
import json
import random
from poetry_generator import PoetryGeneratorclass Poem:def __init__(self, content, style, emotion):self.content = contentself.style = styleself.emotion = emotionself.score = 0self.sentiment = 0class Audience:def __init__(self):self.preferences = {"style": random.choice(["five_syllable", "seven_syllable", "free_verse"]),"emotion": random.choice(["positive", "negative", "neutral"])}def evaluate_poem(self, poem, task_emotion=None):score = 50if poem.style == self.preferences["style"]:score += 20if poem.emotion == self.preferences["emotion"]:score += 20if task_emotion and poem.emotion == task_emotion:score += 10score += random.randint(-10, 10)return max(0, min(100, score))class Task:def __init__(self, id, target, target_value, reward):self.id = idself.target = targetself.target_value = target_valueself.reward = rewardself.created_day = 0class PoetryCraftGame:def __init__(self):pygame.init()self.screen = pygame.display.set_mode((800, 600))pygame.display.set_caption("PoetryCraftGame")self.font = pygame.font.Font(None, 24)self.clock = pygame.time.Clock()self.generator = PoetryGenerator()self.day = 0self.max_days = 30self.poems = []self.tasks = []self.audience = Audience()self.resources = 100self.game_over = Falseself.current_keywords = []self.current_style = "free_verse"self.current_emotion = "neutral"self.input_text = ""def run(self):print("欢迎来到《PoetryCraftGame》!目标:在 30 天内创作诗歌(评分 > 80,完成 10 个任务,情感匹配 > 90%)。")running = Truewhile running and not self.game_over:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:if self.input_text:self.current_keywords = self.input_text.split()self.input_text = ""elif event.key == pygame.K_BACKSPACE:self.input_text = self.input_text[:-1]elif event.key == pygame.K_s:self.save_game()elif event.key == pygame.K_l:self.load_game()elif event.key == pygame.K_1:self.current_style = "five_syllable"elif event.key == pygame.K_2:self.current_style = "seven_syllable"elif event.key == pygame.K_3:self.current_style = "free_verse"elif event.key == pygame.K_p:self.current_emotion = "positive"elif event.key == pygame.K_n:self.current_emotion = "negative"elif event.key == pygame.K_m:self.current_emotion = "neutral"elif event.key == pygame.K_SPACE and self.resources >= 20:self.create_poem()else:self.input_text += event.unicodeself.step()self.display_state()self.clock.tick(30)if self.check_win():print("恭喜!你成为诗匠大师!")self.game_over = Trueif self.check_lose():print("游戏结束。未能达成目标。")self.game_over = Truepygame.quit()def create_poem(self):poem = Poem(self.generator.generate_poem(self.current_keywords, self.current_style, self.current_emotion),self.current_style, self.current_emotion)poem.sentiment = self.generator.analyze_sentiment(poem.content)poem.score = self.audience.evaluate_poem(poem, self.get_task_emotion())self.poems.append(poem)self.resources -= 20print(f"创作诗歌:\n{'\n'.join(poem.content)}\n情感:{poem.emotion},评分:{poem.score}")def get_task_emotion(self):for task in self.tasks:if task.target == "Emotion":return task.target_valuereturn Nonedef step(self):self.day += 1self.resources = min(100, self.resources + 5)self.audience = Audience()self.generate_task()self.complete_tasks()def generate_task(self):if random.random() < 0.3:task_id = len(self.tasks) + 1target = random.choice(["Style", "Emotion", "Score"])target_value = random.choice(["five_syllable", "seven_syllable", "free_verse"]) if target == "Style" else \random.choice(["positive", "negative", "neutral"]) if target == "Emotion" else 80reward = {"resources": 30} if target != "Style" else {"resources": 20}task = Task(task_id, target, target_value, reward)task.created_day = self.dayself.tasks.append(task)print(f"任务 ID {task_id}: {target} 达到 {target_value},奖励 {reward}")def complete_tasks(self):for poem in self.poems[-1:]:for task in self.tasks[:]:if task.target == "Style" and poem.style == task.target_value:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif task.target == "Emotion" and poem.emotion == task.target_value and abs(poem.sentiment - {"positive": 0.5, "negative": -0.5, "neutral": 0.0}[task.target_value]) < 0.1:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif task.target == "Score" and poem.score >= task.target_value:self.resources += task.reward.get("resources", 0)self.tasks.remove(task)print(f"任务 ID {task.id} 完成!资源增加 {task.reward.get('resources', 0)}")elif self.day - task.created_day >= 5:print(f"任务 ID {task.id} 过期!")self.tasks.remove(task)def display_state(self):self.screen.fill((255, 255, 255))if self.poems:poem = self.poems[-1]for i, line in enumerate(poem.content):rendered = self.font.render(line, True, (0, 0, 0))self.screen.blit(rendered, (50, 50 + i * 30))rendered = self.font.render(f"Style: {poem.style}, Emotion: {poem.emotion}, Score: {poem.score}", True, (0, 0, 0))self.screen.blit(rendered, (50, 50 + len(poem.content) * 30))texts = [f"Day: {self.day}/{self.max_days}",f"Resources: {self.resources:.1f}",f"Input Keywords: {self.input_text}",f"Style: {self.current_style} (1: Five, 2: Seven, 3: Free)",f"Emotion: {self.current_emotion} (P: Positive, N: Negative, M: Neutral)",f"Tasks Completed: {len([t for t in self.tasks if not t.created_day])}",f"Press SPACE to create poem (cost 20 resources)",f"Press S to save, L to load"]for i, text in enumerate(texts):rendered = self.font.render(text, True, (0, 0, 0))self.screen.blit(rendered, (10, 300 + i * 30))if self.tasks:for i, task in enumerate(self.tasks):text = f"Task {task.id}: {task.target} {task.target_value}"rendered = self.font.render(text, True, (0, 0, 0))self.screen.blit(rendered, (10, 500 + i * 30))pygame.display.flip()print(f"\nDay {self.day}")print(f"资源: {self.resources:.1f}")print(f"当前风格: {self.current_style}, 情感: {self.current_emotion}")if self.poems:print(f"最新诗歌:\n{'\n'.join(self.poems[-1].content)}\n评分:{self.poems[-1].score}")def save_game(self):state = {"day": self.day,"resources": self.resources,"poems": [{"content": p.content, "style": p.style, "emotion": p.emotion, "score": p.score, "sentiment": p.sentiment} for p in self.poems],"tasks": [{"id": t.id, "target": t.target, "target_value": t.target_value, "reward": t.reward, "created_day": t.created_day} for t in self.tasks],"current_keywords": self.current_keywords,"current_style": self.current_style,"current_emotion": self.current_emotion}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.day = state["day"]self.resources = state["resources"]self.poems = [Poem(p["content"], p["style"], p["emotion"]) for p in state["poems"]]for p, data in zip(self.poems, state["poems"]):p.score = data["score"]p.sentiment = data["sentiment"]self.tasks = [Task(t["id"], t["target"], t["target_value"], t["reward"]) for t in state["tasks"]]for t in self.tasks:t.created_day = state["tasks"][self.tasks.index(t)]["created_day"]self.current_keywords = state["current_keywords"]self.current_style = state["current_style"]self.current_emotion = state["current_emotion"]print("游戏已加载!")except FileNotFoundError:print("没有找到存档文件!")def check_win(self):avg_score = sum(p.score for p in self.poems) / len(self.poems) if self.poems else 0tasks_completed = len([t for t in self.tasks if not t.created_day])sentiment_match = all(abs(p.sentiment - {"positive": 0.5, "negative": -0.5, "neutral": 0.0}[p.emotion]) < 0.1 for p in self.poems[-3:]) if len(self.poems) >= 3 else Falsereturn self.day >= self.max_days and avg_score > 80 and tasks_completed >= 10 and sentiment_matchdef check_lose(self):return self.day >= self.max_days and not self.check_win()

main.py

from game import PoetryCraftGameif __name__ == "__main__":game = PoetryCraftGame()game.run()