格局判定

本命与运限的格局命中、口径开关、格局标识与序列化 DTO。

格局是「盘上某几颗星按特定方式凑在一起」的模式识别。判定在本命盘与运限盘上共用同一套规则, 共 64 条。什么是格局、每条规则的条件与来源,见概念页

let chart = by_solar("1985-5-3", 9, Gender::Male, true, Language::ZhCN, Config::default())?;
let hits = chart.patterns();

本页示例统一用 Language::ZhCN 的本命盘,因此输出里的展示值都是中文。

类型

五个类型都在 crate 根重导出:PatternHitStarAtPatternConfigBrightnessSourcePatternKey,另有常量 ALL_PATTERNS 与模块函数 patterns_at

PatternHit

一次命中。

字段类型说明
keyPatternKey格局
scopeScope判定视角:本命为 Scope::Origin,运限为该层
palaceusize成格所在的宫位索引(0-11,寅宫为 0)
variantOption<&'static str>多口径格局命中的是哪个口径;单口径为 None
brokenbool「破格 / 加杀平常」条件是否触发。成格照报,这里只作标记
starsVec<StarAt>参与成格的星与落宫

PatternHit 实现 ClonePartialEqEqSerializeDeserialize

StarAt

一颗参与成格的星。

字段类型说明
starStarKey星耀
palaceusize该星真正待的宫位索引(借宫时不是借到的那一宫)
brightnessOption<Brightness>亮度;无亮度表的星为 None
mutagenOption<Mutagen>判定视角下的四化:本命读生年四化,运限读该层四化

PatternConfig

判定口径。凡是「同一格局的多种成立形式」都走 PatternHit::variant,这里只放会改变 事实判定本身的数据口径,因此只有三个字段。

pub struct PatternConfig {
    pub brightness_source: BrightnessSource,  // 默认 Table
    pub borrow: bool,                         // 默认 true
    pub flow_stars: bool,                     // 默认 true
}
字段默认作用
brightness_sourceBrightnessSource::Table日月明暗的依据
borrowtrue空宫是否借对宫主星参与判定
flow_starstrue运限视角下流曜(运禄/流禄、运昌/流昌…)是否等同对应本命辅星

BrightnessSource 两个变体:Table 按星盘亮度表(庙旺为明,陷与「不」为暗,与 iztro 逐值一致), Positional 按传统位置(太阳寅至午明、酉至丑暗;太阴酉至丑明、卯至未暗)。 两者的取舍见概念页的说明

PatternConfig 实现 Default,改单项用结构体更新语法:

let cfg = PatternConfig {
    brightness_source: BrightnessSource::Positional,
    ..Default::default()
};

PatternKey

64 个格局的语言无关标识,Copy + Hash,可直接做 HashMap 的键。

方法签名说明
as_keyfn as_key(self) -> &'static strsnake_case 标识,如 "sha_po_lang"
from_keyfn from_key(key: &str) -> Option<Self>由标识反查;未知字符串返回 None
is_horoscope_onlyfn is_horoscope_only(self) -> bool是否行运格(只在运限视角判定)

常量 ALL_PATTERNS: [PatternKey; 64] 按来源页条目顺序列出全部格局。 译名用 translate_pattern(key, lang),六种语言都有。

示例

println!("{}", ALL_PATTERNS.len());
println!("{}", PatternKey::ShaPoLang.as_key());
println!("{:?}", PatternKey::from_key("sha_po_lang"));
println!("{:?}", PatternKey::from_key("nope"));
println!("{}", PatternKey::FengYunJiHui.is_horoscope_only());

输出

64
sha_po_lang
Some(ShaPoLang)
None
true

patterns

用途 取本命盘的全部格局命中,默认口径。

斗数含义 把这张盘上成立的所有有名字的星耀组合列出来,附上成格的宫位与证据星。

签名

impl Astrolabe {
    pub fn patterns(&self) -> Vec<PatternHit>
}

返回值 Vec<PatternHit>——按来源页条目顺序排列;一条格局也不成立时为空 Vec。 本命盘上两条行运格(禄衰马困、风云际会)永远不出现。

示例

let zh = Language::ZhCN;
let chart = by_solar("1985-5-3", 9, Gender::Male, true, zh, Config::default())?;

for hit in chart.patterns() {
    println!("{} {} broken={}", translate_pattern(hit.key, zh), hit.palace, hit.broken);
}

输出

武贪同行 11 broken=false
府相朝垣 5 broken=false
杀破狼 11 broken=false
禄马交驰 5 broken=false
左右夹命 5 broken=false
文贵文华 11 broken=false
文星朝命 5 broken=true
文星暗拱 5 broken=false
文星暗拱 5 broken=false

取一条命中的证据星:

let hit = chart.patterns().into_iter()
    .find(|h| h.key == PatternKey::FuXiangChaoYuan)
    .unwrap();

println!("{} variant={:?}", translate_pattern(hit.key, zh), hit.variant);
for s in &hit.stars {
    println!("  {} 宫位 {} 亮度 {:?}", translate_star(s.star, zh), s.palace, s.brightness);
}
府相朝垣 variant=Some("soul_empty")
  天府 宫位 9 亮度 Some(De)
  天相 宫位 1 亮度 Some(Xian)

边界与陷阱


patterns_with

用途 同 patterns,指定判定口径。

签名

impl Astrolabe {
    pub fn patterns_with(&self, config: &PatternConfig) -> Vec<PatternHit>
}

