news 2026/10/27 9:06:52

Java 实现六爻排盘小程序:从摇卦到完整盘面的后端源码实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 实现六爻排盘小程序:从摇卦到完整盘面的后端源码实战

简介:这份资源是Java实现的六爻起卦排盘小程序完整源码,面向对周易占卜文化感兴趣、希望用编程方式实现传统起卦流程的开发者与学习者。程序按六爻占卜规则模拟硬币抛掷或蓍草操作,随机生成由六个爻组成的卦象,并依据六十四卦卦辞自动完成解读,省去手工排盘与查卦的繁琐步骤。资源包共17个文件,以7个xml配置文件、5个class字节码、3个java源码及2个gitignore为主,压缩后约28KB,涵盖起卦、卦象分析与结果展示等模块,结构清晰,便于理解面向对象设计在传统占卜场景中的落地方式。目前已有268人学习下载,适合作为Java入门练手项目或传统文化与编程结合的参考案例,读者可从中获取完整的排盘算法思路、模块划分方式与可运行的工程骨架,并在此基础上扩展人机交互或个性化占卜功能。

1. 六爻排盘小程序:从「摇一卦」到可运行源码,Java 后端到底要做什么

很多人第一次听到「六爻起卦排盘小程序」,脑子里浮现的是玄学界面加动画铜钱,但真正落到 Java 代码层面,它其实是一套规则确定、状态可枚举、结果可复现的排盘计算系统。用户在小程序里点「摇卦」,后端要完成的是:记录六次摇动结果(老阴、少阳、少阴、老阳),映射成六爻的阴阳与动静,再叠加干支、月建、日辰、六亲、六神、世应、旬空这些固定规则,最后输出一份结构化排盘。它解决的不是「预测准不准」,而是「排得对不对、算得快不快、结果能不能稳定复现」。适合谁?适合有 Java 基础、想找一个规则明确又能练手的后端项目的人,也适合做小程序商城、工具类应用、fatemaster.ai 排盘这类产品时,需要自己掌控排盘逻辑而不是调第三方接口的开发者。源码的核心价值,是把散落在古籍和口传里的排盘规则,翻译成可测试的 Java 方法。

2. 六爻排盘的规则底座:干支、五行与六亲怎么用 Java 表达

2.1 先定数据结构,再谈算法

排盘这件事,最怕一上来就写if-else堆规则。我一般会先把「一个卦」拆成几个不可变对象:Yao(爻)、Gua(卦)、Pan(盘)。Yao只需要三个字段:位置(初爻到上爻)、阴阳(0/1)、动静(静爻/动爻)。Gua持有六个Yao,外加卦名、卦宫、世应位置。Pan则是在Gua之上叠加时间维度:起卦时的年、月、日、时四柱,以及由此推导出的六亲、六神、旬空、月破、日破。

为什么强调不可变?因为排盘结果一旦生成,后续所有展示、分享、存档都应该是同一份数据。如果对象可变,很容易在「重新排盘」时把旧盘改脏。用 Java 的record或者final字段加构造器就能做到。下面是一个最小化的爻对象定义:

