C#: 生辰八字五行計算算法

最近偶有機緣接觸到八卦五行,有個校友在做紫微斗數,於是乎就想做個計算生辰八字五行算法的C#代碼,說到底占卜命理這種理論筆者覺得最終還是基於統計學的,這個可能有很多學派很多師傅有不同的理論,不過算生辰八字還算是通用的,不過不能亂算,筆者最不喜歡的就是搞個不靠譜的誤人子弟,於是乎研究了一圈,發現有篇潘愛民寫的還算比較可靠,但是是基於c語言的,於是筆者在這基礎上寫了個C#版的,本着源於網絡回饋網絡的精神下面是C#改寫的代碼,望大家交流,有其他占卜相關的算法也可以一起研究,其實這和大數據還真的能結合一起。

    public class BaziAlgorithm
    {
        //==================================
        //以下爲http://blog.csdn.net/panaimin/article/details/8544489
        //計算五行


        const string TianGan = "甲乙丙丁戊己庚辛壬癸";
        const string DiZhi = "子醜寅卯辰巳午未申酉戌亥";


        public bool CheckBazi(string bazi)
        {


            int baziLen;


            int i, j;






            baziLen = bazi.Length;


            if (baziLen != 6 && baziLen != 8) return false;






            for (i = 0; i < baziLen;)
            {


                char ch = bazi[i];


                for (j = 0; j < 10; j++)


                    if (ch == TianGan[j]) break;


                if (j >= 10) return false;


                i++;






                ch = bazi[i];


                for (j = 0; j < 12; j++)


                    if (ch == DiZhi[j]) break;


                if (j >= 12) return false;


                i++;


            }






            return true;


        }






        /*


        根據出生日子的天干,通過下表來查算時辰干支:


        時辰干支查算表


        時間時辰                             五行紀日干支


                               甲己     乙庚     丙辛     丁壬     戊癸






        23-01 子/水           甲子     丙子     戊子     庚子     壬子


        01-03 醜/土           乙丑     丁丑     己丑     辛丑     癸丑


        03-05 寅/木           丙寅     戊寅     庚寅     壬寅     甲寅


        05-07 卯/木           丁卯     己卯     辛卯     癸卯     乙卯


        07-09 辰/土           戊辰     庚辰     壬辰     甲辰     丙辰


        09-11 巳/火           己巳     辛巳     癸巳     己巳     丁巳


        11-13 午/火           庚午     壬午     甲午     丙午     戊午


        13-15 未/土           辛未     癸未     乙未     丁未     己未


        15-17 申/金           壬申     甲申     丙申     戊申     庚申


        17-19 酉/金           癸酉     乙酉     丁酉     己酉     辛酉


        19-21 戊/土           甲戌     丙戌     戊戌     庚戌     壬戌


        21-23 亥/水           乙亥     丁亥     己亥     辛亥     癸亥






        */


        string[][] cTimeGanZhi_Table = new string[12][]


{


        new string[] {"甲子","丙子","戊子","庚子","壬子"},


        new string[] {"乙丑","丁丑","己丑","辛丑","癸丑"},


        new string[] {"丙寅","戊寅","庚寅","壬寅","甲寅"},


        new string[] {"丁卯","己卯","辛卯","癸卯","乙卯"},


        new string[] {"戊辰","庚辰","壬辰","甲辰","丙辰"},


        new string[] {"己巳","辛巳","癸巳","己巳","丁巳"},


        new string[] {"庚午","壬午","甲午","丙午","戊午"},


        new string[] {"辛未","癸未","乙未","丁未","己未"},


        new string[] {"壬申","甲申","丙申","戊申","庚申"},


        new string[] {"癸酉","乙酉","丁酉","己酉","辛酉"},


        new string[] {"甲戌","丙戌","戊戌","庚戌","壬戌"},


        new string[] {"乙亥","丁亥","己亥","辛亥","癸亥"}


};






        static string sBuf;        // 用作八字結果緩衝區






        // 根據出生年月日的干支計算時辰干支


        // 輸入參數:bazi,年月日的干支,即八字中的前六個字


        // 輸入參數:hour,出生時間的小時數,-1~22


        // 輸出結果:八字字符串,Unicode編碼


        public string ComputeTimeGan(string bazi, int hour)


        {
            if (hour > 22) hour -= 24;
            char dayGan = bazi[4];






            int indexX, indexY;






            int i;


            for (i = 0; i < 10; i++)


                if (dayGan == TianGan[i]) break;


            if (i >= 10) return "";


            indexX = i;


            if (indexX >= 5) indexX -= 5;


            indexY = (hour + 1) / 2;






            sBuf = bazi;


            sBuf += cTimeGanZhi_Table[indexY][indexX];






            return sBuf;


        }






        /*


        十二月份天干強度表


        生月\四柱天干        甲              乙              丙              丁              戊              己              庚              辛              壬              癸


        子月                            1.2             1.2             1.0             1.0             1.0             1.0             1.0             1.0             1.2             1.2


        丑月                            1.06 1.06 1.0             1.0             1.1             1.1             1.14 1.14 1.1             1.1


        寅月                            1.14 1.14 1.2             1.2             1.06 1.06 1.0             1.0             1.0             1.0


        卯月                            1.2             1.2             1.2             1.2             1.0             1.0             1.0             1.0             1.0             1.0


        辰月                            1.1             1.1             1.06 1.06 1.1             1.1             1.1             1.1             1.04 1.04


        巳月                            1.0             1.0             1.14 1.14 1.14 1.14 1.06 1.06 1.06 1.06


        午月                            1.0             1.0             1.2             1.2             1.2             1.2             1.0             1.0             1.0             1.0


        未月                            1.04 1.04 1.1             1.1             1.16 1.16 1.1             1.1             1.0             1.0


        申月                            1.06 1.06 1.0             1.0             1.0             1.0             1.14 1.14 1.2             1.2


        酉月                            1.0             1.0             1.0             1.0             1.0             1.0             1.2             1.2             1.2             1.2


        戌月                            1.0             1.0             1.04 1.04 1.14 1.14 1.16 1.16 1.06 1.06


        亥月                            1.2             1.2             1.0             1.0             1.0             1.0             1.0             1.0             1.14 1.14


        */






        double[][] TianGan_Strength = new double[12][]


        {


        new double[] {1.2, 1.2,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.2,  1.2},


         new double[]{1.06,        1.06,         1.0,  1.0,  1.1,  1.1,  1.14,         1.14,         1.1,  1.1},


        new double[] {1.14,        1.14,         1.2,  1.2,  1.06,         1.06,         1.0,  1.0,  1.0,  1.0},


        new double[] {1.2, 1.2,  1.2,  1.2,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0},


        new double[] {1.1, 1.1,  1.06,         1.06,         1.1,  1.1,  1.1,  1.1,  1.04,         1.04},


        new double[] {1.0, 1.0,  1.14,         1.14,         1.14,         1.14,         1.06,         1.06,         1.06,         1.06},


        new double[] {1.0, 1.0,  1.2,  1.2,  1.2,  1.2,  1.0,  1.0,  1.0,  1.0},


        new double[] {1.04,        1.04,         1.1,  1.1,  1.16,         1.16,         1.1,  1.1,  1.0,  1.0},


        new double[] {1.06,        1.06,         1.0,  1.0,  1.0,  1.0,  1.14,         1.14,         1.2,  1.2},


        new double[] {1.0, 1.0,  1.0,  1.0,  1.0,  1.0,  1.2,  1.2,  1.2,  1.2},


        new double[] {1.0, 1.0,  1.04,         1.04,         1.14,         1.14,         1.16,         1.16,         1.06,         1.06},


        new double[] {1.2, 1.2,  1.0,  1.0,  1.0,  1.0,  1.0,  1.0,  1.14,         1.14}


        };






        /*


        十二月份地支強度表






                                生月       子月         丑月         寅月         卯月         辰月         巳月         午月         未月         申月         酉月         戌月         亥月        


        地支         支藏


        子              癸                       1.2             1.1             1.0             1.0             1.04 1.06 1.0             1.0             1.2             1.2             1.06 1.14


        醜              癸                       0.36 0.33 0.3             0.3             0.312        0.318        0.3             0.3             0.36 0.36 0.318        0.342


        醜              辛                       0.2             0.228        0.2             0.2             0.23 0.212        0.2             0.22 0.228        0.248        0.232        0.2           


        醜              己                       0.5             0.55 0.53 0.5             0.55 0.57 0.6             0.58 0.5             0.5             0.57 0.5            


        寅              丙                       0.3             0.3             0.36 0.36 0.318        0.342        0.36 0.33 0.3             0.3             0.342        0.318       


        寅              甲                       0.84 0.742        0.798        0.84 0.77 0.7             0.7             0.728        0.742        0.7             0.7             0.84


        卯              乙                       1.2             1.06 1.14 1.2             1.1             1.0             1.0             1.04 1.06 1.0             1.0             1.2            


        辰              乙                       0.36 0.318        0.342        0.36 0.33 0.3             0.3             0.312        0.318        0.3             0.3             0.36


        辰              癸                       0.24 0.22 0.2             0.2             0.208        0.2             0.2             0.2             0.24 0.24 0.212        0.228       


        辰              戊                       0.5             0.55 0.53 0.5             0.55 0.6             0.6             0.58 0.5             0.5             0.57 0.5            


        巳              庚                       0.3             0.342        0.3             0.3             0.33 0.3             0.3             0.33 0.342        0.36 0.348        0.3            


        巳              丙                       0.7             0.7             0.84 0.84 0.742        0.84 0.84 0.798        0.7             0.7             0.728        0.742       


        午              丁                       1.0             1.0             1.2             1.2             1.06 1.14 1.2             1.1             1.0             1.0             1.04 1.06


        未              丁                       0.3             0.3             0.36 0.36 0.318        0.342        0.36 0.33 0.3             0.3             0.312        0.318       


        未              乙                       0.24 0.212        0.228        0.24 0.22 0.2             0.2             0.208        0.212        0.2             0.2             0.24


        未              己                       0.5             0.55 0.53 0.5             0.55 0.57 0.6             0.58 0.5             0.5             0.57 0.5            


        申              壬                       0.36 0.33 0.3             0.3             0.312        0.318        0.3             0.3             0.36 0.36 0.318        0.342       


        申              庚                       0.7             0.798        0.7             0.7             0.77 0.742        0.7             0.77 0.798        0.84 0.812        0.7            


        酉              辛                       1.0             1.14 1.0             1.0             1.1             1.06 1.0             1.1             1.14 1.2             1.16 1.0            


        戌              辛                       0.3             0.342        0.3             0.3             0.33 0.318        0.3             0.33 0.342        0.36 0.348        0.3            


        戌              丁                       0.2             0.2             0.24 0.24 0.212        0.228        0.24 0.22 0.2             0.2             0.208        0.212       


        戌              戊                       0.5             0.55 0.53 0.5             0.55 0.57 0.6             0.58 0.5             0.5             0.57 0.5            


        亥              甲                       0.36 0.318        0.342        0.36 0.33 0.3             0.3             0.312        0.318        0.3             0.3             0.36


        亥              壬                        0.84 0.77 0.7             0.7             0.728        0.742        0.7             0.7             0.84 0.84 0.724        0.798       


        */


        struct ZISTRENGTH
        {


            public char diZhi;


            public char zhiCang;


            public double[] strength;


            public ZISTRENGTH(char a, char b, double[] c)
            {
                diZhi = a; zhiCang = b; strength = c;
            }


        };




        ZISTRENGTH[] DiZhi_Strength = new ZISTRENGTH[]


        {


        new ZISTRENGTH ('子', '癸', new double[] {1.2,1.1, 1.0, 1.0,        1.04, 1.06, 1.0,1.0, 1.2, 1.2, 1.06, 1.14}),


         new ZISTRENGTH('醜', '癸', new double[] {0.36,0.33, 0.3, 0.3, 0.312, 0.318, 0.3, 0.3, 0.36, 0.36, 0.318, 0.342}),


         new ZISTRENGTH('醜', '辛', new double[] {0.2,0.228, 0.2, 0.2, 0.23, 0.212, 0.2,         0.22,0.228, 0.248, 0.232, 0.2}),


         new ZISTRENGTH('醜', '己',new double[]  {0.5,0.55, 0.53, 0.5, 0.55, 0.57, 0.6, 0.58, 0.5, 0.5, 0.57, 0.5}),


         new ZISTRENGTH('寅', '丙', new double[] {0.3,0.3, 0.36, 0.36, 0.318, 0.342, 0.36, 0.33, 0.3, 0.3, 0.342, 0.318}),


         new ZISTRENGTH('寅', '甲',new double[]  {0.84,0.742, 0.798, 0.84, 0.77, 0.7, 0.7, 0.728, 0.742, 0.7, 0.7, 0.84}),


         new ZISTRENGTH('卯', '乙', new double[] {1.2,1.06, 1.14, 1.2, 1.1, 1.0, 1.0, 1.04, 1.06, 1.0, 1.0, 1.2}),


         new ZISTRENGTH('辰', '乙',new double[]  {0.36,0.318, 0.342, 0.36, 0.33, 0.3, 0.3, 0.312, 0.318, 0.3, 0.3, 0.36}),


         new ZISTRENGTH('辰', '癸', new double[] {0.24,0.22,  0.2, 0.2, 0.208, 0.2, 0.2, 0.2,0.24, 0.24, 0.212, 0.228}),


         new ZISTRENGTH('辰', '戊',new double[]  {0.5,0.55, 0.53, 0.5, 0.55, 0.6, 0.6, 0.58, 0.5, 0.5, 0.57, 0.5}),


        new ZISTRENGTH('巳', '庚', new double[] {0.3,0.342, 0.3, 0.3, 0.33, 0.3, 0.3, 0.33, 0.342, 0.36, 0.348, 0.3}),


         new ZISTRENGTH('巳', '丙', new double[] {0.7,0.7, 0.84, 0.84, 0.742, 0.84, 0.84, 0.798, 0.7, 0.7, 0.728, 0.742}),


         new ZISTRENGTH('午', '丁', new double[] {1.0,1.0, 1.2, 1.2, 1.06, 1.14, 1.2, 1.1, 1.0, 1.0, 1.04, 1.06}),


         new ZISTRENGTH('未', '丁', new double[] {0.3,0.3, 0.36, 0.36, 0.318, 0.342, 0.36, 0.33, 0.3, 0.3, 0.312, 0.318}),


         new ZISTRENGTH('未', '乙',new double[]  {0.24,0.212, 0.228, 0.24, 0.22, 0.2, 0.2, 0.208, 0.212, 0.2, 0.2, 0.24}),


        new ZISTRENGTH('未', '己', new double[] {0.5,0.55, 0.53, 0.5, 0.55, 0.57, 0.6, 0.58, 0.5, 0.5, 0.57, 0.5}),


         new ZISTRENGTH('申', '壬', new double[] {0.36,0.33, 0.3, 0.3, 0.312, 0.318, 0.3, 0.3, 0.36, 0.36, 0.318, 0.342}),


         new ZISTRENGTH('申', '庚',new double[]  {0.7,0.798, 0.7, 0.7, 0.77, 0.742, 0.7, 0.77, 0.798, 0.84, 0.812, 0.7}),


         new ZISTRENGTH('酉', '辛',new double[]  {1.0,1.14, 1.0, 1.0, 1.1, 1.06, 1.0, 1.1, 1.14, 1.2, 1.16, 1.0}),


         new ZISTRENGTH('戌', '辛',new double[]  {0.3,0.342, 0.3, 0.3, 0.33, 0.318, 0.3, 0.33, 0.342, 0.36, 0.348, 0.3}),


         new ZISTRENGTH('戌', '丁', new double[] {0.2,0.2, 0.24, 0.24, 0.212, 0.228, 0.24, 0.22, 0.2, 0.2, 0.208, 0.212}),
         new ZISTRENGTH('戌', '戊',new double[]  {0.5,0.55, 0.53, 0.5, 0.55, 0.57, 0.6, 0.58, 0.5, 0.5, 0.57, 0.5}),
         new ZISTRENGTH('亥', '甲',new double[]  {0.36,0.318, 0.342, 0.36, 0.33, 0.3, 0.3, 0.312, 0.318, 0.3, 0.3, 0.36}),
         new ZISTRENGTH('亥', '壬',new double[]  {0.84,0.77, 0.7, 0.7, 0.728, 0.742, 0.7, 0.7, 0.84, 0.84, 0.724, 0.798})
        };
        
        /*
                 金 --- 0
                 木 --- 1
                 水 --- 2
                 火 --- 3
                 土 --- 4
        */




        char[] WuXingTable = new char[] { '金', '木', '水', '火', '土' };
        
        /*
                 天干地支的五行屬性表
                 天干: 甲-木、乙-木、丙-火、丁-火、戊-土、己-土、庚-金、辛-金、壬-水、癸-水
                 地支:子-水、醜-土、寅-木、卯-木、辰-土、巳-火、午-火、未-土、申-金、酉-金、戌-土、亥-水
        */






        int[] TianGan_WuXingProp = new int[10] { 1, 1, 3, 3, 4, 4, 0, 0, 2, 2 };
        int[] DiZhi_WuXingProp = new int[12] { 2, 4, 1, 1, 4, 3, 3, 4, 0, 0, 4, 2 };
        int[] GenerationSourceTable = new int[5] { 4, 2, 0, 1, 3 };
        
        int ComputeGanIndex(char gan)
        {
            int i;


            for (i = 0; i < 10; i++)
                if (TianGan[i] == gan) break;


            if (i >= 10) return -1;


            return i;
        }
        
        int ComputeZhiIndex(char zhi)
        {
            int i;


            for (i = 0; i < 12; i++)
                if (DiZhi[i] == zhi) break;


            if (i >= 12) return -1;


            return i;
        }
        
        static string sResultBuf;   // 用作八字測算結果返回的字符緩衝區


        // 根據八字計算五行平衡
        // 輸入參數:bazi,年月日時的干支,即俗稱的八字
        // 輸出結果:分析結果字符串,Unicode編碼
        public string EvalBazi(string bazi)
        {
            double[] strengthResult = new double[5];


            int monthIndex = ComputeZhiIndex(bazi[3]);


            if (monthIndex == -1) return "";
            
            sResultBuf = bazi;
            sResultBuf += "\n\n五行強度:天干 + 支藏\n";


            for (int wuXing = 0; wuXing < 5; wuXing++)
            {
                double value1 = 0.0, value2 = 0.0;
                int i;


                //掃描4個天干
                for (i = 0; i < 8; i += 2)
                {


                    char gan = bazi[i];


                    int index = ComputeGanIndex(gan);


                    if (index == -1) return "";
                    
                    if (TianGan_WuXingProp[index] == wuXing)
                        value1 += TianGan_Strength[monthIndex][index];
                }
                
                //掃描支藏
                for (i = 1; i < 8; i += 2)
                {
                    char zhi = bazi[i];


                    for (int j = 0; j < DiZhi_Strength.Length; j++)
                    {


                        if (DiZhi_Strength[j].diZhi == zhi)
                        {


                            int zhiCangIndex = ComputeGanIndex(DiZhi_Strength[j].zhiCang);


                            if (zhiCangIndex == -1) return "";


                            if (TianGan_WuXingProp[zhiCangIndex] == wuXing)
                            {
                                value2 += DiZhi_Strength[j].strength[monthIndex];
                                break;
                            }
                        }
                    }
                }


                strengthResult[wuXing] = value1 + value2;
                
                //輸出一行計算結果
                {
                    string preStr;
                    string tmpBuf;


                    tmpBuf = value1.ToString("0.00") + " + " + value2.ToString("0.00") + " = " + (value1 + value2).ToString("0.00") + "\n";
                    
                    preStr = WuXingTable[wuXing] + ":\t";
                    sResultBuf += preStr;
                    sResultBuf += tmpBuf;
                }
            }


            //根據日干求命裏屬性
            int fateProp, srcProp;
            {
                string tmpWBuf;


                fateProp = TianGan_WuXingProp[ComputeGanIndex(bazi[4])];


                if (fateProp == -1) return "";
                
                tmpWBuf = "\n命屬" + WuXingTable[fateProp] + "\n\n";
                sResultBuf += tmpWBuf;
            }


            //求同類和異類的強度值
            srcProp = GenerationSourceTable[fateProp];
            {
                string preStr;
                string tmpBuf;
                double tongLei = strengthResult[fateProp] + strengthResult[srcProp];
                double yiLei = 0.0;


                for (int i = 0; i < 5; i++) yiLei += strengthResult[i];


                yiLei -= tongLei;
                
                tmpBuf = strengthResult[fateProp].ToString("0.00") + " + " + strengthResult[srcProp].ToString("0.00") + " = " + tongLei.ToString("0.00") + "\n";
                preStr = "同類:" + WuXingTable[fateProp] + "+" + WuXingTable[srcProp] + ",";


                sResultBuf += preStr;
                sResultBuf += tmpBuf;


                tmpBuf = yiLei.ToString("0.00") + "\n";
                sResultBuf += "異類:總和爲 " + tmpBuf;
            }
            return sResultBuf;
        }
    }