参数

参数类型必填默认说明
config&PatternConfig判定口径,PatternConfig::default()patterns() 的行为

返回值 同 patterns

示例 同一张盘按两种日月明暗口径判:

let chart = by_solar("1985-1-5", 11, Gender::Female, true, zh, Config::default())?;
let cfg = PatternConfig {
    brightness_source: BrightnessSource::Positional,
    ..Default::default()
};

println!("{:?}", chart.patterns().iter()
    .map(|h| translate_pattern(h.key, zh)).collect::<Vec<_>>());
println!("{:?}", chart.patterns_with(&cfg).iter()
    .map(|h| translate_pattern(h.key, zh)).collect::<Vec<_>>());

输出

["禄马交驰", "左右夹命", "坐贵向贵"]
["日月并明", "禄马交驰", "左右夹命", "坐贵向贵"]

HoroscopeRef::patterns

用途 取某个运限层级视角下的格局命中。

斗数含义 以该层的命宫为命宫、合并该层的流曜与四化之后重跑全部规则。 「本命有此组合,大限又走到即享其益」就是这么算出来的。

签名

impl<'a> HoroscopeRef<'a> {
    pub fn patterns(&self, scope: Scope) -> Vec<PatternHit>
    pub fn patterns_with(&self, scope: Scope, config: &PatternConfig) -> Vec<PatternHit>
}

参数

参数类型必填默认说明
scopeScope判定视角所在的层级
config&PatternConfigpatterns_with 必填判定口径

返回值 Vec<PatternHit>,每条的 scope 即传入的层级。 传 Scope::Origin 时结果与本命盘上直接调 patterns() 完全一致。

示例

let chart = by_solar("2000-8-16", 2, Gender::Female, true, zh, Config::default())?;
let h = chart.horoscope("2025-6-1", 0)?;

for hit in h.patterns(Scope::Decadal) {
    println!("{} {:?} {:?}", translate_pattern(hit.key, zh), hit.scope, hit.variant);
}

输出

杀破狼 Decadal None
风云际会 Decadal None
风云际会 Decadal Some("yearly")

同一张盘的本命视角只有一条「府相朝垣」——大限换了命宫,杀破狼才在这一层成立。

边界与陷阱


patterns_at

用途 在某运限层视角上判定格局的自由函数版,收 HoroscopeData 而非 HoroscopeRef

签名

pub fn patterns_at(
    astrolabe: &Astrolabe,
    horoscope: &HoroscopeData,
    scope: Scope,
    config: &PatternConfig,
) -> Vec<PatternHit>

返回值 同 HoroscopeRef::patterns_with

手里只有 HoroscopeData(例如从别处反序列化得到)时用它; 有 HoroscopeRef 的场合用方法版更短。


patterns_dto

用途 取序列化用的命中列表:键为 camelCase,值按排盘语言翻译,同时给出语言无关标识。 三语言绑定与 FFI 都走这一层。

签名

impl Astrolabe {
    pub fn patterns_dto(&self, config: &PatternConfig) -> Vec<PatternHitDto>
}

impl HoroscopeData {
    pub fn patterns_dto(
        &self,
        astrolabe: &Astrolabe,
        scope: Scope,
        config: &PatternConfig,
    ) -> Vec<PatternHitDto>
}

返回值 Vec<PatternHitDto>。相对 PatternHit 多出四项: 每条带 name(译名)与 palaceName / palaceNameKey(成格宫在该视角下的宫名), 每颗证据星带 namebrightnessKey / mutagenKey。 无值的可选键在序列化时省略。

示例

let chart = by_solar("2000-8-16", 2, Gender::Female, true, zh, Config::default())?;
let dto = chart.patterns_dto(&PatternConfig::default());
println!("{}", serde_json::to_string_pretty(&dto[0]).unwrap());

输出

{
  "key": "fu_xiang_chao_yuan",
  "name": "府相朝垣",
  "scope": "origin",
  "palaceIndex": 4,
  "palaceName": "命宫",
  "palaceNameKey": "soulPalace",
  "broken": false,
  "stars": [
    {
      "key": "tianfuMaj",
      "name": "天府",
      "palaceIndex": 8,
      "brightness": "庙",
      "brightnessKey": "miao"
    },
    {
      "key": "tianxiangMaj",
      "name": "天相",
      "palaceIndex": 0,
      "brightness": "庙",
      "brightnessKey": "miao"
    }
  ]
}

PatternHitDto 里的字段叫 palaceIndex,Rust 结构体里叫 palace—— DTO 的键名与 JS 侧的命名习惯对齐,Rust 侧用更短的名字。


语义化文本

格局命中列表可以经 text::patterns_to_text 投影成文本,每条一行: 格局名、命中宫、构成星耀,破格标 [破格]

pub fn patterns_to_text(hits: &[PatternHit], palace_names: &[Palace], lang: Language) -> String

palace_names 是判定视角下按宫位索引排列的十二宫名——本命视角传 chart.palaces 各宫的 name,运限视角传该层的 palace_names

use x_iztro::text::patterns_to_text;

let hits = chart.patterns();
let names: Vec<Palace> = chart.palaces.iter().map(|p| p.name).collect();
print!("{}", patterns_to_text(&hits, &names, chart.language));

输出

- 府相朝垣(命宫): 天府(庙), 天相(庙)

本命盘的 to_text 已自带这一节;单独调用适合只要格局摘要的场景。

本页目录