Files
meihua-yishu/calculator/dist/analysis.js
T
小钰 4ff76822ad feat: 梅花易数 + 梅花心易 算法层 v1.0
- 八卦基础数据(先天数/五行/方位/生克关系)
- 六十四卦完整数据(卦名/卦辞/象辞/吉凶/关键词)
- 体用分析引擎(动爻→体用→五行生克→旺衰判定)
- 变卦/互卦计算
- 三种起卦方式:数字法、时间法、外应法(梅花心易)
- CLI入口:JSON/文本双格式输出
- 断卦分析 prompt + 梅花心易 prompt + 海报版 prompt
- HTML海报模板(古风暗色系)
2026-08-03 07:12:25 +08:00

118 lines
5.0 KiB
JavaScript

import { getTrigramByNumber, getRelation, WUXING_SHENG, WUXING_KE } from './trigrams.js';
import { getHexagram, getChangedHexagram, getMutualHexagram } from './hexagrams.js';
// 获取当前节气(用于判断旺衰)
function getCurrentJieqi() {
const now = new Date();
const month = now.getMonth() + 1;
// 简化版:按月份判断大致季节
if (month >= 3 && month <= 4)
return '春(寅卯月)';
if (month >= 5 && month <= 6)
return '夏(巳午月)';
if (month >= 7 && month <= 8)
return '夏末(未申月)';
if (month >= 9 && month <= 10)
return '秋(酉戌月)';
if (month >= 11 || month <= 1)
return '冬(亥子月)';
return '冬末(丑寅月)';
}
// 判断五行在当季旺衰
function isElementWang(element, season) {
if (season.includes('春') && element === '木')
return true;
if (season.includes('夏') && element === '火')
return true;
if (season.includes('秋') && element === '金')
return true;
if (season.includes('冬') && element === '水')
return true;
if (season.includes('末') && element === '土')
return true;
return false;
}
// 核心排盘
export function calculateHua(input) {
let upperNum, lowerNum, dongYao;
if (input.method === 'number' && input.numbers) {
// 数字起卦
const nums = input.numbers;
upperNum = nums[0] % 8 || 8;
lowerNum = nums[1] % 8 || 8;
dongYao = nums.length >= 3 ? (nums[0] + nums[1] + nums[2]) % 6 || 6 : (nums[0] + nums[1]) % 6 || 6;
}
else if (input.method === 'time') {
// 时间起卦:年月日时
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth() + 1;
const day = now.getDate();
const hour = now.getHours();
const minute = now.getMinutes();
upperNum = (year + month + day) % 8 || 8;
lowerNum = (year + month + day + hour) % 8 || 8;
dongYao = (year + month + day + hour + minute) % 6 || 6;
}
else if (input.method === 'observation' && input.observedTrigrams) {
// 梅花心易:从外应推导
const nums = input.observedTrigrams;
upperNum = nums[0] % 8 || 8;
lowerNum = nums[1] % 8 || 8;
dongYao = nums.length >= 3 ? nums[2] % 6 || 6 : (nums[0] + nums[1]) % 6 || 6;
}
else {
throw new Error('无效的起卦参数');
}
const upperTrigram = getTrigramByNumber(upperNum);
const lowerTrigram = getTrigramByNumber(lowerNum);
const mainHex = getHexagram(upperNum, lowerNum);
// 体用判断:动爻在下卦(1-3)则下卦为用、上卦为体;动爻在上卦(4-6)则上卦为用、下卦为体
const tiPosition = dongYao <= 3 ? 'upper' : 'lower';
const yongPosition = dongYao <= 3 ? 'lower' : 'upper';
const tiTrigram = tiPosition === 'upper' ? upperTrigram : lowerTrigram;
const yongTrigram = yongPosition === 'upper' ? upperTrigram : lowerTrigram;
// 变卦
const changedHex = getChangedHexagram(upperNum, lowerNum, dongYao);
// 互卦
const mutualHex = getMutualHexagram(upperNum, lowerNum);
// 五行分析
const relation = getRelation(tiTrigram.element, yongTrigram.element);
let verdict = '';
if (WUXING_SHENG[yongTrigram.element] === tiTrigram.element) {
verdict = '用生体:外来助力,事易成,有人帮助。';
}
else if (WUXING_SHENG[tiTrigram.element] === yongTrigram.element) {
verdict = '体生用:我泄气于外,耗损之象,需付出较多。';
}
else if (WUXING_KE[yongTrigram.element] === tiTrigram.element) {
verdict = '用克体:外来压力大,受制于人,事难成。';
}
else if (WUXING_KE[tiTrigram.element] === yongTrigram.element) {
verdict = '体克用:我能制外,事可成但需努力。';
}
else {
verdict = '体用比和:势均力敌,事可成,和合之象。';
}
// 旺衰
const season = getCurrentJieqi();
const tiWang = isElementWang(tiTrigram.element, season);
const yongWang = isElementWang(yongTrigram.element, season);
const wangAnalysis = `当令${season}。体卦${tiTrigram.element}${tiWang ? '旺' : '衰'},用卦${yongTrigram.element}${yongWang ? '旺' : '衰'}。`;
return {
mainHexagram: { upper: upperTrigram, lower: lowerTrigram, hexagram: mainHex },
tiGua: { trigram: tiTrigram, position: tiPosition },
yongGua: { trigram: yongTrigram, position: yongPosition },
dongYao,
changedHexagram: changedHex,
mutualHexagram: mutualHex,
wuxingAnalysis: { tiElement: tiTrigram.element, yongElement: yongTrigram.element, relation, verdict },
wangShuai: { season, tiWang, yongWang, analysis: wangAnalysis },
meta: {
method: input.method,
inputNumbers: input.numbers || [],
question: input.question,
timestamp: new Date().toISOString(),
},
};
}