UNPKG

novel-writer-cn

Version:

AI 驱动的中文小说创作工具 - 基于结构化工作流的智能写作助手

337 lines 12.7 kB
/** * 混合方法支持 * 允许组合使用多种写作方法 */ export class HybridMethodManager { /** * 预定义的有效混合组合 */ validCombinations = [ { name: '史诗奇幻组合', primary: 'hero-journey', secondary: 'story-circle', description: '主线用英雄之旅,角色支线用故事圈', suitable: ['奇幻', '史诗', '系列小说'] }, { name: '悬疑惊悚组合', primary: 'seven-point', secondary: 'three-act', description: '整体用七点结构,章节用三幕组织', suitable: ['悬疑', '惊悚', '推理'] }, { name: '多线叙事组合', primary: 'three-act', secondary: 'story-circle', micro: 'pixar-formula', description: '主线三幕,支线故事圈,场景用皮克斯', suitable: ['群像', '多线', '现代文学'] }, { name: '成长故事组合', primary: 'story-circle', secondary: 'hero-journey', description: '整体循环结构,关键章节用英雄之旅', suitable: ['成长', '青春', '系列'] } ]; /** * 创建混合结构 */ createHybridStructure(config, storyDetails) { // 验证组合有效性 this.validateCombination(config); // 创建主线结构 const mainPlot = this.createMainPlot(config.primary.method, storyDetails); // 创建次要结构 const mapping = { mainPlot }; if (config.secondary) { if (config.secondary.scope === 'sub-plot') { mapping.subPlots = this.createSubPlots(config.secondary.method, storyDetails); } else if (config.secondary.scope === 'character-arc') { mapping.characterArcs = this.createCharacterArcs(config.secondary.method, storyDetails); } } if (config.micro) { mapping.chapterTemplates = this.createChapterTemplates(config.micro.method, storyDetails); } // 生成指导原则 const guidelines = this.generateGuidelines(config); // 生成示例 const examples = this.generateExamples(config); return { config, mapping, guidelines, examples }; } /** * 验证组合有效性 */ validateCombination(config) { const incompatible = [ ['pixar-formula', 'hero-journey'], // 复杂度不匹配 ['pixar-formula', 'seven-point'] // 复杂度不匹配 ]; if (config.primary && config.secondary) { const pair = [config.primary.method, config.secondary.method].sort(); incompatible.forEach(([a, b]) => { if (pair[0] === a && pair[1] === b) { throw new Error(`不建议的组合:${a}${b} 复杂度差异太大`); } }); } } /** * 创建主线结构 */ createMainPlot(method, storyDetails) { const structures = { 'three-act': [ { name: '第一幕:建立', chapters: [1, 25], description: '介绍世界和冲突' }, { name: '第二幕:发展', chapters: [26, 75], description: '冲突升级和发展' }, { name: '第三幕:解决', chapters: [76, 100], description: '高潮和结局' } ], 'hero-journey': [ { name: '平凡世界', chapters: [1, 8], description: '英雄的日常' }, { name: '冒险召唤', chapters: [9, 16], description: '打破平静' }, // ... 其他阶段 ], 'seven-point': [ { name: '钩子', chapters: [1, 3], description: '吸引读者' }, { name: 'PP1', chapters: [25], description: '第一情节点' }, // ... 其他节点 ] }; return { method, elements: structures[method] || [] }; } /** * 创建支线结构 */ createSubPlots(method, storyDetails) { // 为每条支线创建结构 const subPlots = []; if (storyDetails.subPlots) { storyDetails.subPlots.forEach((subplot) => { subPlots.push({ method, elements: this.adaptStructureToSubplot(method, subplot) }); }); } return subPlots; } /** * 创建角色弧线结构 */ createCharacterArcs(method, storyDetails) { const arcs = []; if (storyDetails.characters) { storyDetails.characters.forEach((character) => { if (character.hasArc) { arcs.push({ character: character.name, method, arc: this.createCharacterArcElements(method, character) }); } }); } return arcs; } /** * 创建章节模板 */ createChapterTemplates(method, storyDetails) { if (method === 'pixar-formula') { return [ { method: 'pixar-formula', template: ` ## 章节结构(皮克斯公式) 1. 开始状态:[本章开始时的情况] 2. 日常/期望:[角色在做什么/想要什么] 3. 变化事件:[什么打破了平静] 4. 因此1:[直接后果] 5. 因此2:[连锁反应] 6. 结果:[本章结尾状态] ` } ]; } return []; } /** * 适配结构到支线 */ adaptStructureToSubplot(method, subplot) { // 简化主线结构用于支线 if (method === 'story-circle') { return [ { name: '舒适区', chapters: subplot.startChapter, description: '支线起点' }, { name: '需要', chapters: subplot.startChapter + 2, description: '产生需求' }, { name: '搜索', chapters: subplot.middleChapters, description: '寻找解决' }, { name: '找到', chapters: subplot.endChapter - 2, description: '获得答案' }, { name: '改变', chapters: subplot.endChapter, description: '支线解决' } ]; } return []; } /** * 创建角色弧线元素 */ createCharacterArcElements(method, character) { if (method === 'story-circle') { return [ { name: '初始状态', chapters: [1, 10], description: `${character.name}的起点` }, { name: '产生需求', chapters: [11, 20], description: '意识到缺失' }, { name: '努力改变', chapters: [21, 60], description: '尝试和失败' }, { name: '获得成长', chapters: [61, 80], description: '真正的改变' }, { name: '新的自我', chapters: [81, 100], description: '完成转变' } ]; } return []; } /** * 生成指导原则 */ generateGuidelines(config) { const guidelines = []; guidelines.push(`主线情节使用${this.getMethodName(config.primary.method)}结构`); if (config.secondary) { if (config.secondary.scope === 'sub-plot') { guidelines.push(`支线情节使用${this.getMethodName(config.secondary.method)}结构`); guidelines.push('支线不要喧宾夺主,保持与主线的关联'); } else if (config.secondary.scope === 'character-arc') { guidelines.push(`角色成长使用${this.getMethodName(config.secondary.method)}追踪`); guidelines.push('确保角色弧线与主线情节同步发展'); } } if (config.micro) { guidelines.push(`单个${config.micro.scope}可以使用${this.getMethodName(config.micro.method)}组织`); guidelines.push('微观结构要服务于宏观结构'); } guidelines.push('保持整体的一致性和连贯性'); guidelines.push('避免结构冲突和重复'); return guidelines; } /** * 生成示例 */ generateExamples(config) { const examples = []; if (config.primary.method === 'hero-journey' && config.secondary?.method === 'story-circle') { examples.push(` 示例:《奇幻冒险》 - 主线(英雄之旅):主角从平凡少年成长为拯救世界的英雄 - 支线A(故事圈):导师角色寻找传承者的循环 - 支线B(故事圈):反派从善到恶的堕落循环 `); } if (config.primary.method === 'seven-point' && config.micro?.method === 'pixar-formula') { examples.push(` 示例:《都市悬疑》 - 整体结构(七点):通过7个关键节点推进悬疑 - 章节结构(皮克斯):每章用"因此...因此...最终"推进 `); } return examples; } /** * 推荐混合方案 */ recommendHybrid(genre, length, complexity) { // 根据特征推荐混合方案 if (genre === '奇幻' && length > 200000 && complexity === '复杂') { return { primary: { method: 'hero-journey', scope: 'main-plot' }, secondary: { method: 'story-circle', scope: 'character-arc' } }; } if (genre === '悬疑' && complexity === '中等') { return { primary: { method: 'seven-point', scope: 'main-plot' }, micro: { method: 'three-act', scope: 'chapter' } }; } if (genre === '群像' || genre === '多线') { return { primary: { method: 'three-act', scope: 'main-plot' }, secondary: { method: 'story-circle', scope: 'sub-plot' } }; } return null; } /** * 生成混合方法文档 */ generateHybridDocument(structure) { let doc = `# 混合方法结构文档\n\n`; doc += `## 方法配置\n`; doc += `- **主要方法**:${this.getMethodName(structure.config.primary.method)} (${structure.config.primary.scope})\n`; if (structure.config.secondary) { doc += `- **次要方法**:${this.getMethodName(structure.config.secondary.method)} (${structure.config.secondary.scope})\n`; } if (structure.config.micro) { doc += `- **微观方法**:${this.getMethodName(structure.config.micro.method)} (${structure.config.micro.scope})\n`; } doc += `\n## 结构映射\n\n`; doc += `### 主线结构\n`; structure.mapping.mainPlot.elements.forEach(element => { doc += `- **${element.name}**:第${element.chapters[0]}-${element.chapters[1]}章 - ${element.description}\n`; }); if (structure.mapping.subPlots) { doc += `\n### 支线结构\n`; structure.mapping.subPlots.forEach((subplot, index) => { doc += `#### 支线${index + 1}\n`; subplot.elements.forEach(element => { doc += `- ${element.name}${element.description}\n`; }); }); } if (structure.mapping.characterArcs) { doc += `\n### 角色弧线\n`; structure.mapping.characterArcs.forEach(arc => { doc += `#### ${arc.character}\n`; arc.arc.forEach(element => { doc += `- ${element.name}:第${element.chapters[0]}-${element.chapters[1]}章\n`; }); }); } doc += `\n## 使用指南\n`; structure.guidelines.forEach(guideline => { doc += `- ${guideline}\n`; }); if (structure.examples.length > 0) { doc += `\n## 示例\n`; structure.examples.forEach(example => { doc += example + '\n'; }); } return doc; } /** * 获取方法中文名 */ getMethodName(method) { const names = { 'three-act': '三幕结构', 'hero-journey': '英雄之旅', 'story-circle': '故事圈', 'seven-point': '七点结构', 'pixar-formula': '皮克斯公式' }; return names[method] || method; } } //# sourceMappingURL=hybrid-method.js.map