import { BRANCHES } from './constants'; import type { EarthlyBranchName, FiveElement, HeavenlyStemName, } from './types'; const STEM_ORDER = '甲乙丙丁戊己庚辛壬癸'; const STEM_COMBINATIONS = new Map([ ['甲己', 'earth'], ['乙庚', 'metal'], ['丙辛', 'water'], ['丁壬', 'wood'], ['戊癸', 'fire'], ]); const BRANCH_SIX_COMBINATIONS = new Map([ ['子丑', 'earth'], ['寅亥', 'wood'], ['卯戌', 'fire'], ['辰酉', 'metal'], ['巳申', 'water'], ['午未', 'earth'], ]); const BRANCH_CLASHES = new Set([ '子午', '丑未', '寅申', '卯酉', '辰戌', '巳亥', ]); const BRANCH_HARMS = new Set([ '子未', '丑午', '寅巳', '卯辰', '申亥', '酉戌', ]); export const BRANCH_THREE_COMBINATION_RULES: ReadonlyArray<{ branches: readonly [EarthlyBranchName, EarthlyBranchName, EarthlyBranchName]; element: FiveElement; label: string; }> = [ { branches: ['申', '子', '辰'], element: 'water', label: '申子辰三合' }, { branches: ['亥', '卯', '未'], element: 'wood', label: '亥卯未三合' }, { branches: ['寅', '午', '戌'], element: 'fire', label: '寅午戌三合' }, { branches: ['巳', '酉', '丑'], element: 'metal', label: '巳酉丑三合' }, ]; export const BRANCH_TRIPLE_PUNISHMENT_RULES: ReadonlyArray<{ branches: readonly [EarthlyBranchName, EarthlyBranchName, EarthlyBranchName]; pattern: 'yin-si-shen' | 'chou-xu-wei'; label: string; }> = [ { branches: ['寅', '巳', '申'], pattern: 'yin-si-shen', label: '寅巳申三刑' }, { branches: ['丑', '戌', '未'], pattern: 'chou-xu-wei', label: '丑戌未三刑' }, ]; export const SELF_PUNISHMENT_BRANCHES: readonly EarthlyBranchName[] = [ '辰', '午', '酉', '亥', ]; export function stemPairKey( left: HeavenlyStemName, right: HeavenlyStemName, ): string { return [left, right].sort((a, b) => STEM_ORDER.indexOf(a) - STEM_ORDER.indexOf(b) ).join(''); } export function branchPairKey( left: EarthlyBranchName, right: EarthlyBranchName, ): string { return [left, right].sort((a, b) => BRANCHES.indexOf(a) - BRANCHES.indexOf(b) ).join(''); } export function getStemCombinationElement( left: HeavenlyStemName, right: HeavenlyStemName, ): FiveElement | undefined { return STEM_COMBINATIONS.get(stemPairKey(left, right)); } export function getBranchSixCombinationElement( left: EarthlyBranchName, right: EarthlyBranchName, ): FiveElement | undefined { return BRANCH_SIX_COMBINATIONS.get(branchPairKey(left, right)); } export function isBranchClash( left: EarthlyBranchName, right: EarthlyBranchName, ): boolean { return BRANCH_CLASHES.has(branchPairKey(left, right)); } export function isBranchHarm( left: EarthlyBranchName, right: EarthlyBranchName, ): boolean { return BRANCH_HARMS.has(branchPairKey(left, right)); }