""" 批命流程引擎 - 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']