public record Yao(int position, int yinYang, boolean moving) { // position: 1~6,1 为初爻 // yinYang: 0 表示阴,1 表示阳 // moving: true 表示动爻(老阴或老阳) public Yao { if (position < 1 || position > 6) { throw new IllegalArgumentException("爻位必须在 1~6 之间"); } if (yinYang != 0 && yinYang != 1) { throw new IllegalArgumentException("阴阳只能用 0 或 1 表示"); } } }

这段代码没有玄学,只有约束。参数说明:position决定爻位,yinYang决定阴阳,moving决定是否发动。逻辑说明:构造器里做边界检查,避免后续排盘时出现「第七爻」这种脏数据。很多新手会忽略校验,结果在小程序端传参异常时,后端直接算出乱七八糟的卦。

2.2 干支与五行的映射表怎么落地

六爻排盘离不开干支。年、月、日、时各有一个天干一个地支,共八个字。Java 里不要用魔法字符串,而是用枚举加数组。天干十个、地支十二个,六十甲子循环。我一般会写一个GanZhi工具类,提供两个核心方法:根据公历日期推算日柱干支,以及根据年份推算年柱干支。月柱和时柱则依赖节气与时辰,这部分如果做完整版,需要引入节气表;如果只是排盘演示,可以先用简化规则,但要在代码里明确标注「简化版,未处理节气交接」。

public enum TianGan { JIA("甲"), YI("乙"), BING("丙"), DING("丁"), WU("戊"), JI("己"), GENG("庚"), XIN("辛"), REN("壬"), GUI("癸"); private final String name; TianGan(String name) { this.name = name; } public String getName() { return name; } public static TianGan fromIndex(int index) { return values()[Math.floorMod(index, 10)]; } }

地支同理,十二个枚举值。五行则用另一个枚举WuXing,并给每个天干、地支绑定五行属性。六亲(父母、兄弟、子孙、妻财、官鬼)的推导规则是:以卦宫五行为「我」,看各爻地支五行与「我」的生克关系。生我者父母,我生者子孙,克我者官鬼,我克者妻财,比和者兄弟。这段逻辑用switch或映射表都能写,关键是把规则集中在一个类里,不要散落在各个 Service 中。

2.3 装卦与世应:规则固定,但顺序不能乱

装卦是指给六爻配上地支、六亲、六神。六神(青龙、朱雀、勾陈、腾蛇、白虎、玄武)的起始位置由日干决定:甲乙日起青龙,丙丁日起朱雀,戊日起勾陈,己日起腾蛇,庚辛日起白虎,壬癸日起玄武。然后按爻位从初爻到上爻依次排列。世应位置则由卦宫和卦序决定,八宫卦各有固定的世爻位置,比如本宫卦世在六爻,一世卦世在初爻,等等。

这部分最容易翻车的地方是顺序。六神要按爻位从下往上排,但很多人写循环时从 0 开始却忘了初爻对应索引 0。世应如果查表,表要写全六十四卦,不能只写八个宫的首卦。我一般会用一个Map<String, Integer>存世爻位置,键是卦名,值是爻位。这样虽然「笨」,但可读性和可维护性最好,也方便后续对照古籍校验。

3. 起卦与排盘的核心算法:从摇卦到完整盘面的 Java 实现

3.1 摇卦模拟:随机数怎么用才不「玄学」

小程序端通常提供两种起卦方式:手动输入六次摇动结果,或者点击按钮模拟摇卦。模拟摇卦的本质是生成六个爻,每个爻有三种可能:老阴(三背)、少阳(两背一字)、少阴(两字一背)、老阳(三字)。用 Java 实现时,可以用ThreadLocalRandom生成 0~3 的随机数,映射到四种结果。注意:老阴和老阳是动爻,会变卦;少阳和少阴是静爻,不变。

public static Yao randomYao(int position) { int r = ThreadLocalRandom.current().nextInt(4); // 0: 老阴(动), 1: 少阳(静), 2: 少阴(静), 3: 老阳(动) return switch (r) { case 0 -> new Yao(position, 0, true); case 1 -> new Yao(position, 1, false); case 2 -> new Yao(position, 0, false); case 3 -> new Yao(position, 1, true); default -> throw new IllegalStateException("随机数越界"); }; }

逻辑说明:nextInt(4)返回 0 到 3,等概率。参数说明:position由调用方传入 1 到 6。这段代码没有用Math.random(),因为ThreadLocalRandom在并发环境下更稳,小程序后端如果同时处理多个起卦请求,不会因为随机数种子竞争导致结果异常。另外,不要用SecureRandom,排盘不需要密码学强度,用它会拖慢响应。

3.2 变卦与动爻:老阴老阳怎么处理

六爻排盘里,动爻是重点。老阴(阴动)变阳,老阳(阳动)变阴。变卦就是把所有动爻取反后得到的新卦。Java 实现时,先根据六个Yao确定本卦卦名,再根据动爻生成变卦卦名。卦名的确定依赖上下卦的组合:初、二、三爻为下卦,四、五、上爻为上卦。八卦各有三爻二进制表示,比如乾为 111,坤为 000,震为 001(从下往上读)。用Map<Integer, String>存八卦索引到卦名的映射,再组合成六十四卦名。

public static String guaName(List<Yao> yaos) { int lower = toBinary(yaos.subList(0, 3)); // 初、二、三 int upper = toBinary(yaos.subList(3, 6)); // 四、五、上 return BA_GUA_MAP.get(lower) + BA_GUA_MAP.get(upper); } private static int toBinary(List<Yao> three) { int result = 0; for (int i = 0; i < 3; i++) { if (three.get(i).yinYang() == 1) { result |= (1 << i); } } return result; }

逻辑说明:toBinary把三爻的阴阳转成 0~7 的整数,低位对应初爻。参数说明:yaos必须按初爻到上爻的顺序传入。注意:八卦的二进制顺序各家略有差异,但只要你自己的映射表一致,排出来的卦名就是对的。我一般会在单元测试里把六十四卦全跑一遍,对照古籍确认无误。

3.3 六亲、六神、旬空的批量计算

当本卦和变卦都确定后,就要给每一爻配上六亲、六神,并计算旬空。旬空由日柱决定:甲子旬中戌亥空,甲戌旬中申酉空,以此类推。Java 里可以用一个Map<String, String[]>存旬空表,键是旬首,值是空亡的两个地支。六亲的计算前面说过,以卦宫五行为基准。六神则按日干起,顺序固定。

这部分代码量不大,但顺序敏感。我一般会写一个PanBuilder类,按固定步骤执行:1)确定本卦卦宫;2)装地支;3)定六亲;4)排六神;5)算旬空;6)标世应;7)处理动爻与变卦。每一步都输出中间结果,方便调试。如果最后盘面不对,可以逐层排查是哪一步错了,而不是对着最终结果发呆。

