""" 八字排盘基础数据与规则 天干地支、藏干、十神、纳音、空亡、神煞——均为子平术几百年通行的传统命理常数, 不属于任何单一作者的原创表达,此处按经典规则自行组织/计算,非转录自任何第三方代码库。 """ from collections import OrderedDict Gan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"] Zhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"] # 天干五行 gan5 = { "甲": "木", "乙": "木", "丙": "火", "丁": "火", "戊": "土", "己": "土", "庚": "金", "辛": "金", "壬": "水", "癸": "水", } # 地支本气五行 zhi_wuhang = { "子": "水", "丑": "土", "寅": "木", "卯": "木", "辰": "土", "巳": "火", "午": "火", "未": "土", "申": "金", "酉": "金", "戌": "土", "亥": "水", } # 阴阳:甲丙戊庚壬为阳,乙丁己辛癸为阴(Gan列表偶数位为阳、奇数位为阴) _YANG_GAN = set(Gan[0::2]) # 五行相生:木生火 火生土 土生金 金生水 水生木 _SHENG = {"木": "火", "火": "土", "土": "金", "金": "水", "水": "木"} # 五行相克:木克土 土克水 水克火 火克金 金克木 _KE = {"木": "土", "土": "水", "水": "火", "火": "金", "金": "木"} # 地支藏干及其力量权重(本气/中气/余气),子平术通用表 zhi5 = { "子": OrderedDict({"癸": 8}), "丑": OrderedDict({"己": 5, "癸": 2, "辛": 1}), "寅": OrderedDict({"甲": 5, "丙": 2, "戊": 1}), "卯": OrderedDict({"乙": 8}), "辰": OrderedDict({"戊": 5, "乙": 2, "癸": 1}), "巳": OrderedDict({"丙": 5, "戊": 2, "庚": 1}), "午": OrderedDict({"丁": 5, "己": 3}), "未": OrderedDict({"己": 5, "丁": 2, "乙": 1}), "申": OrderedDict({"庚": 5, "壬": 2, "戊": 1}), "酉": OrderedDict({"辛": 8}), "戌": OrderedDict({"戊": 5, "辛": 2, "丁": 1}), "亥": OrderedDict({"壬": 5, "甲": 3}), } # 藏干列表(不含权重),直接从 zhi5 派生,保证两者不会不一致 zhi5_list = {zhi: list(stems.keys()) for zhi, stems in zhi5.items()} def _ten_god(day_master: str, target_gan: str) -> str: """按日主与目标天干的五行生克 + 阴阳同异,算出十神关系(子平术标准规则)。""" if target_gan == day_master: return "比" e_me, e_target = gan5[day_master], gan5[target_gan] same_polarity = (day_master in _YANG_GAN) == (target_gan in _YANG_GAN) if e_target == e_me: return "比" if same_polarity else "劫" if _SHENG[e_me] == e_target: # 我生 return "食" if same_polarity else "伤" if _KE[e_me] == e_target: # 我克 return "才" if same_polarity else "财" if _KE[e_target] == e_me: # 克我 return "杀" if same_polarity else "官" if _SHENG[e_target] == e_me: # 生我 return "枭" if same_polarity else "印" return "unknown" # 十神表:ten_deities[日主][目标天干] -> 十神。按规则实时算出,不是手抄表。 ten_deities = { d: {g: _ten_god(d, g) for g in Gan} for d in Gan } # 六十甲子纳音(《三命通会》以来子平术通行表,古今各家版本完全一致,属公共历法常识) nayins = { ('甲', '子'): '海中金', ('乙', '丑'): '海中金', ('丙', '寅'): '炉中火', ('丁', '卯'): '炉中火', ('戊', '辰'): '大林木', ('己', '巳'): '大林木', ('庚', '午'): '路旁土', ('辛', '未'): '路旁土', ('壬', '申'): '剑锋金', ('癸', '酉'): '剑锋金', ('甲', '戌'): '山头火', ('乙', '亥'): '山头火', ('丙', '子'): '涧下水', ('丁', '丑'): '涧下水', ('戊', '寅'): '城头土', ('己', '卯'): '城头土', ('庚', '辰'): '白蜡金', ('辛', '巳'): '白蜡金', ('壬', '午'): '杨柳木', ('癸', '未'): '杨柳木', ('甲', '申'): '井泉水', ('乙', '酉'): '井泉水', ('丙', '戌'): '屋上土', ('丁', '亥'): '屋上土', ('戊', '子'): '霹雳火', ('己', '丑'): '霹雳火', ('庚', '寅'): '松柏木', ('辛', '卯'): '松柏木', ('壬', '辰'): '长流水', ('癸', '巳'): '长流水', ('甲', '午'): '砂中金', ('乙', '未'): '砂中金', ('丙', '申'): '山下火', ('丁', '酉'): '山下火', ('戊', '戌'): '平地木', ('己', '亥'): '平地木', ('庚', '子'): '壁上土', ('辛', '丑'): '壁上土', ('壬', '寅'): '金泊金', ('癸', '卯'): '金泊金', ('甲', '辰'): '覆灯火', ('乙', '巳'): '覆灯火', ('丙', '午'): '天河水', ('丁', '未'): '天河水', ('戊', '申'): '大驿土', ('己', '酉'): '大驿土', ('庚', '戌'): '钗钏金', ('辛', '亥'): '钗钏金', ('壬', '子'): '桑柘木', ('癸', '丑'): '桑柘木', ('甲', '寅'): '大溪水', ('乙', '卯'): '大溪水', ('丙', '辰'): '砂中土', ('丁', '巳'): '砂中土', ('戊', '午'): '天上火', ('己', '未'): '天上火', ('庚', '申'): '石榴木', ('辛', '酉'): '石榴木', ('壬', '戌'): '大海水', ('癸', '亥'): '大海水', } def _sixty_index(gan: str, zhi: str) -> int: """给定干支求其在六十甲子里的序号(0=甲子)。""" gi, zi = Gan.index(gan), Zhi.index(zhi) for n in range(60): if n % 10 == gi and n % 12 == zi: return n raise ValueError(f'invalid ganzhi combination: {gan}{zhi}') def _empties_for(gan: str, zhi: str) -> tuple: """算空亡:某干支所在'旬'里,十天干轮完后地支剩下的两个未配对分支即为空亡。""" xun_start = (_sixty_index(gan, zhi) // 10) * 10 return (Zhi[(xun_start + 10) % 12], Zhi[(xun_start + 11) % 12]) empties = {(g, z): _empties_for(g, z) for g in Gan for z in Zhi if (Gan.index(g) - Zhi.index(z)) % 2 == 0} # 神煞(子平术通用规则,年/月/日柱查法各异) year_shens = { '孤辰': {"子": "寅", "丑": "寅", "寅": "巳", "卯": "巳", "辰": "巳", "巳": "申", "午": "申", "未": "申", "申": "亥", "酉": "亥", "戌": "亥", "亥": "寅"}, '寡宿': {"子": "戌", "丑": "戌", "寅": "丑", "卯": "丑", "辰": "丑", "巳": "辰", "午": "辰", "未": "辰", "申": "未", "酉": "未", "戌": "未", "亥": "戌"}, '大耗': {"子": "巳未", "丑": "午申", "寅": "未酉", "卯": "申戌", "辰": "酉亥", "巳": "戌子", "午": "亥丑", "未": "子寅", "申": "丑卯", "酉": "寅辰", "戌": "卯巳", "亥": "辰午"}, } month_shens = { '天德': {"子": "巳", "丑": "庚", "寅": "丁", "卯": "申", "辰": "壬", "巳": "辛", "午": "亥", "未": "甲", "申": "癸", "酉": "寅", "戌": "丙", "亥": "乙"}, '月德': {"子": "壬", "丑": "庚", "寅": "丙", "卯": "甲", "辰": "壬", "巳": "庚", "午": "丙", "未": "甲", "申": "壬", "酉": "庚", "戌": "丙", "亥": "甲"}, } day_shens = { '将星': {"子": "子", "丑": "酉", "寅": "午", "卯": "卯", "辰": "子", "巳": "酉", "午": "午", "未": "卯", "申": "子", "酉": "酉", "戌": "午", "亥": "卯"}, '华盖': {"子": "辰", "丑": "丑", "寅": "戌", "卯": "未", "辰": "辰", "巳": "丑", "午": "戌", "未": "未", "申": "辰", "酉": "丑", "戌": "戌", "亥": "未"}, '驿马': {"子": "寅", "丑": "亥", "寅": "申", "卯": "巳", "辰": "寅", "巳": "亥", "午": "申", "未": "巳", "申": "寅", "酉": "亥", "戌": "申", "亥": "巳"}, '劫煞': {"子": "巳", "丑": "寅", "寅": "亥", "卯": "申", "辰": "巳", "巳": "寅", "午": "亥", "未": "申", "申": "巳", "酉": "寅", "戌": "亥", "亥": "申"}, '亡神': {"子": "亥", "丑": "申", "寅": "巳", "卯": "寅", "辰": "亥", "巳": "申", "午": "巳", "未": "寅", "申": "亥", "酉": "申", "戌": "巳", "亥": "寅"}, '桃花': {"子": "酉", "丑": "午", "寅": "卯", "卯": "子", "辰": "酉", "巳": "午", "午": "卯", "未": "子", "申": "酉", "酉": "午", "戌": "卯", "亥": "子"}, } g_shens = { '天乙': {"甲": "未丑", "乙": "申子", "丙": "酉亥", "丁": "酉亥", "戊": "未丑", "己": "申子", "庚": "未丑", "辛": "寅午", "壬": "卯巳", "癸": "卯巳"}, '文昌': {"甲": "巳", "乙": "午", "丙": "申", "丁": "酉", "戊": "申", "己": "酉", "庚": "亥", "辛": "子", "壬": "寅", "癸": "丑"}, '阳刃': {"甲": "卯", "乙": "", "丙": "午", "丁": "", "戊": "午", "己": "", "庚": "酉", "辛": "", "壬": "子", "癸": ""}, '红艳': {"甲": "午", "乙": "午", "丙": "寅", "丁": "未", "戊": "辰", "己": "辰", "庚": "戌", "辛": "酉", "壬": "子", "癸": "申"}, }