这是一个基于Python和Tkinter开发的六爻排盘程序,用于模拟传统的六爻起卦过程。程序具有图形界面,可以输入占问事项和时间,自动生成卦象并显示结果。

2. 核心功能

2.1 时间处理

  • 支持阳历时间输入(YYYY.MM.DD-HH:MM格式)
  • 自动转换为农历时间
  • 显示干支纪年、农历月日、时辰

2.2 卦象生成

  • 模拟三枚铜钱投掷
  • 生成六爻卦象
  • 识别变爻
  • 自动生成变卦

2.3 卦象解析

  • 支持64卦的识别和命名
  • 区分八纯卦(⚠标记)和其他卦象
  • 显示爻的变化

3. 技术实现

3.1 铜钱模拟

def coin_toss(self):
    tosses = [random.choice([0, 1]) for _ in range(3)]
    return tosses.count(1)
  • 使用random模块模拟铜钱正反面
  • 统计阳面(1)的数量确定爻的性质

3.2 爻的判定

def interpret_toss(self, toss_result):
    if toss_result == 1:    # 少阳
        return '▄▄▄▄▄▄▄▄▄▄', False
    elif toss_result == 2:  # 少阴
        return '▄▄▄▄  ▄▄▄▄', False  
    elif toss_result == 0:  # 老阴
        return '▄▄▄▄  ▄▄▄▄ x', True
    else:                   # 老阳
        return '▄▄▄▄▄▄▄▄▄▄ x', True
  • 1个阳面: 少阳(不变)
  • 2个阳面: 少阴(不变)
  • 0个阳面: 老阴(变阳)
  • 3个阳面: 老阳(变阴)

3.3 卦象编码

  • 使用6位二进制表示卦象
  • 阳爻记为1,阴爻记为0
  • 从下往上依次排列(初爻到上爻)

3.4 变卦处理

  • 记录变爻位置
  • 老阴变阳,老阳变阴
  • 生成新的卦象序列

4. 界面设计

4.1 输入区域

  • 占问事项输入框
  • 时间输入框(自动填入当前时间)
  • 起卦按钮

4.2 显示区域

  • 滚动文本框显示结果
  • 分段显示:
    • 占问信息
    • 时间信息
    • 主卦
    • 变卦(如有)

5. 数据结构

5.1 卦象存储

  • 使用字典存储64卦
  • 键:6位二进制字符串
  • 值:卦名

5.2 爻的表示

  • 阳爻: ▄▄▄▄▄▄▄▄▄▄
  • 阴爻: ▄▄▄▄ ▄▄▄▄
  • 变爻: 添加x标记

6. 扩展建议

  1. 添加卦象解释功能
  2. 支持卦象图形化显示
  3. 增加历史记录功能
  4. 添加卦象详细含义查询
  5. 支持多种起卦方法

7. 注意事项

  1. 时间输入格式需严格遵守
  2. 农历转换依赖外部库
  3. 变爻判断需注意顺序
  4. 卦象编码需注意方向

8. 全部代码