4. 小程序端与 Java 后端的接口设计:请求、响应与状态管理

4.1 起卦接口的入参与出参

小程序端发起卦请求时,通常只传一个sessionId或者用户标识,后端负责生成六个爻并返回完整盘面。如果支持手动输入,则传入六个爻的阴阳和动静。接口设计要遵循「前端轻、后端重」的原则,因为排盘规则复杂,放在后端更容易统一维护和升级。下面是一个典型的请求体:

{ "mode": "auto", "yaos": [] }

mode为auto时,后端随机生成;为manual时,yaos数组必须包含六个对象,每个对象有yinYang和moving字段。响应体则包含本卦、变卦、六爻详情、四柱、旬空、六神等。注意:不要在小程序端做排盘计算,一是 JavaScript 处理干支容易出错,二是规则更新后需要发版,而小程序发版审核周期不可控。

4.2 用 Spring Boot 暴露排盘服务

Java 后端我一般用 Spring Boot,因为生态成熟,写 REST 接口快。一个最小的 Controller 如下:

@RestController @RequestMapping("/api/divination") public class DivinationController { private final PanService panService; public DivinationController(PanService panService) { this.panService = panService; } @PostMapping("/cast") public PanResponse cast(@RequestBody CastRequest request) { List<Yao> yaos = request.mode().equals("auto") ? YaoGenerator.randomSix() : request.yaos().stream() .map(y -> new Yao(y.position(), y.yinYang(), y.moving())) .toList(); Pan pan = panService.buildPan(yaos, LocalDateTime.now()); return PanResponse.from(pan); } }