注:原作c代碼裏面對於hour小時的範圍有個前後矛盾,這裏加了一句if (hour > 22) hour -= 24;來匹配範圍。


這個方法需要先去比如nongli.net查詢八字的前6字,也就是年月子對應的天干和地支,這個查萬年曆當然是很容易的,不過也可以用代碼的形式輸入年月日就自動得到這前6字,然後調用本篇的代碼算出五行。至於得到前6字的算法大家可以研究nongli.net的js代碼然後改寫成C#代碼,這個大家可以自己嘗試哈。能做到自動生成的話,其實本篇的CheckBazi()函數就不需要了。

值得一提的是,本篇的c語言轉成c#還是簡單的,其實js轉成c#也是簡單的,不過有些時間函數C#並沒有一一對應的,這裏講解兩個關鍵的。

在JS裏面的Date.UTC(1900,0,6,2,5)這個函數在C#是沒有對應的,所以需要自己寫,需要注意的是此函數的月份範圍是0~11而不是1-12,所以在用C#的datetime來表示的時候,月份需要+1,另外就是時區的問題,中國在東8區,所以正常情況下你的電腦設置的時區也是東8區的北京時間的話,在做轉換的時候需要考慮這個問題。UTC返回的可以用double變量來存,用int是不夠的切記。

還有new Date( Date.UTC(1900,0,6,2,5) )這個函數會把計算的UTC數值再轉化成日期並取出天的數值,需要寫另外一個C#函數來實現,下面是代碼。

public double ConvertDateTimeInt(System.DateTime time)
        {
            double intResult = 0;
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            time = time.AddHours(8);//轉化爲北京時間(北京時間=UTC時間+8小時 )
            intResult = (time - startTime).TotalMilliseconds;
            return intResult;
        }
        public DateTime ConvertIntDatetime(double utc)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            startTime = startTime.AddMilliseconds(utc);
            startTime = startTime.AddHours(-8);//轉化爲北京時間(北京時間=UTC時間+8小時 )
            return startTime;
        }

這裏面的addHours的8和-8都是實際測試驗證的。有了上面2個函數,要計算八字就不難了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章