Spaces:
Running
Running
Download reading_methodology.py from sisithefox/astrology-ziwei-api: direct link, hf CLI and curl.
- Browser
- Download file 49.9 kB
-
https://huggingface.co/spaces/sisithefox/astrology-ziwei-api/resolve/main/reading_methodology.py
- Command line
-
hf download hf://spaces/sisithefox/astrology-ziwei-api/reading_methodology.py
-
curl -L -o reading_methodology.py https://huggingface.co/spaces/sisithefox/astrology-ziwei-api/resolve/main/reading_methodology.py
49.9 kB
"""
批命流程引擎 - Reading Methodology Engine
实现10步标准批命流程和36条核心口诀应用
Version: 1.0
Created: 2026-02-03
Author: Sisi & TH Studio
核心功能:
1. 10步标准批命流程执行
2. 36条核心口诀自动匹配
3. 吉格凶格自动识别
4. 死限判断公式应用
5. 综合批命报告生成
"""
from typing import Dict, List, Any, Optional, Tuple
from methodology_loader import MethodologyLoader, get_methodology_loader
from barnum_cold_reader import BarnumColdReader, BarnumTone, get_barnum_reader
class ReadingMethodologyEngine:
"""
批命流程引擎
执行10步标准批命流程,应用36条核心口诀
"""
def __init__(self):
"""初始化批命引擎"""
self.methodology = get_methodology_loader()
self.barnum = get_barnum_reader()
# 主星列表
self.main_stars = [
'紫微', '天机', '太阳', '武曲', '天同', '廉贞', '天府',
'太阴', '贪狼', '巨门', '天相', '天梁', '七杀', '破军'
]
# 六吉星
self.lucky_stars = ['左辅', '右弼', '文昌', '文曲', '天魁', '天钺']
# 六煞星
self.evil_stars = ['擎羊', '陀罗', '火星', '铃星', '天空', '地劫']
# 四化对照表(按年干)
self.sihua_by_tiangan = {
'甲': {'禄': '廉贞', '权': '破军', '科': '武曲', '忌': '太阳'},
'乙': {'禄': '太阴', '权': '天机', '科': '天同', '忌': '巨门'},
'丙': {'禄': '天同', '权': '天机', '科': '文昌', '忌': '廉贞'},
'丁': {'禄': '太阴', '权': '天同', '科': '天机', '忌': '巨门'},
'戊': {'禄': '贪狼', '权': '太阴', '科': '右弼', '忌': '天机'},
'己': {'禄': '武曲', '权': '贪狼', '科': '天梁', '忌': '文曲'},
'庚': {'禄': '太阳', '权': '武曲', '科': '太阴', '忌': '天同'},
'辛': {'禄': '巨门', '权': '太阳', '科': '文曲', '忌': '文昌'},
'壬': {'禄': '天梁', '权': '紫微', '科': '左辅', '忌': '武曲'},
'癸': {'禄': '破军', '权': '巨门', '科': '太阴', '忌': '贪狼'}
}
# 命局数对应
self.mingshu_map = {
'水': 2, '木': 3, '金': 4, '土': 5, '火': 6
}
# 吉格规则
self.ji_ge_rules = self._init_ji_ge_rules()
# 凶格规则
self.xiong_ge_rules = self._init_xiong_ge_rules()
def _init_ji_ge_rules(self) -> List[Dict]:
"""初始化吉格规则"""
return [
{
'name': '紫府夹权',
'condition': lambda palaces: self._check_zifu_jia_quan(palaces),
'meaning': '紫微天府在命宫左右侧,主有权势',
'category': 'power'
},
{
'name': '日月夹命',
'condition': lambda palaces: self._check_riyue_jia_ming(palaces),
'meaning': '太阳太阴庙旺在命宫两侧,一世财禄无缺',
'category': 'wealth'
},
{
'name': '魁钺夹贵',
'condition': lambda palaces: self._check_kuiyue_jia_gui(palaces),
'meaning': '天魁天钺在命宫两侧,贵人扶持',
'category': 'noble'
},
{
'name': '日月并明',
'condition': lambda palaces: self._check_riyue_bing_ming(palaces),
'meaning': '太阳旺辰+太阴旺戌,一世荣华',
'category': 'prosperity'
},
{
'name': '明珠出海',
'condition': lambda palaces: self._check_mingzhu_chuhai(palaces),
'meaning': '命宫在未,太阴亥宫+太阳卯宫入庙,父母双全',
'category': 'family'
},
{
'name': '火贪相聚',
'condition': lambda palaces: self._check_huo_tan_xiangjv(palaces),
'meaning': '贪狼+火星/铃星同宫,武贵格',
'category': 'military'
},
{
'name': '禄马交驰',
'condition': lambda palaces: self._check_luma_jiaochi(palaces),
'meaning': '禄存/化禄+天马同宫,辛苦赚大钱',
'category': 'wealth'
},
{
'name': '府相会命',
'condition': lambda palaces: self._check_fuxiang_huiming(palaces),
'meaning': '天府天相分别位于财帛事业宫,天生辅佐人才',
'category': 'career'
},
{
'name': '日照雷门',
'condition': lambda palaces: self._check_rizhao_leimen(palaces),
'meaning': '命宫在卯,太阳入命庙,男命最吉',
'category': 'prosperity'
},
{
'name': '月朗天门',
'condition': lambda palaces: self._check_yuelang_tianmen(palaces),
'meaning': '命宫在亥,太阴入命庙,女命最吉',
'category': 'prosperity'
}
]
def _init_xiong_ge_rules(self) -> List[Dict]:
"""初始化凶格规则"""
return [
{
'name': '半空折翅',
'condition': lambda palaces: self._check_bankong_zheshi(palaces),
'meaning': '命宫在巳或亥,廉贪落陷对冲,中年横夭',
'severity': 'critical',
'category': 'life_threat'
},
{
'name': '日月反背',
'condition': lambda palaces: self._check_riyue_fanbei(palaces),
'meaning': '太阳太阴均落陷,离乡发展,克父母',
'severity': 'high',
'category': 'family'
},
{
'name': '羊陀夹杀',
'condition': lambda palaces: self._check_yangtuo_jiasha(palaces),
'meaning': '擎羊陀罗在命宫两侧,犯小人',
'severity': 'medium',
'category': 'social'
},
{
'name': '吉处藏凶',
'condition': lambda palaces: self._check_jichu_cangxiong(palaces),
'meaning': '吉星丛中煞星落陷,必凶',
'severity': 'high',
'category': 'hidden_danger'
},
{
'name': '廉贞七杀',
'condition': lambda palaces: self._check_lianzhen_qisha(palaces),
'meaning': '落陷主半路埋尸',
'severity': 'critical',
'category': 'life_threat'
},
{
'name': '廉贞破军',
'condition': lambda palaces: self._check_lianzhen_pojun(palaces),
'meaning': '落陷主水中做冢',
'severity': 'critical',
'category': 'life_threat'
},
{
'name': '目不见日月',
'condition': lambda palaces: self._check_mu_bujian_riyue(palaces),
'meaning': '太阳太阴均落陷,主死',
'severity': 'critical',
'category': 'life_threat'
}
]
def execute_ten_step_reading(self, chart_data: Dict) -> Dict[str, Any]:
"""
执行完整的10步批命流程
Args:
chart_data: 命盘数据
Returns:
dict: 完整批命结果
"""
result = {
'version': '4.0',
'methodology': 'ten_step_reading',
'steps': [],
'summary': {},
'warnings': [],
'formulas_matched': []
}
# 准备宫位数据
palaces = chart_data.get('palaces', {})
birth_info = chart_data.get('birth_info', {})
# 执行10步批命
result['steps'].append(self._step1_basic_info(chart_data, birth_info))
result['steps'].append(self._step2_overall_pattern(palaces, chart_data))
result['steps'].append(self._step3_shen_gong(palaces, chart_data))
result['steps'].append(self._step4_six_relations(palaces, chart_data))
result['steps'].append(self._step5_career_wealth(palaces, chart_data))
result['steps'].append(self._step6_health(palaces, chart_data))
result['steps'].append(self._step7_timing(palaces, chart_data))
result['steps'].append(self._step8_marriage_timing(palaces, chart_data))
result['steps'].append(self._step9_property(palaces, chart_data))
result['steps'].append(self._step10_fude(palaces, chart_data))
# 汇总所有匹配的口诀
for step in result['steps']:
if 'formulas_matched' in step:
result['formulas_matched'].extend(step['formulas_matched'])
# 生成综合评估
result['summary'] = self._generate_summary(result)
# v4.1: 为dict类型的summary添加barnum增强
result['barnum_enhanced_summary'] = self._enhance_summary_with_barnum(result['summary'])
return result
def _step1_basic_info(self, chart_data: Dict, birth_info: Dict) -> Dict:
"""第一步:确认盘面基础信息"""
step_result = {
'step': 1,
'name': '确认盘面基础信息',
'analysis': {}
}
# 1.1 命局数
wuxing = chart_data.get('wuxing', '')
if wuxing and wuxing in self.mingshu_map:
mingshu = self.mingshu_map[wuxing]
step_result['analysis']['mingshu'] = {
'value': mingshu,
'meaning': f'{wuxing}{mingshu}局,{mingshu}岁起运'
}
# 1.2 命宫位置
ming_palace = chart_data.get('ming_palace', {})
step_result['analysis']['ming_palace'] = {
'position': ming_palace.get('position', ''),
'main_stars': ming_palace.get('main_stars', [])
}
# 1.3 身宫位置
shen_palace = chart_data.get('shen_palace', {})
step_result['analysis']['shen_palace'] = {
'position': shen_palace.get('position', ''),
'palace_name': shen_palace.get('palace_name', ''),
'meaning': self._get_shen_palace_meaning(shen_palace.get('palace_name', ''))
}
# 1.4 四化位置
sihua = chart_data.get('sihua', {})
step_result['analysis']['sihua'] = sihua
return step_result
def _step2_overall_pattern(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第二步:看总格成败"""
step_result = {
'step': 2,
'name': '看总格成败',
'analysis': {
'sanfang_sizheng': {},
'ji_ge': [],
'xiong_ge': []
},
'formulas_matched': []
}
# 2.1 观察命宫三方四正
ming_palace = chart_data.get('ming_palace', {})
step_result['analysis']['sanfang_sizheng'] = self._analyze_sanfang_sizheng(
palaces, ming_palace
)
# 2.2 识别吉格
for rule in self.ji_ge_rules:
try:
if rule['condition'](palaces):
ji_ge = {
'name': rule['name'],
'meaning': rule['meaning'],
'category': rule['category']
}
step_result['analysis']['ji_ge'].append(ji_ge)
step_result['formulas_matched'].append({
'type': 'ji_ge',
'name': rule['name'],
'meaning': rule['meaning']
})
except Exception:
pass
# 2.3 识别凶格
for rule in self.xiong_ge_rules:
try:
if rule['condition'](palaces):
xiong_ge = {
'name': rule['name'],
'meaning': rule['meaning'],
'severity': rule['severity'],
'category': rule['category']
}
step_result['analysis']['xiong_ge'].append(xiong_ge)
step_result['formulas_matched'].append({
'type': 'xiong_ge',
'name': rule['name'],
'meaning': rule['meaning'],
'severity': rule['severity']
})
# 严重凶格加入警告
if rule['severity'] == 'critical':
step_result['critical_warning'] = rule['meaning']
except Exception:
pass
# 2.4 总格评价
ji_count = len(step_result['analysis']['ji_ge'])
xiong_count = len(step_result['analysis']['xiong_ge'])
critical_count = sum(
1 for x in step_result['analysis']['xiong_ge']
if x.get('severity') == 'critical'
)
if critical_count > 0:
step_result['analysis']['overall_rating'] = 'critical_warning'
step_result['analysis']['overall_comment'] = '命盘有严重凶格,需特别关注'
elif ji_count > xiong_count:
step_result['analysis']['overall_rating'] = 'positive'
step_result['analysis']['overall_comment'] = '吉格多于凶格,总体偏吉'
elif xiong_count > ji_count:
step_result['analysis']['overall_rating'] = 'challenging'
step_result['analysis']['overall_comment'] = '凶格多于吉格,人生较有波折'
else:
step_result['analysis']['overall_rating'] = 'neutral'
step_result['analysis']['overall_comment'] = '吉凶参半,中平之命'
return step_result
def _step3_shen_gong(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第三步:看身宫定后天发展"""
step_result = {
'step': 3,
'name': '看身宫定后天发展',
'analysis': {}
}
shen_palace = chart_data.get('shen_palace', {})
palace_name = shen_palace.get('palace_name', '')
# 身宫落宫判断
shen_meanings = {
'财帛宫': '后天发展方向在财富,适合私企或自己做老板',
'官禄宫': '后天发展方向在事业,适合从政或做官',
'迁移宫': '后天发展方向在外地,离乡发展更有利',
'夫妻宫': '后天被婚姻影响很大,配偶对人生有重大影响',
'命宫': '身命同宫,先天后天一致,性格坚定'
}
step_result['analysis']['shen_position'] = palace_name
step_result['analysis']['meaning'] = shen_meanings.get(
palace_name,
f'身宫在{palace_name},后天发展受该宫位影响'
)
# 检查七杀临身
shen_stars = shen_palace.get('main_stars', [])
if '七杀' in str(shen_stars):
step_result['analysis']['warning'] = '七杀临身终不美,一辈子多败少成'
step_result['formulas_matched'] = [{
'type': 'xiong_ge',
'name': '七杀临身',
'meaning': '一辈子多败少成'
}]
return step_result
def _step4_six_relations(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第四步:批六亲关系"""
step_result = {
'step': 4,
'name': '批六亲关系',
'analysis': {
'parents': {},
'siblings': {},
'spouse': {},
'children': {}
},
'formulas_matched': []
}
# 获取相关宫位
parents_palace = palaces.get('父母宫', {})
siblings_palace = palaces.get('兄弟宫', {})
spouse_palace = palaces.get('夫妻宫', {})
children_palace = palaces.get('子女宫', {})
fude_palace = palaces.get('福德宫', {})
# 4.1 父母宫分析
step_result['analysis']['parents'] = self._analyze_parents_palace(
parents_palace, palaces, chart_data
)
# 4.2 兄弟宫分析
step_result['analysis']['siblings'] = self._analyze_siblings_palace(
siblings_palace, chart_data
)
# 4.3 夫妻宫分析(必须与福德宫同参!)
step_result['analysis']['spouse'] = self._analyze_spouse_palace(
spouse_palace, fude_palace, chart_data
)
# 4.4 子女宫分析
step_result['analysis']['children'] = self._analyze_children_palace(
children_palace, chart_data
)
return step_result
def _step5_career_wealth(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第五步:看事业财运方向"""
step_result = {
'step': 5,
'name': '看事业财运方向',
'analysis': {
'career': {},
'wealth': {},
'migration': {}
},
'formulas_matched': []
}
guanlu_palace = palaces.get('官禄宫', {})
caibo_palace = palaces.get('财帛宫', {})
qianyi_palace = palaces.get('迁移宫', {})
# 5.1 官禄宫分析
step_result['analysis']['career'] = self._analyze_career_palace(
guanlu_palace, chart_data
)
# 5.2 财帛宫分析
step_result['analysis']['wealth'] = self._analyze_wealth_palace(
caibo_palace, chart_data
)
# 5.3 迁移宫分析
step_result['analysis']['migration'] = self._analyze_migration_palace(
qianyi_palace, chart_data
)
return step_result
def _step6_health(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第六步:看疾厄宫"""
step_result = {
'step': 6,
'name': '看疾厄宫',
'analysis': {}
}
jie_palace = palaces.get('疾厄宫', {})
# 中医经脉对应
meridian_map = {
'寅': '肺经', '卯': '大肠经', '辰': '胃经', '巳': '脾经',
'午': '心经', '未': '小肠经', '申': '膀胱经', '酉': '肾经',
'戌': '心包经', '亥': '三焦经', '子': '胆经', '丑': '肝经'
}
position = jie_palace.get('position', '')
step_result['analysis']['meridian'] = meridian_map.get(position, '')
# 分析疾厄宫星性
stars = jie_palace.get('stars', [])
health_concerns = []
for star in stars:
star_name = star if isinstance(star, str) else star.get('name', '')
if star_name in self.evil_stars:
health_concerns.append(f'{star_name}在疾厄宫,需注意相关健康问题')
step_result['analysis']['health_concerns'] = health_concerns
# 化忌检查
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '疾厄宫':
step_result['analysis']['huaji_warning'] = '化忌入疾厄宫,该脏腑需特别注意'
return step_result
def _step7_timing(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第七步:批流年大运"""
step_result = {
'step': 7,
'name': '批流年大运',
'analysis': {
'daxun': {},
'timing_rules': []
},
'formulas_matched': []
}
# 获取大运信息
daxun = chart_data.get('daxun', [])
if daxun:
step_result['analysis']['daxun'] = self._analyze_daxun(daxun, chart_data)
# 应用时间预测规则
timing_rules = self.methodology.timing_rules
for rule_category, rules in timing_rules.items():
for rule in rules:
step_result['analysis']['timing_rules'].append({
'category': rule_category,
'rule': rule['rule'],
'meaning': rule['meaning']
})
# 检查特殊年份规律
birth_year = chart_data.get('birth_info', {}).get('year', 0)
tiangan = chart_data.get('tiangan', '')
special_pattern = self.methodology.get_special_year_pattern(tiangan)
if special_pattern:
step_result['analysis']['special_year_pattern'] = special_pattern
return step_result
def _step8_marriage_timing(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第八步:看婚姻成败时机"""
step_result = {
'step': 8,
'name': '看婚姻成败时机',
'analysis': {}
}
# 获取婚姻时机规则
marriage_rules = self.methodology.get_marriage_timing_rules()
step_result['analysis']['timing_rules'] = marriage_rules
# 检查红鸾天喜位置
spouse_palace = palaces.get('夫妻宫', {})
ming_palace = chart_data.get('ming_palace', {})
# 检查夫妻宫星性
spouse_stars = spouse_palace.get('stars', [])
marriage_outlook = []
for star in spouse_stars:
star_name = star if isinstance(star, str) else star.get('name', '')
if star_name == '红鸾' or star_name == '天喜':
marriage_outlook.append(f'{star_name}在夫妻宫,婚姻吉祥')
step_result['analysis']['marriage_outlook'] = marriage_outlook
# 检查化忌
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '夫妻宫':
step_result['analysis']['warning'] = '化忌入夫妻宫,夫妻八字不合,注意感情波折'
return step_result
def _step9_property(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第九步:看田宅宫"""
step_result = {
'step': 9,
'name': '看田宅宫',
'analysis': {}
}
tianzhai_palace = palaces.get('田宅宫', {})
# 分析田宅宫
stars = tianzhai_palace.get('stars', [])
property_outlook = []
for star in stars:
star_name = star if isinstance(star, str) else star.get('name', '')
if star_name == '火星':
property_outlook.append('火星在田宅宫,注意火灾风险')
elif star_name in ['擎羊', '陀罗']:
property_outlook.append(f'{star_name}在田宅宫,可能有房产纠纷')
step_result['analysis']['property_outlook'] = property_outlook
# 化忌检查
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '田宅宫':
step_result['analysis']['warning'] = '化忌入田宅宫,可能破祖业或耗尽父母财产'
return step_result
def _step10_fude(self, palaces: Dict, chart_data: Dict) -> Dict:
"""第十步:福德宫判断"""
step_result = {
'step': 10,
'name': '福德宫判断',
'analysis': {},
'formulas_matched': []
}
fude_palace = palaces.get('福德宫', {})
gender = chart_data.get('gender', '')
# 福德宫核心意义
step_result['analysis']['core_meaning'] = '主一辈子的福禄、财禄、事业'
if gender == '女':
step_result['analysis']['gender_note'] = '女命福德宫最重要,也代表夫妻宫'
# 分析福德宫星性
stars = fude_palace.get('stars', [])
fude_analysis = []
for star in stars:
star_name = star if isinstance(star, str) else star.get('name', '')
if star_name == '破军':
fude_analysis.append('破军在福德宫,婚姻需特别注意')
elif star_name == '红鸾' or star_name == '天喜':
fude_analysis.append(f'{star_name}在福德宫,主多婚')
elif star_name in ['武曲', '七杀']:
if gender == '男':
fude_analysis.append('武曲七杀在福德宫,个性刚强,不靠祖业')
else:
fude_analysis.append('武曲七杀在福德宫,女命需注意孤独问题')
step_result['analysis']['fude_analysis'] = fude_analysis
# 🔥 核心秘诀:福德宫化忌 → 夫妻死别
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '福德宫':
step_result['critical_warning'] = {
'type': 'spouse_death_separation',
'message': '福德宫化忌,夫妻缘分需特别关注',
'severity': 'critical',
'formula': '福德宫化忌→夫妻必死别'
}
step_result['formulas_matched'].append({
'type': 'critical_rule',
'name': '福德宫化忌',
'meaning': '夫妻缘分需特别关注(核心秘诀)'
})
return step_result
# ============== 格局判断辅助方法 ==============
def _check_zifu_jia_quan(self, palaces: Dict) -> bool:
"""检查紫府夹权格"""
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
# 获取命宫左右宫位
adjacent = self._get_adjacent_palaces(ming_position)
left_palace = palaces.get(adjacent['left'], {})
right_palace = palaces.get(adjacent['right'], {})
left_stars = str(left_palace.get('stars', []))
right_stars = str(right_palace.get('stars', []))
has_ziwei = '紫微' in left_stars or '紫微' in right_stars
has_tianfu = '天府' in left_stars or '天府' in right_stars
return has_ziwei and has_tianfu
def _check_riyue_jia_ming(self, palaces: Dict) -> bool:
"""检查日月夹命格"""
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
adjacent = self._get_adjacent_palaces(ming_position)
left_palace = palaces.get(adjacent['left'], {})
right_palace = palaces.get(adjacent['right'], {})
left_stars = str(left_palace.get('stars', []))
right_stars = str(right_palace.get('stars', []))
has_sun = '太阳' in left_stars or '太阳' in right_stars
has_moon = '太阴' in left_stars or '太阴' in right_stars
return has_sun and has_moon
def _check_kuiyue_jia_gui(self, palaces: Dict) -> bool:
"""检查魁钺夹贵格"""
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
adjacent = self._get_adjacent_palaces(ming_position)
left_palace = palaces.get(adjacent['left'], {})
right_palace = palaces.get(adjacent['right'], {})
left_stars = str(left_palace.get('stars', []))
right_stars = str(right_palace.get('stars', []))
has_tiankui = '天魁' in left_stars or '天魁' in right_stars
has_tianyue = '天钺' in left_stars or '天钺' in right_stars
return has_tiankui and has_tianyue
def _check_riyue_bing_ming(self, palaces: Dict) -> bool:
"""检查日月并明格"""
# 太阳旺辰宫+太阴旺戌宫,命宫在辰或戌
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
return ming_position in ['辰', '戌']
def _check_mingzhu_chuhai(self, palaces: Dict) -> bool:
"""检查明珠出海格"""
ming_palace = palaces.get('命宫', {})
return ming_palace.get('position', '') == '未'
def _check_huo_tan_xiangjv(self, palaces: Dict) -> bool:
"""检查火贪相聚格"""
ming_palace = palaces.get('命宫', {})
stars = str(ming_palace.get('stars', []))
has_tanlang = '贪狼' in stars
has_huoxing = '火星' in stars or '铃星' in stars
return has_tanlang and has_huoxing
def _check_luma_jiaochi(self, palaces: Dict) -> bool:
"""检查禄马交驰格"""
for palace_name, palace_data in palaces.items():
stars = str(palace_data.get('stars', []))
has_lucun = '禄存' in stars
has_tianma = '天马' in stars
if has_lucun and has_tianma:
return True
return False
def _check_fuxiang_huiming(self, palaces: Dict) -> bool:
"""检查府相会命格"""
caibo_stars = str(palaces.get('财帛宫', {}).get('stars', []))
guanlu_stars = str(palaces.get('官禄宫', {}).get('stars', []))
has_tianfu = '天府' in caibo_stars or '天府' in guanlu_stars
has_tianxiang = '天相' in caibo_stars or '天相' in guanlu_stars
return has_tianfu and has_tianxiang
def _check_rizhao_leimen(self, palaces: Dict) -> bool:
"""检查日照雷门格"""
ming_palace = palaces.get('命宫', {})
if ming_palace.get('position', '') != '卯':
return False
stars = str(ming_palace.get('stars', []))
return '太阳' in stars
def _check_yuelang_tianmen(self, palaces: Dict) -> bool:
"""检查月朗天门格"""
ming_palace = palaces.get('命宫', {})
if ming_palace.get('position', '') != '亥':
return False
stars = str(ming_palace.get('stars', []))
return '太阴' in stars
def _check_bankong_zheshi(self, palaces: Dict) -> bool:
"""检查半空折翅格"""
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
if ming_position not in ['巳', '亥']:
return False
# 检查廉贪落陷对冲
qianyi_stars = str(palaces.get('迁移宫', {}).get('stars', []))
has_lianzhen = '廉贞' in qianyi_stars
has_tanlang = '贪狼' in qianyi_stars
return has_lianzhen or has_tanlang
def _check_riyue_fanbei(self, palaces: Dict) -> bool:
"""检查日月反背格"""
# 白天月亮、夜间太阳(均落陷)
# 简化判断:太阳太阴都在落陷位置
for palace_data in palaces.values():
stars = palace_data.get('stars', [])
for star in stars:
if isinstance(star, dict):
if star.get('name') == '太阳' and star.get('brightness') == '陷':
for s2 in stars:
if isinstance(s2, dict):
if s2.get('name') == '太阴' and s2.get('brightness') == '陷':
return True
return False
def _check_yangtuo_jiasha(self, palaces: Dict) -> bool:
"""检查羊陀夹杀格"""
ming_palace = palaces.get('命宫', {})
ming_position = ming_palace.get('position', '')
adjacent = self._get_adjacent_palaces(ming_position)
left_palace = palaces.get(adjacent['left'], {})
right_palace = palaces.get(adjacent['right'], {})
left_stars = str(left_palace.get('stars', []))
right_stars = str(right_palace.get('stars', []))
has_qingyang = '擎羊' in left_stars or '擎羊' in right_stars
has_tuoluo = '陀罗' in left_stars or '陀罗' in right_stars
return has_qingyang and has_tuoluo
def _check_jichu_cangxiong(self, palaces: Dict) -> bool:
"""检查吉处藏凶格"""
ming_palace = palaces.get('命宫', {})
stars = ming_palace.get('stars', [])
lucky_count = 0
evil_陷_count = 0
for star in stars:
star_name = star if isinstance(star, str) else star.get('name', '')
brightness = star.get('brightness', '') if isinstance(star, dict) else ''
if star_name in self.lucky_stars:
lucky_count += 1
if star_name in self.evil_stars and brightness == '陷':
evil_陷_count += 1
return lucky_count >= 2 and evil_陷_count >= 1
def _check_lianzhen_qisha(self, palaces: Dict) -> bool:
"""检查廉贞七杀格"""
ming_palace = palaces.get('命宫', {})
stars = ming_palace.get('stars', [])
for star in stars:
if isinstance(star, dict):
if star.get('name') in ['廉贞', '七杀'] and star.get('brightness') == '陷':
return True
return False
def _check_lianzhen_pojun(self, palaces: Dict) -> bool:
"""检查廉贞破军格"""
ming_palace = palaces.get('命宫', {})
stars = ming_palace.get('stars', [])
has_lianzhen_xian = False
has_pojun_xian = False
for star in stars:
if isinstance(star, dict):
if star.get('name') == '廉贞' and star.get('brightness') == '陷':
has_lianzhen_xian = True
if star.get('name') == '破军' and star.get('brightness') == '陷':
has_pojun_xian = True
return has_lianzhen_xian and has_pojun_xian
def _check_mu_bujian_riyue(self, palaces: Dict) -> bool:
"""检查目不见日月格"""
sun_xian = False
moon_xian = False
for palace_data in palaces.values():
stars = palace_data.get('stars', [])
for star in stars:
if isinstance(star, dict):
if star.get('name') == '太阳' and star.get('brightness') == '陷':
sun_xian = True
if star.get('name') == '太阴' and star.get('brightness') == '陷':
moon_xian = True
return sun_xian and moon_xian
# ============== 辅助分析方法 ==============
def _get_adjacent_palaces(self, position: str) -> Dict[str, str]:
"""获取相邻宫位"""
order = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥']
if position not in order:
return {'left': '', 'right': ''}
idx = order.index(position)
left_idx = (idx - 1) % 12
right_idx = (idx + 1) % 12
return {
'left': order[left_idx],
'right': order[right_idx]
}
def _get_shen_palace_meaning(self, palace_name: str) -> str:
"""获取身宫含义"""
meanings = {
'财帛宫': '后天发展方向在财富,适合私企或自己做老板',
'官禄宫': '后天发展方向在事业,适合从政或做官',
'迁移宫': '后天发展方向在外地,离乡发展更有利',
'夫妻宫': '后天被婚姻影响很大,配偶对人生有重大影响',
'命宫': '身命同宫,先天后天一致'
}
return meanings.get(palace_name, f'身宫在{palace_name}')
def _analyze_sanfang_sizheng(self, palaces: Dict, ming_palace: Dict) -> Dict:
"""分析三方四正"""
return {
'ming': ming_palace,
'caibo': palaces.get('财帛宫', {}),
'guanlu': palaces.get('官禄宫', {}),
'qianyi': palaces.get('迁移宫', {})
}
def _analyze_parents_palace(self, parents_palace: Dict, palaces: Dict, chart_data: Dict) -> Dict:
"""分析父母宫"""
result = {
'stars': parents_palace.get('stars', []),
'analysis': []
}
stars_str = str(result['stars'])
# 检查日月反背
if '太阳' in stars_str or '太阴' in stars_str:
for star in parents_palace.get('stars', []):
if isinstance(star, dict):
if star.get('name') == '太阳' and star.get('brightness') == '陷':
result['analysis'].append('太阳落陷,父亲运势需关注')
if star.get('name') == '太阴' and star.get('brightness') == '陷':
result['analysis'].append('太阴落陷,母亲运势需关注')
# 检查化忌
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '父母宫':
result['analysis'].append('化忌入父母宫,与父母缘分较浅')
return result
def _analyze_siblings_palace(self, siblings_palace: Dict, chart_data: Dict) -> Dict:
"""分析兄弟宫"""
result = {
'stars': siblings_palace.get('stars', []),
'analysis': []
}
# 检查化忌
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '兄弟宫':
result['analysis'].append('化忌入兄弟宫,兄弟姐妹关系需注意或合伙需谨慎')
return result
def _analyze_spouse_palace(self, spouse_palace: Dict, fude_palace: Dict, chart_data: Dict) -> Dict:
"""分析夫妻宫(必须与福德宫同参)"""
result = {
'spouse_palace_stars': spouse_palace.get('stars', []),
'fude_palace_stars': fude_palace.get('stars', []),
'analysis': [],
'critical_warning': None
}
# 🔥 核心秘诀:福德宫化忌 → 夫妻死别
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '福德宫':
result['critical_warning'] = {
'type': 'spouse_death_separation',
'message': '福德宫化忌,夫妻缘分需特别关注(核心秘诀)',
'severity': 'critical'
}
result['analysis'].append('福德宫化忌,婚姻需特别关注')
# 检查夫妻宫化忌
if sihua.get('忌', {}).get('palace') == '夫妻宫':
result['analysis'].append('化忌入夫妻宫,主生离')
# 检查破军星
spouse_stars_str = str(spouse_palace.get('stars', []))
fude_stars_str = str(fude_palace.get('stars', []))
if '破军' in spouse_stars_str or '破军' in fude_stars_str:
result['analysis'].append('破军在福德或夫妻宫,婚姻需谨慎')
if '廉贞' in spouse_stars_str and '贪狼' in spouse_stars_str:
result['analysis'].append('廉贪在夫妻宫,可能有生离或死别')
return result
def _analyze_children_palace(self, children_palace: Dict, chart_data: Dict) -> Dict:
"""分析子女宫"""
result = {
'stars': children_palace.get('stars', []),
'analysis': []
}
# 检查化忌
sihua = chart_data.get('sihua', {})
if sihua.get('忌', {}).get('palace') == '子女宫':
result['analysis'].append('化忌入子女宫,子女缘分需关注')
# 检查空宫
if not children_palace.get('stars', []):
result['analysis'].append('子女宫空宫,需看对宫情况')
return result
def _analyze_career_palace(self, guanlu_palace: Dict, chart_data: Dict) -> Dict:
"""分析事业宫"""
result = {
'stars': guanlu_palace.get('stars', []),
'analysis': [],
'career_direction': ''
}
sihua = chart_data.get('sihua', {})
stars_str = str(guanlu_palace.get('stars', []))
# 化权最佳
if sihua.get('权', {}).get('palace') == '官禄宫':
result['analysis'].append('化权入官禄宫,最适合当官或掌权')
result['career_direction'] = 'leadership'
# 化科
if sihua.get('科', {}).get('palace') == '官禄宫':
result['analysis'].append('化科入官禄宫,适合教育或技术领域')
result['career_direction'] = 'professional'
# 化忌
if sihua.get('忌', {}).get('palace') == '官禄宫':
result['analysis'].append('化忌入官禄宫,不利当官,适合其他发展')
result['career_direction'] = 'alternative'
# 检查机月同梁
if '天机' in stars_str or '天梁' in stars_str:
result['analysis'].append('机月同梁,定为吏也,适合公家单位')
return result
def _analyze_wealth_palace(self, caibo_palace: Dict, chart_data: Dict) -> Dict:
"""分析财帛宫"""
result = {
'stars': caibo_palace.get('stars', []),
'analysis': [],
'wealth_type': ''
}
sihua = chart_data.get('sihua', {})
stars_str = str(caibo_palace.get('stars', []))
# 权禄相逢
has_quan = sihua.get('权', {}).get('palace') == '财帛宫'
has_lucun = '禄存' in stars_str
has_hualv = sihua.get('禄', {}).get('palace') == '财帛宫'
if has_quan and (has_lucun or has_hualv):
result['analysis'].append('权禄相逢,适合自己当老板')
result['wealth_type'] = 'entrepreneur'
elif has_quan:
result['analysis'].append('化权入财帛宫,可在私企掌权')
result['wealth_type'] = 'executive'
# 化忌
if sihua.get('忌', {}).get('palace') == '财帛宫':
result['analysis'].append('化忌入财帛宫,不适合自己做生意')
result['wealth_type'] = 'employee'
return result
def _analyze_migration_palace(self, qianyi_palace: Dict, chart_data: Dict) -> Dict:
"""分析迁移宫"""
result = {
'stars': qianyi_palace.get('stars', []),
'analysis': [],
'migration_advice': ''
}
sihua = chart_data.get('sihua', {})
stars_str = str(qianyi_palace.get('stars', []))
# 化禄
if sihua.get('禄', {}).get('palace') == '迁移宫':
result['analysis'].append('化禄入迁移宫,外地经商大利')
result['migration_advice'] = '适合外地发展'
# 紫微
if '紫微' in stars_str:
if '左辅' in stars_str or '右弼' in stars_str:
result['analysis'].append('紫微有左辅右弼相会,外地比本地发展好')
else:
result['analysis'].append('紫微独守迁移宫,外地遇贵人但孤军奋战')
# 凶星
for evil_star in self.evil_stars:
if evil_star in stars_str:
result['analysis'].append(f'{evil_star}在迁移宫,外地发展需谨慎')
result['migration_advice'] = '本地发展更稳定'
break
return result
def _analyze_daxun(self, daxun: List, chart_data: Dict) -> Dict:
"""分析大运"""
result = {
'daxun_list': daxun,
'analysis': []
}
# 分析每个大运
for dx in daxun:
dx_analysis = {
'age_range': dx.get('age_range', ''),
'palace': dx.get('palace', ''),
'stars': dx.get('stars', [])
}
# 检查是否有化忌冲
# 简化判断,实际需要更复杂的计算
result['analysis'].append(dx_analysis)
return result
def _get_age_group(self, birth_info: Dict) -> str:
"""获取年龄段"""
birth_year = birth_info.get('year', 0)
if not birth_year:
return 'unknown'
import datetime
current_year = datetime.datetime.now().year
age = current_year - birth_year
if age < 25:
return 'young'
elif age < 40:
return 'middle_young'
elif age < 55:
return 'middle'
else:
return 'senior'
def _generate_summary(self, result: Dict) -> Dict:
"""生成综合评估摘要(使用全部十步分析数据)"""
steps = result.get('steps', [])
summary = {
'overall_pattern': '',
'key_strengths': [],
'key_challenges': [],
'life_advice': [],
'post_heaven_focus': '',
'relationship_highlights': [],
'health_warnings': [],
'marriage_timing': '',
'fortune_blessing': '',
'formulas_count': len(result.get('formulas_matched', []))
}
# Step 2: 总格评价(吉格/凶格)
step2 = steps[1] if len(steps) > 1 else {}
analysis = step2.get('analysis', {})
summary['overall_pattern'] = analysis.get('overall_comment', '')
for ji_ge in analysis.get('ji_ge', []):
summary['key_strengths'].append(ji_ge.get('meaning', ''))
for xiong_ge in analysis.get('xiong_ge', []):
summary['key_challenges'].append(xiong_ge.get('meaning', ''))
# Step 3: 身宫 → 后天发展方向
step3 = steps[2] if len(steps) > 2 else {}
shen_analysis = step3.get('analysis', {})
shen_meaning = shen_analysis.get('shen_palace_meaning', '')
if shen_meaning:
summary['post_heaven_focus'] = shen_meaning
# Step 4: 六亲 → 关键亲缘提醒
step4 = steps[3] if len(steps) > 3 else {}
six_analysis = step4.get('analysis', {})
for relation in ['parents', 'siblings', 'spouse', 'children']:
rel_data = six_analysis.get(relation, {})
key_point = rel_data.get('key_point', '') or rel_data.get('status', '')
if key_point and key_point != 'normal':
summary['relationship_highlights'].append(f'{relation}: {key_point}')
# Step 5: 事业方向
step5 = steps[4] if len(steps) > 4 else {}
career_analysis = step5.get('analysis', {}).get('career', {})
if career_analysis.get('career_direction'):
direction_map = {
'leadership': '适合领导岗位或自主创业',
'professional': '适合专业技术或教育领域',
'alternative': '建议避开官场,另寻发展方向'
}
advice = direction_map.get(career_analysis['career_direction'], '')
if advice:
summary['life_advice'].append(advice)
# Step 6: 疾厄 → 健康注意事项
step6 = steps[5] if len(steps) > 5 else {}
health_analysis = step6.get('analysis', {})
health_warning = health_analysis.get('health_warning', '') or health_analysis.get('key_point', '')
if health_warning:
summary['health_warnings'].append(health_warning)
meridian = health_analysis.get('meridian', '')
if meridian:
summary['health_warnings'].append(f'经络关注: {meridian}')
# Step 8: 婚姻时机
step8 = steps[7] if len(steps) > 7 else {}
marriage_analysis = step8.get('analysis', {})
marriage_note = marriage_analysis.get('timing_note', '') or marriage_analysis.get('key_point', '')
if marriage_note:
summary['marriage_timing'] = marriage_note
# Step 10: 福德宫核心判断
step10 = steps[9] if len(steps) > 9 else {}
fude_analysis = step10.get('analysis', {})
fude_note = fude_analysis.get('core_meaning', '') or fude_analysis.get('key_point', '')
if fude_note:
summary['fortune_blessing'] = fude_note
# 福德宫化忌重要警告
fude_warning = fude_analysis.get('critical_warning', '')
if fude_warning:
summary['key_challenges'].append(fude_warning)
# 综合建议
if summary['key_challenges']:
summary['life_advice'].append('注意命盘中的挑战,提前做好准备')
if summary['health_warnings']:
summary['life_advice'].append('关注健康,定期体检')
return summary
def _enhance_summary_with_barnum(self, summary: Dict) -> Dict:
"""
使用巴纳姆效果增强summary(dict类型)
Args:
summary: 原始summary字典
Returns:
dict: 巴纳姆增强后的summary
"""
enhanced = summary.copy()
# 增强总格评价
if enhanced['overall_pattern']:
enhanced['overall_pattern_enhanced'] = self.barnum._apply_generic_barnum(
enhanced['overall_pattern'],
BarnumTone.WARM
)
# 增强优势描述
if enhanced['key_strengths']:
enhanced['key_strengths_enhanced'] = [
self.barnum._apply_generic_barnum(strength, BarnumTone.SUPPORTIVE)
for strength in enhanced['key_strengths']
]
# 增强挑战描述(用温和语言替代敏感内容)
if enhanced['key_challenges']:
enhanced['key_challenges_enhanced'] = [
self.barnum.replace_sensitive_content(
self.barnum._apply_generic_barnum(challenge, BarnumTone.CAUTIOUS)
)
for challenge in enhanced['key_challenges']
]
# 增强人生建议
if enhanced['life_advice']:
enhanced['life_advice_enhanced'] = [
self.barnum._apply_generic_barnum(advice, BarnumTone.INSIGHTFUL)
for advice in enhanced['life_advice']
]
return enhanced
# 单例模式
_engine_instance = None
def get_reading_engine() -> ReadingMethodologyEngine:
"""获取批命引擎单例"""
global _engine_instance
if _engine_instance is None:
_engine_instance = ReadingMethodologyEngine()
return _engine_instance
# 导出
__all__ = ['ReadingMethodologyEngine', 'get_reading_engine']
"""
批命流程引擎 - Reading Methodology Engine
实现10步标准批命流程和36条核心口诀应用
Version: 1.0
Created: 2026-02-03
Author: Sisi & TH Studio
核心功能:
1. 10步标准批命流程执行
2. 36条核心口诀自动匹配
3. 吉格凶格自动识别
4. 死限判断公式应用
5. 综合批命报告生成
"""
from typing import Dict, List, Any, Optional, Tuple
from methodology_loader import MethodologyLoader, get_methodology_loader
from barnum_cold_reader import BarnumColdReader, BarnumTone, get_barnum_reader
class ReadingMethodologyEngine:
"""
批命流程引擎
执行10步标准批命流程,应用36条核心口诀
"""
def __init__(self):
"""初始化批命引擎"""
self.methodology = get_methodology_loader()
self.barnum = get_barnum_reader()
# 主星列表
self.main_stars = [
'紫微', '天机', '太阳', '武曲', '天同', '廉贞', '天府',
'太阴', '贪狼', '巨门', '天相', '天梁', '七杀', '破军'
]
# 六吉星
self.lucky_stars = ['左辅', '右弼', '文昌', '文曲', '天魁', '天钺']
# 六煞星
self.evil_stars = ['擎羊', '陀罗', '火星', '铃星', '天空', '地劫']
# 四化对照表(按年干)
self.sihua_by_tiangan = {
'甲': {'禄': '廉贞', '权': '破军', '科': '武曲', '忌': '太阳'},
'乙': {'禄': '太阴', '权': '天机', '科': '天同', '忌': '巨门'},
'丙': {'禄': '天同', '权': '天机', '科': '文昌', '忌': '廉贞'},
'丁': {'禄': '太阴', '权': '天同', '科': '天机', '忌': '巨门'},
'戊': {'禄': '贪狼', '权': '太阴', '科': '右弼', '忌': '天机'},
'己': {'禄': '武曲', '权': '贪狼', '科': '天梁', '忌': '文曲'},
'庚': {'禄': '太阳', '权': '武曲', '科': '太阴', '忌': '天同'},
'辛': {'禄': '巨门', '权': '太阳', '科': '文曲', '忌': '文昌'},
'壬': {'禄': '天梁', '权': '紫微', '科': '左辅', '忌': '武曲'},
'癸': {'禄': '破军', '权': '巨门', '科': '太阴', '忌': '贪狼'}
}
# 命局数对应
self.mingshu_map = {
'水': 2, '木': 3, '金': 4, '土': 5, '火': 6
}
# 吉格规则
self.ji_ge_rules = self._init_ji_ge_rules()
# 凶格规则
self.xiong_ge_rules = self._init_xiong_ge_rules()
def _init_ji_ge_rules(self) -> List[Dict]:
"""初始化吉格规则"""
return [
{
'name': '紫府夹权',
'condition': lambda palaces: self._check_zifu_jia_quan(palaces),
'meaning': '紫微天府在命宫左右侧,主有权势',
'category': 'power'
},
{
'name': '日月夹命',
'condition': lambda palaces: self._check_riyue_jia_ming(palaces),
'meaning': '太阳太阴庙旺在命宫两侧,一世财禄无缺',
'category': 'wealth'
},
{
'name': '魁钺夹贵',
'condition': lambda palaces: self._check_kuiyue_jia_gui(palaces),
'meaning': '天魁天钺在命宫两侧,贵人扶持',
'category': 'noble'
},
{
'name': '日月并明',
'condition': lambda palaces: self._check_riyue_bing_ming(palaces),
'meaning': '太阳旺辰+太阴旺戌,一世荣华',
'category': 'prosperity'
},
{
'name': '明珠出海',
'condition': lambda palaces: self._check_mingzhu_chuhai(palaces),
'meaning': '命宫在未,太阴亥宫+太阳卯宫入庙,父母双全',