逻辑说明:cast方法根据mode决定是随机起卦还是手动起卦,然后调用PanService构建盘面。参数说明:CastRequest和PanResponse用 record 定义,字段与前端约定一致。注意:LocalDateTime.now()取的是服务器时间,如果用户分布在不同时区,要考虑时区转换,否则日柱可能算错。我一般会要求前端传一个timezone字段,或者统一用东八区。

4.3 会话与状态:排盘结果要不要存

如果只是即时排盘,可以不存数据库,直接返回。但如果用户想「保存卦例」或者「历史记录」,就需要持久化。我一般会存三张表:user、divination_record、yao_detail。divination_record存盘面主信息(起卦时间、本卦、变卦、四柱),yao_detail存六爻的明细。这样查询历史时不用反序列化大 JSON,也方便做统计。注意:不要用 Redis 存排盘结果,因为排盘数据量小但要求持久,Redis 重启可能丢数据,而且历史记录需要长期保存。

5. 避坑与排查:六爻排盘源码里最容易翻车的 5 个地方

5.1 日柱算错,整个盘全废

现象:排出来的六亲、旬空、六神全不对,但卦名是对的。原因:日柱干支推算错误,导致后续所有依赖日柱的规则都错。解决:单独写一个DayGanZhiTest,用已知公历日期对照万年历验证。注意:公历转日柱有公式,但闰年、月份天数容易算错,建议直接用java.time.LocalDate的toEpochDay()做基准偏移,再取模六十甲子。

5.2 动爻变卦时阴阳取反搞混

现象:变卦卦名不对,或者动爻数量对不上。原因:老阴是阴动,变阳;老阳是阳动,变阴。有人把「动」直接当成「取反」,但静爻不能取反。解决:在Yao里明确moving字段,变卦生成时只对moving == true的爻取反,其余保持不变。

5.3 六神起始位置记错

现象:六神顺序整体偏移一位。原因:日干对应的六神起始规则记混,比如把「甲乙起青龙」记成「甲己起青龙」。解决:把规则写成常量表,并在代码注释里标明出处。测试时用五个不同日干各跑一遍,检查初爻六神是否符合预期。

5.4 旬空表不完整

现象:某些日期排出来的旬空为空。原因:旬空表只写了几个旬,没写全。解决:六十甲子共六旬,每旬十个干支,空亡两个地支。把六旬全部写进Map,键用旬首干支,值用两个地支字符串。测试时遍历六十天,确保每天都能查到旬空。

5.5 小程序端传参顺序颠倒

现象:手动起卦时,卦象和用户输入完全相反。原因:小程序端习惯从上往下展示爻,但六爻规则是初爻在下。前端传数组时如果按从上到下,后端按从下到上解析,就会颠倒。解决:接口文档里明确「数组顺序为初爻到上爻」,并在后端做一次校验,如果发现顺序可疑(比如第一个元素是上爻),可以拒绝或自动反转。我一般会在响应里回显爻位,方便前端核对。

6. 进阶技巧:用单元测试锁死排盘规则,让源码可维护

排盘规则一旦写错,用户可能不会立刻发现,但懂行的人一眼就能看出问题。所以我在写完核心算法后,一定会补一套单元测试,把「已知卦例」固化下来。比如手动构造六个爻,断言卦名、世应、六亲、旬空全部符合预期。这样以后改代码,只要测试还绿,就说明没破坏原有规则。

@Test void testQianGua() { List<Yao> yaos = List.of( new Yao(1, 1, false), new Yao(2, 1, false), new Yao(3, 1, false), new Yao(4, 1, false), new Yao(5, 1, false), new Yao(6, 1, false) ); Pan pan = panService.buildPan(yaos, LocalDateTime.of(2025, 1, 1, 12, 0)); assertEquals("乾为天", pan.benGua().name()); assertEquals(6, pan.benGua().shiYaoPosition()); assertEquals(3, pan.benGua().yingYaoPosition()); }

