UNPKG

ziwei-mcp

Version:

紫微斗数 MCP (Ziwei Doushu Model Context Protocol) - 基于 MCP 协议的紫微斗数命理分析工具

890 lines (780 loc) 22.1 kB
/** * 增强版紫微斗数命盘生成器 * 实现真实的紫微斗数算法 */ const { CalendarConverter } = require("./calendar.js"); const { v4: uuidv4 } = require("uuid"); /** * 天干地支映射 */ const TIANGAN = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]; const DIZHI = [ "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥", ]; /** * 十二宫名称 */ const PALACE_NAMES = [ "命宫", "兄弟宫", "夫妻宫", "子女宫", "财帛宫", "疾厄宫", "迁移宫", "奴仆宫", "官禄宫", "田宅宫", "福德宫", "父母宫", ]; class EnhancedChartGenerator { constructor() { this.charts = new Map(); this.starsDatabase = this.loadStarsDatabase(); this.palacesDatabase = this.loadPalacesDatabase(); } /** * 生成增强版紫微斗数命盘 */ async generateChart(input) { try { // 验证输入参数 this.validateInput(input); // 转换日期 const solarDate = this.parseBirthInfo(input); const lunarDate = CalendarConverter.solarToLunar(solarDate); // 生成命盘ID const chartId = uuidv4(); // 计算年龄 const age = CalendarConverter.calculateAge(solarDate); // 生成基本信息 const chartInfo = { id: chartId, name: input.name || "未知", gender: input.gender, birthDate: input.birthDate, birthTime: input.birthTime, birthLocation: input.birthLocation || "", lunarDate: this.formatLunarDate(lunarDate), age: age, createdAt: new Date().toISOString(), }; // 精确排盘计算 const palaces = this.calculatePalacesEnhanced(lunarDate, input.gender); // 精确安星 this.placeStarsEnhanced(palaces, lunarDate); // 确定命宫和身宫 const destinyPalace = this.findDestinyPalace(palaces, lunarDate); const bodyPalace = this.findBodyPalace(palaces, lunarDate); // 计算四化 const sihua = this.calculateSihua(lunarDate.yearInGanZhi[0], palaces); // 识别格局 const patterns = this.recognizePatterns( palaces, destinyPalace, bodyPalace, ); // 构建完整命盘 const chart = { id: chartId, info: { ...chartInfo, destinyPalace: destinyPalace.id, bodyPalace: bodyPalace.id, }, palaces: palaces, lunarInfo: lunarDate, sihua: sihua, patterns: patterns, metadata: { version: "2.0.0", algorithm: "enhanced_traditional", generatedAt: new Date().toISOString(), accuracy: "professional", }, }; // 存储命盘 this.charts.set(chartId, chart); return { success: true, data: { chartId: chartId, chart: chart, summary: this.generateEnhancedSummary(chart), }, }; } catch (error) { console.error("生成命盘失败:", error); return { success: false, error: error.message, }; } } /** * 增强版宫位计算 */ calculatePalacesEnhanced(lunarDate, gender) { const palaces = []; // 计算命宫位置(精确算法) const destinyPosition = this.calculateDestinyPositionEnhanced(lunarDate); // 生成十二宫 for (let i = 0; i < 12; i++) { const palacePosition = (destinyPosition + i) % 12; const palace = { id: i + 1, name: PALACE_NAMES[i], position: palacePosition, earthlyBranch: DIZHI[palacePosition], element: this.getElementByPosition(palacePosition), stars: [], brightness: {}, sihua: {}, isDestinyPalace: i === 0, isBodyPalace: false, // 后续计算身宫时设置 }; palaces.push(palace); } return palaces; } /** * 精确计算命宫位置 */ calculateDestinyPositionEnhanced(lunarDate) { // 命宫 = 寅宫 + 生月数 - 生时数 const birthMonth = lunarDate.month; const birthHour = Math.floor(lunarDate.hour / 2); // 转换为时辰 // 寅宫为2(从子=0开始计算) let destinyPos = 2 + birthMonth - 1 - birthHour; // 确保结果在0-11范围内 while (destinyPos < 0) destinyPos += 12; destinyPos = destinyPos % 12; return destinyPos; } /** * 增强版安星算法 */ placeStarsEnhanced(palaces, lunarDate) { // 安主星 this.placeMainStarsEnhanced(palaces, lunarDate); // 安辅星 this.placeAuxiliaryStarsEnhanced(palaces, lunarDate); // 安煞星 this.placeMaleficStarsEnhanced(palaces, lunarDate); // 计算星曜亮度 this.calculateBrightnessEnhanced(palaces); } /** * 精确安主星 */ placeMainStarsEnhanced(palaces, lunarDate) { // 计算紫微星位置(精确算法) const ziweiPosition = this.calculateZiweiPositionEnhanced(lunarDate); this.addStarToPalace(palaces, ziweiPosition, { name: "紫微", type: "main", category: "帝星", element: "土", }); // 计算天府星位置(与紫微相对) const tianfuPosition = (ziweiPosition + 6) % 12; this.addStarToPalace(palaces, tianfuPosition, { name: "天府", type: "main", category: "财星", element: "土", }); // 紫微星系(以紫微为基准) const ziweiStars = [ { name: "天机", offset: 1, element: "木" }, { name: "太阳", offset: this.calculateTaiyangOffset(lunarDate), element: "火", }, { name: "武曲", offset: 4, element: "金" }, { name: "天同", offset: 5, element: "水" }, { name: "廉贞", offset: 8, element: "火" }, ]; ziweiStars.forEach((star) => { const position = (ziweiPosition + star.offset) % 12; this.addStarToPalace(palaces, position, { name: star.name, type: "main", element: star.element, }); }); // 天府星系(以天府为基准) const tianfuStars = [ { name: "太阴", offset: this.calculateTaiyinOffset(lunarDate), element: "水", }, { name: "贪狼", offset: 1, element: "木" }, { name: "巨门", offset: 2, element: "土" }, { name: "天相", offset: 3, element: "水" }, { name: "天梁", offset: 4, element: "土" }, { name: "七杀", offset: 5, element: "金" }, { name: "破军", offset: 11, element: "水" }, ]; tianfuStars.forEach((star) => { const position = (tianfuPosition + star.offset) % 12; this.addStarToPalace(palaces, position, { name: star.name, type: "main", element: star.element, }); }); } /** * 精确计算紫微星位置 */ calculateZiweiPositionEnhanced(lunarDate) { const day = lunarDate.day; const hour = Math.floor(lunarDate.hour / 2); // 紫微星定位公式:根据农历日期和时辰 // 这里使用传统的紫微星定位算法 let position; if (day <= 15) { // 上半月算法 position = (day - 1 + hour) % 12; } else { // 下半月算法 position = (30 - day + hour) % 12; } return position; } /** * 计算太阳星偏移 */ calculateTaiyangOffset(lunarDate) { // 太阳星按月份安星:正月在寅,二月在卯... return (lunarDate.month + 1) % 12; } /** * 计算太阴星偏移 */ calculateTaiyinOffset(lunarDate) { // 太阴星与太阳星相对 const taiyangOffset = this.calculateTaiyangOffset(lunarDate); return (taiyangOffset + 6) % 12; } /** * 精确安辅星 */ placeAuxiliaryStarsEnhanced(palaces, lunarDate) { // 左辅右弼 const zuofuPosition = (lunarDate.month + 1) % 12; // 正月在寅 const youbiPosition = (13 - lunarDate.month) % 12; // 正月在子 this.addStarToPalace(palaces, zuofuPosition, { name: "左辅", type: "auxiliary", category: "吉星", element: "土", }); this.addStarToPalace(palaces, youbiPosition, { name: "右弼", type: "auxiliary", category: "吉星", element: "水", }); // 文昌文曲 const wenchangPosition = this.calculateWenchangPosition(lunarDate); const wenquPosition = this.calculateWenquPosition(lunarDate); this.addStarToPalace(palaces, wenchangPosition, { name: "文昌", type: "auxiliary", category: "文星", element: "金", }); this.addStarToPalace(palaces, wenquPosition, { name: "文曲", type: "auxiliary", category: "文星", element: "水", }); // 天魁天钺 const tiankuiPosition = this.calculateTiankuiPosition(lunarDate); const tianyuePosition = this.calculateTianyuePosition(lunarDate); this.addStarToPalace(palaces, tiankuiPosition, { name: "天魁", type: "auxiliary", category: "贵人星", element: "火", }); this.addStarToPalace(palaces, tianyuePosition, { name: "天钺", type: "auxiliary", category: "贵人星", element: "火", }); } /** * 计算文昌星位置 */ calculateWenchangPosition(lunarDate) { const dayGan = this.getDayGan(lunarDate.dayInGanZhi); const wenchangMap = { 甲: 10, // 戌 乙: 9, // 酉 丙: 8, // 申 丁: 7, // 未 戊: 8, // 申 己: 7, // 未 庚: 6, // 午 辛: 5, // 巳 壬: 4, // 辰 癸: 3, // 卯 }; return wenchangMap[dayGan] || 0; } /** * 计算文曲星位置 */ calculateWenquPosition(lunarDate) { const dayGan = this.getDayGan(lunarDate.dayInGanZhi); const wenquMap = { 甲: 4, // 辰 乙: 5, // 巳 丙: 7, // 未 丁: 6, // 午 戊: 7, // 未 己: 6, // 午 庚: 9, // 酉 辛: 10, // 戌 壬: 11, // 亥 癸: 0, // 子 }; return wenquMap[dayGan] || 0; } /** * 计算天魁星位置 */ calculateTiankuiPosition(lunarDate) { const yearGan = lunarDate.yearInGanZhi[0]; const tiankuiMap = { 甲: 1, // 丑 乙: 0, // 子 丙: 11, // 亥 丁: 10, // 戌 戊: 1, // 丑 己: 0, // 子 庚: 11, // 亥 辛: 10, // 戌 壬: 5, // 午 癸: 4, // 巳 }; return tiankuiMap[yearGan] || 0; } /** * 计算天钺星位置 */ calculateTianyuePosition(lunarDate) { const yearGan = lunarDate.yearInGanZhi[0]; const tianyueMap = { 甲: 7, // 申 乙: 6, // 未 丙: 9, // 酉 丁: 8, // 申 戊: 7, // 申 己: 6, // 未 庚: 9, // 酉 辛: 8, // 申 壬: 2, // 卯 癸: 3, // 辰 }; return tianyueMap[yearGan] || 0; } /** * 精确安煞星 */ placeMaleficStarsEnhanced(palaces, lunarDate) { // 擎羊陀罗 const qingyangPosition = this.calculateQingyangPosition(lunarDate); const tuoluoPosition = (qingyangPosition + 1) % 12; this.addStarToPalace(palaces, qingyangPosition, { name: "擎羊", type: "malefic", category: "煞星", element: "金", }); this.addStarToPalace(palaces, tuoluoPosition, { name: "陀罗", type: "malefic", category: "煞星", element: "金", }); // 火星铃星 const huoxingPosition = this.calculateHuoxingPosition(lunarDate); const lingxingPosition = this.calculateLingxingPosition(lunarDate); this.addStarToPalace(palaces, huoxingPosition, { name: "火星", type: "malefic", category: "煞星", element: "火", }); this.addStarToPalace(palaces, lingxingPosition, { name: "铃星", type: "malefic", category: "煞星", element: "火", }); } /** * 计算四化 */ calculateSihua(yearGan, palaces) { const sihuaMap = { 甲: { 化禄: "廉贞", 化权: "破军", 化科: "武曲", 化忌: "太阳" }, 乙: { 化禄: "天机", 化权: "天梁", 化科: "紫微", 化忌: "太阴" }, 丙: { 化禄: "天同", 化权: "天机", 化科: "文昌", 化忌: "廉贞" }, 丁: { 化禄: "太阴", 化权: "天同", 化科: "天机", 化忌: "巨门" }, 戊: { 化禄: "贪狼", 化权: "太阴", 化科: "右弼", 化忌: "天机" }, 己: { 化禄: "武曲", 化权: "贪狼", 化科: "天梁", 化忌: "文曲" }, 庚: { 化禄: "太阳", 化权: "武曲", 化科: "太阴", 化忌: "天同" }, 辛: { 化禄: "巨门", 化权: "太阳", 化科: "文曲", 化忌: "文昌" }, 壬: { 化禄: "天梁", 化权: "紫微", 化科: "左辅", 化忌: "武曲" }, 癸: { 化禄: "破军", 化权: "巨门", 化科: "太阴", 化忌: "贪狼" }, }; const yearSihua = sihuaMap[yearGan] || {}; const result = {}; // 为每个宫位的星曜添加四化属性 palaces.forEach((palace) => { palace.stars.forEach((star) => { Object.entries(yearSihua).forEach(([sihuaType, starName]) => { if (star.name === starName) { star.sihua = sihuaType; result[sihuaType] = { star: starName, palace: palace.name, position: palace.position, }; } }); }); }); return result; } /** * 识别格局 */ recognizePatterns(palaces, destinyPalace, bodyPalace) { const patterns = []; const destinyStars = destinyPalace.stars.map((s) => s.name); // 检查紫微格局 if (destinyStars.includes("紫微")) { if (destinyStars.includes("天府")) { patterns.push({ name: "紫府同宫", type: "富贵格", description: "帝王之相,主大富大贵,一生显达", strength: "excellent", influence: "very_positive", }); } if (destinyStars.includes("贪狼")) { patterns.push({ name: "紫贪同宫", type: "桃花格", description: "主聪明多才,异性缘佳,适合娱乐行业", strength: "good", influence: "positive", }); } } // 检查杀破狼格局 const shapolangStars = ["七杀", "破军", "贪狼"]; const hasShapolang = shapolangStars.some((star) => destinyStars.includes(star), ); if (hasShapolang) { patterns.push({ name: "杀破狼格局", type: "变动格", description: "主变动,宜外出发展,创业有成,不宜安逸", strength: "good", influence: "dynamic", }); } // 检查机月同梁格局 const jiyuetongliangStars = ["天机", "太阴", "天同", "天梁"]; const hasJiyuetongliang = jiyuetongliangStars.filter((star) => destinyStars.includes(star)) .length >= 2; if (hasJiyuetongliang) { patterns.push({ name: "机月同梁格局", type: "清贵格", description: "主清贵,适合文职、教育、咨询等行业", strength: "good", influence: "stable", }); } return patterns; } /** * 计算星曜亮度 */ calculateBrightnessEnhanced(palaces) { palaces.forEach((palace) => { palace.stars.forEach((star) => { const brightness = this.getStarBrightness( star.name, palace.earthlyBranch, ); star.brightness = brightness; palace.brightness[star.name] = brightness; }); }); } /** * 获取星曜在特定地支的亮度 */ getStarBrightness(starName, earthlyBranch) { const brightnessMap = { 紫微: { 子: "庙", 丑: "旺", 寅: "得", 卯: "利", 辰: "平", 巳: "不", 午: "庙", 未: "旺", 申: "得", 酉: "利", 戌: "平", 亥: "不", }, 天机: { 子: "旺", 丑: "得", 寅: "庙", 卯: "旺", 辰: "得", 巳: "利", 午: "平", 未: "不", 申: "平", 酉: "不", 戌: "平", 亥: "利", }, 太阳: { 子: "陷", 丑: "不", 寅: "旺", 卯: "庙", 辰: "旺", 巳: "庙", 午: "庙", 未: "旺", 申: "得", 酉: "利", 戌: "平", 亥: "陷", }, // ... 其他星曜的亮度数据 }; return brightnessMap[starName]?.[earthlyBranch] || "平"; } /** * 生成增强版摘要 */ generateEnhancedSummary(chart) { const destinyPalace = chart.palaces.find( (p) => p.id === chart.info.destinyPalace, ); const mainStars = destinyPalace.stars.filter((s) => s.type === "main"); const patterns = chart.patterns; const sihua = chart.sihua; return { basicInfo: { name: chart.info.name, gender: chart.info.gender, age: chart.info.age, destinyPalace: destinyPalace.name, destinyStars: mainStars.map((s) => s.name), }, patterns: patterns.map((p) => ({ name: p.name, type: p.type, strength: p.strength, })), sihua: Object.entries(sihua).map(([type, info]) => ({ type: type, star: info.star, palace: info.palace, })), overallAssessment: this.generateOverallAssessment(chart), }; } /** * 生成整体评估 */ generateOverallAssessment(chart) { const patterns = chart.patterns; const excellentPatterns = patterns.filter( (p) => p.strength === "excellent", ).length; const goodPatterns = patterns.filter((p) => p.strength === "good").length; let level = "普通"; let description = "命盘格局一般,需要后天努力"; if (excellentPatterns > 0) { level = "优秀"; description = "命盘格局优秀,天赋异禀,前程似锦"; } else if (goodPatterns >= 2) { level = "良好"; description = "命盘格局良好,具有发展潜力"; } else if (goodPatterns === 1) { level = "中等"; description = "命盘格局中等,有一定优势"; } return { level: level, description: description, score: this.calculateOverallScore(chart), }; } /** * 计算整体评分 */ calculateOverallScore(chart) { let score = 60; // 基础分 // 格局加分 chart.patterns.forEach((pattern) => { switch (pattern.strength) { case "excellent": score += 20; break; case "good": score += 10; break; case "average": score += 5; break; } }); // 四化加分 if (chart.sihua["化禄"]) score += 5; if (chart.sihua["化权"]) score += 5; if (chart.sihua["化科"]) score += 5; // 四化减分 if (chart.sihua["化忌"]) score -= 3; return Math.min(100, Math.max(0, score)); } // 辅助方法 getDayGan(dayInGanZhi) { return dayInGanZhi ? dayInGanZhi[0] : "甲"; } getElementByPosition(position) { const elementMap = { 0: "水", 1: "土", 2: "木", 3: "木", 4: "土", 5: "火", 6: "火", 7: "土", 8: "金", 9: "金", 10: "土", 11: "水", }; return elementMap[position] || "土"; } addStarToPalace(palaces, position, star) { const palace = palaces.find((p) => p.position === position); if (palace) { palace.stars.push(star); } } // 数据库加载方法(简化版) loadStarsDatabase() { // 这里应该从外部文件或数据库加载 return {}; } loadPalacesDatabase() { // 这里应该从外部文件或数据库加载 return {}; } // 继承原有方法 validateInput(input) { if (!input.birthDate) { throw new Error("出生日期不能为空"); } if (!input.birthTime) { throw new Error("出生时间不能为空"); } if (!input.gender || !["male", "female"].includes(input.gender)) { throw new Error("性别必须是 male 或 female"); } } parseBirthInfo(input) { const [year, month, day] = input.birthDate.split("-").map(Number); const [hour, minute] = input.birthTime.split(":").map(Number); return { year: year, month: month, day: day, hour: hour, minute: minute || 0, }; } formatLunarDate(lunarDate) { return `${lunarDate.year}年${lunarDate.isLeapMonth ? "闰" : ""}${lunarDate.month}月${lunarDate.day}日`; } findDestinyPalace(palaces) { return palaces.find((p) => p.isDestinyPalace) || palaces[0]; } findBodyPalace(palaces, lunarDate) { // 身宫计算:命宫 + 生月 - 生时 const destinyPalace = this.findDestinyPalace(palaces); const birthMonth = lunarDate.month; const birthHour = Math.floor(lunarDate.hour / 2); let bodyPosition = destinyPalace.position + birthMonth - birthHour; while (bodyPosition < 0) bodyPosition += 12; bodyPosition = bodyPosition % 12; const bodyPalace = palaces.find((p) => p.position === bodyPosition); if (bodyPalace) { bodyPalace.isBodyPalace = true; } return bodyPalace || palaces[1]; } getChart(chartId) { return this.charts.get(chartId); } // 继承原有的简化计算方法作为备用 calculateQingyangPosition(lunarDate) { const yearZhi = lunarDate.yearInGanZhi[1]; const zhiIndex = DIZHI.indexOf(yearZhi); return (zhiIndex + 1) % 12; } calculateHuoxingPosition(lunarDate) { const yearZhi = lunarDate.yearInGanZhi[1]; const zhiIndex = DIZHI.indexOf(yearZhi); return (zhiIndex + 2) % 12; } calculateLingxingPosition(lunarDate) { const yearZhi = lunarDate.yearInGanZhi[1]; const zhiIndex = DIZHI.indexOf(yearZhi); return (zhiIndex + 3) % 12; } } module.exports = { EnhancedChartGenerator, };