Files
web-page-backend/saju-lab/app/calculator/monthly_flow.py
gahusb 030367da6c feat(saju-lab): monthly_flow.py — 12개월 운세 흐름 (4 tests)
월간(月干)과 월지(月支)의 일간 관계를 이용한 12개월 운세 점수 계산:
- 월간 상생(生) 관계: +5~10점
- 월간 상극(剋) 관계: -8점
- 월지 육합(六合) 관계: +10점
- 월지 육충(六衝) 관계: -12점
- 월지 상생/상극: ±4점

점수 범위 0~100, 5단계 레이블 (정체/도전/변동/안정/성장)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 08:02:35 +09:00

92 lines
2.7 KiB
Python

"""12개월 운세 흐름 — 월운(月運) + 일간 관계."""
from typing import List
from .constants import (
HEAVENLY_STEMS, EARTHLY_BRANCHES,
FIVE_ELEMENTS, SHENG_CYCLE, KE_CYCLE,
)
# 寅월부터 시작 (1월=寅, 2월=卯, ..., 12월=丑)
MONTH_BRANCHES = ["", "", "", "", "", "", "", "", "", "", "", ""]
LIU_CHONG = {
frozenset(["", ""]), frozenset(["", ""]),
frozenset(["", ""]), frozenset(["", ""]),
frozenset(["", ""]), frozenset(["", ""]),
}
LIU_HE = {
frozenset(["", ""]), frozenset(["", ""]),
frozenset(["", ""]), frozenset(["", ""]),
frozenset(["", ""]), frozenset(["", ""]),
}
def _month_stem_for_year(year_stem: str, branch_idx: int) -> str:
"""월간(月干) — saju-web의 공식: (yearStemIdx * 2 + branchIdx) % 10."""
year_stem_idx = HEAVENLY_STEMS.index(year_stem)
stem_idx = (year_stem_idx * 2 + branch_idx) % 10
return HEAVENLY_STEMS[stem_idx]
def _label_for(score: int) -> str:
if score >= 80:
return "성장"
if score >= 65:
return "안정"
if score >= 50:
return "변동"
if score >= 35:
return "도전"
return "정체"
def calculate_monthly_flow(saju: dict, year: int) -> List[dict]:
"""12개월 운세 흐름."""
day_stem = saju["day_stem"]
day_element = FIVE_ELEMENTS[day_stem]
day_branch = saju["day"]["branch"]
year_stem = saju["year"]["stem"]
flow: List[dict] = []
for i, branch in enumerate(MONTH_BRANCHES):
branch_idx = EARTHLY_BRANCHES.index(branch)
stem = _month_stem_for_year(year_stem, branch_idx)
stem_element = FIVE_ELEMENTS[stem]
branch_element = FIVE_ELEMENTS[branch]
score = 60
if SHENG_CYCLE.get(day_element) == stem_element:
score += 5
elif SHENG_CYCLE.get(stem_element) == day_element:
score += 10
elif KE_CYCLE.get(day_element) == stem_element:
score += 8
elif KE_CYCLE.get(stem_element) == day_element:
score -= 8
elif stem_element == day_element:
score += 3
if frozenset([day_branch, branch]) in LIU_HE:
score += 10
elif frozenset([day_branch, branch]) in LIU_CHONG:
score -= 12
if SHENG_CYCLE.get(branch_element) == day_element:
score += 4
elif KE_CYCLE.get(branch_element) == day_element:
score -= 4
score = max(0, min(100, score))
flow.append({
"month": i + 1,
"stem": stem,
"branch": branch,
"score": score,
"label": _label_for(score),
})
return flow