逻辑说明:六个阳爻静爻组成乾为天,世在上爻(位置 6),应在三爻(位置 3)。参数说明:LocalDateTime固定一个时间,保证日柱、旬空可复现。注意:测试里的时间要选一个已知日柱的日期,否则断言旬空时会依赖外部万年历。我一般会选一个甲子日,这样旬空是戌亥,容易记。

另一个技巧是把排盘结果导出为 JSON 快照。每次修改规则后,跑一遍所有测试卦例,对比 JSON 差异。如果差异只出现在预期变更的字段,就说明改动可控;如果出现意外差异,就要回头检查。这个习惯帮我省了很多「改一处崩三处」的后悔药。

最后说一个我自己的教训:早期我为了图快,把六亲计算直接写在 Controller 里,结果后来想加一个「按六亲筛选爻」的功能,发现逻辑散落各处,改起来非常痛苦。后来重构成PanService加LiuQinCalculator,才把规则收拢。如果你也打算做六爻排盘小程序,建议一开始就把规则层和接口层分开,哪怕多写几个类,后面会轻松很多。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 9:06:52

OpenKnowledge:用 Markdown+Git+Skills 打通 AI Agent 知识库

1. 为什么需要把 Markdown 知识库和 AI Agent 连起来 我自己的知识库大概从三年前开始全面转向 Markdown&#xff0c;原因很简单&#xff1a;纯文本、可版本控制、跨平台、不绑定任何一家笔记软件。但真正让我头疼的问题&#xff0c;是最近一年 AI Agent 爆发之后出现的——我的…

作者头像 李华
网站建设 2026/10/27 9:06:21

小程序盲盒经济:技术实现与运营策略

1. 盲盒经济与小程序的化学反应 第一次接触"无限赏"这个概念是在去年的一次行业交流会上。当时一位做潮玩的朋友向我展示了他的小程序后台数据&#xff1a;单日UV突破10万&#xff0c;复购率高达35%。这个数字让我意识到&#xff0c;盲盒小程序的组合正在打开一个全新…

作者头像 李华
网站建设 2026/10/27 9:06:12

Safety Anchor:用几何瓶颈保障大模型微调安全

1. 这篇论文不是在“加护栏”&#xff0c;而是在模型训练的血管里埋监测探针 最近翻到一篇标题带点工业风的论文——《Safety Anchor: Defending Harmful Fine-tuning via Geometric Bottlenecks》。光看标题&#xff0c;“Safety Anchor”&#xff08;安全锚点&#xff09;听着…

作者头像 李华
网站建设 2026/10/27 9:05:35

数字人演化框架:动力学模型与遗传算法实践

1. 数字人演化框架的核心设计理念 数字人技术正从简单的形象模拟向具备自主演化能力的复杂系统进化。这个底层框架的核心在于构建一个能够模拟生命体完整生存周期的动力学模型&#xff0c;它不同于传统的静态数字人系统&#xff0c;而是引入了生物进化论中的自然选择机制和复杂…

作者头像 李华
网站建设 2026/10/27 9:05:23

AI Agent两条路线:对话型与执行型,四大产品实测对比

聊AI Agent聊了快两年&#xff0c;我最大的感受是&#xff1a;市面上的Agent产品&#xff0c;最终走向无非两条路。一条是把Agent塞进对话框里&#xff0c;让它更聪明地替你写文档、做总结、理思路&#xff0c;千问办公、豆包工作就是这条路线上的典型&#xff1b;另一条是把Ag…

作者头像 李华
网站建设 2026/10/27 9:05:19

大语言模型扩散重写器:面向本地部署的可控文本生成新范式

1. 这不是“把扩散模型搬进大语言模型”&#xff0c;而是重构生成逻辑的底层思维切换最近在好几个技术群和线下交流中&#xff0c;总有人问&#xff1a;“能不能直接把Stable Diffusion那套diffusion models的思想&#xff0c;塞进LLM里&#xff0c;让大语言模型也学会‘去噪’…

作者头像 李华