import random
import datetime
import tkinter as tk
from tkinter import scrolledtext
from lunarcalendar import Converter, Solar
 
 
class LiuYaoGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("六爻排盘神机")
        self.root.geometry("600x800")
        
        # 创建输入框和标签
        tk.Label(root, text="占问事宜:").pack(pady=5)
        self.question_entry = tk.Entry(root, width=50)
        self.question_entry.pack(pady=5)
        
        tk.Label(root, text="起卦时间 (格式如2024.05.29-21:56):").pack(pady=5)
        self.time_entry = tk.Entry(root, width=50)
        # 设置当前时间
        current_time = datetime.datetime.now().strftime("%Y.%m.%d-%H:%M")
        self.time_entry.insert(0, current_time)
        self.time_entry.pack(pady=5)
        
        # 创建开始按钮
        tk.Button(root, text="开始起卦", command=self.start_divination).pack(pady=10)
        
        # 创建文本显示区域
        self.result_text = scrolledtext.ScrolledText(root, width=50, height=30)
        self.result_text.pack(pady=10)

    def append_text(self, text):
        self.result_text.insert(tk.END, text + "\n")
        self.result_text.see(tk.END)

    def start_divination(self):
        # 清空显示区域
        self.result_text.delete(1.0, tk.END)
        
        # 获取输入内容
        question = self.question_entry.get()
        time_str = self.time_entry.get()
        
        self.append_text("-+"*10 + "  六爻排盘神机  " + "+-"*10)
        self.append_text(f"\n占问事宜:{question}\n")
        
        # 处理时间
        solar_date = self.parse_input(time_str)
        if solar_date:
            lunar_date = self.convert_to_lunar(solar_date)
            self.print_lunar_date(lunar_date, solar_date)
        
        # 生成卦象
        hexagram, mutations = self.generate_hexagram()
        
        # 显示主卦
        hexagram_name = self.get_hexagram_name(hexagram)
        self.append_text(f"\n主卦: {hexagram_name}")
        self.print_hexagram(hexagram)
        
        # 显示变卦
        if mutations:
            new_hexagram = self.generate_mutations(hexagram, mutations)
            new_hexagram_name = self.get_hexagram_name(new_hexagram)
            self.append_text(f"\n变卦: {new_hexagram_name}")
            self.print_hexagram(new_hexagram)
        
        self.append_text("\n" + "-+"*10 + "  六爻排盘神机  " + "+-"*10)

    # 将原有的函数方法转换为类方法
    def parse_input(self, user_input):
        try:
            date_part, time_part = user_input.split('-')
            year, month, day = map(int, date_part.split('.'))
            hour, minute = map(int, time_part.split(':'))
            return datetime.datetime(year, month, day, hour, minute)
        except ValueError as e:
            self.append_text(f"输入格式无效: {e}")
            return None

    def print_hexagram(self, hexagram):
        yao_labels = ["六爻", "五爻", "四爻", "三爻", "二爻", "初爻"]
        for i, yao in enumerate(hexagram[::-1]):
            self.append_text(f"{yao_labels[i]}: {yao}")

    def convert_to_lunar(self, solar_date):
        try:
            solar = Solar(solar_date.year, solar_date.month, solar_date.day)
            lunar = Converter.Solar2Lunar(solar)
            return lunar
        except ValueError as e:
            self.append_text(f"转换为阴历时出错: {e}")
            return None

    def get_chinese_hour(self, hour):
        chinese_hours = [
            "子时", "丑时", "丑时", "寅时", "寅时", "卯时", "卯时", "辰时", "辰时", "巳时", "巳时",
            "午时", "午时", "未时", "未时", "申时", "申时", "酉时", "酉时", "戌时", "戌时", "亥时", "亥时"
        ]
        return chinese_hours[hour]

    def get_ganzhi_year(self, year):
        tiangan = ["甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"]
        dizhi = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"]
        base_year = 4
        diff_years = year - base_year
        gan = tiangan[diff_years % 10]
        zhi = dizhi[diff_years % 12]
        return f"{gan}{zhi}年"

    def get_chinese_month(self, month, is_leap):
        chinese_months = [
            "正月", "二月", "三月", "四月", "五月", "六月",
            "七月", "八月", "九月", "十月", "冬月", "腊月"
        ]
        return ("闰" if is_leap else "") + chinese_months[month - 1]

    def get_chinese_day(self, day):
        chinese_days = [
            "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十",
            "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十",
            "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十"
        ]
        return chinese_days[day - 1]

    def print_lunar_date(self, lunar_date, solar_date):
        if lunar_date:
            chinese_hour = self.get_chinese_hour(solar_date.hour)
            chinese_year = self.get_ganzhi_year(lunar_date.year)
            chinese_month = self.get_chinese_month(lunar_date.month, lunar_date.isleap)
            chinese_day = self.get_chinese_day(lunar_date.day)
            self.append_text(f"\n起卦时间: {chinese_year} {chinese_month} {chinese_day} {chinese_hour}\n")

    def coin_toss(self):
        tosses = [random.choice([0, 1]) for _ in range(3)]
        return tosses.count(1)

    def interpret_toss(self, toss_result):
        if toss_result == 1:
            return '▄▄▄▄▄▄▄▄▄▄', False
        elif toss_result == 2:
            return '▄▄▄▄  ▄▄▄▄', False
        elif toss_result == 0:
            return '▄▄▄▄  ▄▄▄▄ x', True
        else:
            return '▄▄▄▄▄▄▄▄▄▄ x', True

    def generate_hexagram(self):
        hexagram = []
        mutations = []
        for i in range(6):
            toss_result = self.coin_toss()
            yao, is_mutation = self.interpret_toss(toss_result)
            hexagram.append(yao)
            if is_mutation:
                mutations.append((len(hexagram) - 1, yao))
        return hexagram, mutations

    def generate_mutations(self, hexagram, mutations):
        new_hexagram = hexagram[:]
        for yao_idx, yao in mutations:
            if yao == '▄▄▄▄  ▄▄▄▄ x':
                new_hexagram[yao_idx] = '▄▄▄▄▄▄▄▄▄▄'
            elif yao == '▄▄▄▄▄▄▄▄▄▄ x':
                new_hexagram[yao_idx] = '▄▄▄▄  ▄▄▄▄'
        return new_hexagram

    def get_hexagram_name(self, hexagram):
        hexagram_names = {
            '111111': '⚠乾为天',
            '111110': '天风姤',
            '111100': '天山遁',
            '111000': '天地否',
            '110000': '风地观',
            '100000': '山地剥',
            '101000': '火地晋',
            '101111': '火天大有',
            '011011': '⚠兑为泽',
            '011010': '泽水困',
            '011000': '泽地萃',
            '011100': '泽山咸',
            '010100': '水山蹇',
            '000100': '地山谦',
            '001100': '雷山小过',
            '001011': '雷泽归妹',
            '101101': '⚠离为火',
            '101100': '火山旅',
            '101110': '火风鼎',
            '101010': '火水未济',
            '100010': '山水蒙',
            '110010': '风水换',
            '111010': '天水讼',
            '111101': '天火同人',
            '001001': '⚠震为雷',
            '001000': '雷地豫',
            '001010': '雷水解',
            '001110': '雷风恒',
            '000110': '地风升',
            '010110': '水风井',
            '011110': '泽风大过',
            '011001': '泽雷随',
            '110110': '⚠巽为风',
            '110111': '风天小畜',
            '110101': '风火家人',
            '110001': '风雷益',
            '111001': '天雷无妄',
            '101001': '火雷噬嗑',
            '100001': '山雷颐',
            '100110': '山风蛊',
            '010010': '⚠坎为水',
            '010011': '水泽节',
            '010001': '水雷屯',
            '010101': '水火既济',
            '011101': '泽火革',
            '001101': '雷火丰',
            '000101': '地火明夷',
            '000010': '地水师',
            '100100': '⚠艮为山',
            '100101': '山火贲',
            '100111': '山天大畜',
            '100011': '山泽损',
            '101011': '火泽睽',
            '111011': '天泽履',
            '110011': '风泽中孚',
            '110100': '风山渐',
            '000000': '⚠坤为地',
            '000001': '地雷复',
            '000011': '地泽临',
            '000111': '地天泰',
            '001111': '雷天大壮',
            '011111': '泽天夬',
            '010111': '天水需',
            '010000': '水地比'
        }
        hexagram_code = ''.join(['1' if '▄▄▄▄▄▄▄▄▄▄' in yao else '0' for yao in hexagram])
        reversed_hexagram_code = hexagram_code[::-1]
        return hexagram_names.get(reversed_hexagram_code, '出错了!')

def main():
    root = tk.Tk()
    app = LiuYaoGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main()
Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