周易占卦解卦程序
一、背景说明
上上周末看《易经》其封面大概是这么一张图(其实还有各卦对应的五行但一下找不到这样的图),想着为什么一个卦用三层表示呢,辗转反侧突然想到这就是二进制啊,需要三位才能表示八个数(000-111)。
然后又去看占卦解卦原理,感觉就是给定一个输入----经过一定的算法流转----给出一个输出,最后一想这就是一个典型的算法啊,完全可以写成一个程序而且感觉这也是一个比较有趣的事。
二、周易及相关
2.1 中华上下五千年,有一千年在干啥?
夏朝是公元前2070年建立的,到现在算下来也就四千年,有一千年在干啥?还有一千年是五帝时期,司马迁的史记就是从五帝开始的。不过这有明显的问题,五帝一千年那不得平均每个人活两百多岁?所以司马迁都说五帝的事迹太久远了多不可靠(“学者多称五帝,尚矣。”),更远的三皇就觉得更扯淡所以司马迁直接没记载了。
2.2 八卦是谁创建的?
八卦相传是三皇之一的人皇伏羲于卦台山所创。八卦分别是乾(qián)、坤(kūn)、震(zhèn)、巽(xùn)、坎(kǎn)、离(lí)、艮(gèn)、兑(duì)。
2.3 周易为什么有六十四卦?
周易六十四卦是周文王姬昌被纣王下狱时使用八卦叠加(8 * 8)推演出来的,这也正是司马迁说的“文王拘而演周易”。另外要注意的是虽然周文王做了很好的铺垫但真正攻灭商朝的是周武王姬发。
2.4 经常看到“周公解梦”之类的书,周公就是指周文王吗?
不是,不管是“周公解梦”中的周公还是哪里说的周公,一般指的都是周文王姬发的弟弟姬旦,因其爵位为公所以叫周公、周公旦。周公上马治军下马治国,“一年救乱,二年克殷,三年践奄,四年建侯卫,五年营成周,六年制礼乐,七年致政成王”,所以成了孔子等知识分子的偶像是个大大的名人。
2.4 易为什么是儒家经典?
儒家经典是四书五经,八卦是伏羲所创易是周文王推演所得,凭什么易被归为五经之一成了儒家经典?
周易、易经、易传是有区别的,他们的关系有很多说法,但按经是指儒家经典来看应该是,“易经 = 周易 + 易传”。周易是周文王所作,是六十四卦三百八十四爻的说明;易传是孔子解释周易所作;两者相加就成了五经之一的易经。其实这也不是很难理解,比如我们上学时买的文言文解析的书,文言文加现代文解释就成了一本新书。其实五经都是孔子整理、增删而成并不是孔子及其弟子从无到有写出来的。
当然易传对周易的解释不是文言文解释成现代文,而是把卦辞爻辞解释成儒家思想,比如周易说“今天利于爬山”,易传就说“年轻人就是好多看看祖国的大好山河才能强身健体、才能开拓眼界、才能更好报效国家”。所以才有人说易在孔子之前是本算命书,在孔子之后就成了一本哲学书。
2.5 易和道家有什么关系?
周易又不是你们儒家写的,你们儒家解释得我们道家就解释不得?我们道家觉得周易就是一本讲道的书,是道家经典,你知道吧。
三、占卦解卦原理
3.1 占卦原理
卜卦有两种方一,一种是易经中的"揲蓍法",比较合理但也比较复杂;另一种是西汉京房所创的铜钱法,操作比较简单,但按概率来说各卦出现的概率是不均等的所以不是和“揲蓍法”完全等价的方法。
我代码中用的是仿"揲蓍法",当然纯属娱乐,没有很讲究,也可能四不象。
参考:https://www.buyiju.com/fengshui/zhishi/10063.html
3.2 解卦原理
易经中没有说怎么解卦,代码中的解卦用的是朱熹总结的解法。
参考:http://blog.sina.com.cn/s/blog_5bdeff550102yo2s.html
四、占卦解卦程序
4.1 实例代码
github地址:https://github.com/PrettyUp/YI
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import random import datetime from yi_book import book class YiProgram(): def __init__(self): pass # 设置随机数种子,确保用户输入一样时,得到的随机数是一样的 def _set_random_seed(self, time_seed_str): def _transfer_str_to_time_seed(): user_input_str_bytes = time_seed_str.encode() inner_random_seed = 0 for tmp_byte in user_input_str_bytes: inner_random_seed += tmp_byte return inner_random_seed random_seed = _transfer_str_to_time_seed() random.seed(random_seed) # 执行一轮变化 def _exec_one_transfer(self, cosmos_count): # 第一步,将四十九颗棋子随机分为左右两组,象征混沌初开,天地一分为二,一边为天,一边为地。 cosmos_list = [1] * cosmos_count divide_index = random.randint(int(cosmos_count/3), int(cosmos_count/3)*2) sky_list = cosmos_list[:divide_index] land_list = cosmos_list[divide_index:] # 第二步,有天有地就该有人,所以任意拿掉一组中的一个棋子,这颗棋子便为人。然后形成三才。 person_point = random.randint(0,cosmos_count) if person_point < divide_index: sky_list.pop() else: land_list.pop() # 第三步,以象征天的那组棋子数除以四,获得余数,如果整除则余数改为4(这里的四象征着一年四季)。 sky_remainder = len(sky_list) % 4 if sky_remainder == 0: sky_remainder = 4 # sky_list = sky_list[:-sky_remainder] # 第四步,对象征地的那组进行同样的操作。 land_remainder = len(land_list) % 4 if land_remainder == 0: land_remainder = 4 # land_list = land_list[:-land_remainder] # 第五步,减去象征人的棋子及两组的余数,获取剩余的棋子数 remove_count = 1 + sky_remainder + land_remainder cosmos_count = cosmos_count - remove_count return cosmos_count # 递规执行三轮变化获取剩余的棋子数,即一爻 def _gen_one_symbol(self, cosmos_count=49, transfer_index=0): cosmos_count = self._exec_one_transfer(cosmos_count) transfer_index += 1 if transfer_index >= 3: return cosmos_count else: return self._gen_one_symbol(cosmos_count=cosmos_count, transfer_index=transfer_index) # 获取六爻,组成本卦 def _gen_origin_hexagram(self): six_symbol_list = [] for symbol_index in range(6): tmp_symbol = int(self._gen_one_symbol() / 4) six_symbol_list.append(tmp_symbol) return six_symbol_list # 根据本卦获取变卦 def _gen_support_hexagram(self, origin_hexagram): support_hexagram = [] for tmp_value in origin_hexagram: if tmp_value == 6: tmp_value = 9 elif tmp_value == 9: tmp_value = 6 support_hexagram.append(tmp_value) return support_hexagram # 分析变爻数及变爻下标列表 def _get_turn_symbol_count_and_index_list(self, origin_hexagram, support_hexagram): turn_symbol_count = 0 turn_symbol_index_list = [] not_turn_symbol_index_list = [] for index in range(len(origin_hexagram)): if origin_hexagram[index] != support_hexagram[index]: turn_symbol_count += 1 turn_symbol_index_list.append(index) else: not_turn_symbol_index_list.append(index) return turn_symbol_count,turn_symbol_index_list,not_turn_symbol_index_list # 偶数为阴,奇数为阳 def _get_hexagram_dict_key(self, hexagram): hexagram_dict_key = "" for tmp_value in hexagram: hexagram_dict_key += str(tmp_value % 2) return hexagram_dict_key # 解卦 def _parser_hexagram(self, origin_hexagram, support_hexagram): main_indicate = "" support_indicate = "" turn_symbol_desc = "" origin_hexagram_dict_key = self._get_hexagram_dict_key(origin_hexagram) support_hexagram_dict_key = self._get_hexagram_dict_key(support_hexagram) turn_symbol_count,turn_symbol_index_list,not_turn_symbol_index_list = self._get_turn_symbol_count_and_index_list(origin_hexagram, support_hexagram) # 六爻皆不变者,占本卦卦辞 if turn_symbol_count == 0: turn_symbol_desc = "六爻皆不变者,占本卦卦辞。" main_indicate = book[origin_hexagram_dict_key]["indicate"][0] # 一爻变者,以本卦变爻之辞占 elif turn_symbol_count == 1: turn_symbol_desc = "一爻变者,以本卦变爻之辞占。" main_indicate = book[origin_hexagram_dict_key]["indicate"][turn_symbol_index_list[0]+1] # 二爻变者,则以本卦二变爻之辞占,而以上爻之辞为主 elif turn_symbol_count == 2: turn_symbol_desc = "二爻变者,则以本卦二变爻之辞占,而以上爻之辞为主。" main_indicate = book[origin_hexagram_dict_key]["indicate"][turn_symbol_index_list[1]+1] support_indicate = book[origin_hexagram_dict_key]["indicate"][turn_symbol_index_list[0]+1] # 三爻变者,占本卦及之卦的卦辞,而以本卦为主 elif turn_symbol_count == 3: turn_symbol_desc = "三爻变者,占本卦及之卦的卦辞,而以本卦为主。" main_indicate = book[origin_hexagram_dict_key]["indicate"][0] support_indicate = book[support_hexagram_dict_key]["indicate"][0] # 四爻变者,以之卦中二不变之爻辞占,以下爻为主 elif turn_symbol_count == 4: turn_symbol_desc = "四爻变者,以之卦中二不变之爻辞占,以下爻为主。" main_indicate = book[origin_hexagram_dict_key]["indicate"][not_turn_symbol_index_list[0]+1] support_indicate = book[origin_hexagram_dict_key]["indicate"][not_turn_symbol_index_list[1]+1] # 五爻变者,以之卦中不变爻的爻辞占 elif turn_symbol_count == 5: turn_symbol_desc = "五爻变者,以之卦中不变爻的爻辞占。" main_indicate = book[origin_hexagram_dict_key]["indicate"][not_turn_symbol_index_list[0]+1] # 六爻皆变者,以乾坤二用之辞占,并参考其之卦卦辞 elif turn_symbol_count == 6: turn_symbol_desc = "六爻皆变者,以乾坤二用之辞占,并参考其之卦卦辞。" main_indicate = book[origin_hexagram_dict_key]["indicate"][7] support_indicate = book[support_hexagram_dict_key]["indicate"][0] return turn_symbol_desc,main_indicate,support_indicate def main_logic_new(self): user_wish = input("请输入你所求之事:") user_pray = input(f"请输入你的祈祷:") today = datetime.datetime.now().__format__("%Y%m%d") time_seed_str = user_wish + user_pray + today # 设置随机数种子,确保当天同样的输出得到的结果是一样的 self._set_random_seed(time_seed_str) print("\n稍等,正在计算卦象...") # 生成本卦 origin_hexagram = self._gen_origin_hexagram() # 计算变卦 support_hexagram = self._gen_support_hexagram(origin_hexagram) # 本卦对应的内容的key origin_hexagram_dict_key = self._get_hexagram_dict_key(origin_hexagram) # 变卦对应的内容的key support_hexagram_dict_key = self._get_hexagram_dict_key(support_hexagram) print(f"本卦:{origin_hexagram}--{book[origin_hexagram_dict_key]['name']}--{book[origin_hexagram_dict_key]['come_from']}\n" f"变卦:{support_hexagram}--{book[support_hexagram_dict_key]['name']}--{book[support_hexagram_dict_key]['come_from']}") print("\n稍等,正在解卦...") # 解卦 turn_symbol_desc, main_indicate, support_indicate = self._parser_hexagram(origin_hexagram, support_hexagram) print(f"说明:{turn_symbol_desc}\n" f"主预言:{main_indicate}\n" f"辅预言:{support_indicate}") if __name__ == "__main__": obj = YiProgram() obj.main_logic_new()