1. 程式人生 > >麻將查胡演算法 資料結構設計與實現

麻將查胡演算法 資料結構設計與實現

根據前面一片部落格傳送門,演算法介紹,這裡來實現核心部分

中間用到的一些功能函式,大家自己搞定吧,我把核心演算法po出來大家參考

一、資料結構設計c#

演算法流程:輪流判斷每一張牌是否符合要求


找出所有可以當將的牌

while(將牌沒遍歷完)

{

    去除將牌,提取陣列byte[] cardgroup

    while(陣列不為空)

    {

          取出第一張牌byte  card  =  cardgroup[0];

          確認牌張數 int count = GetCardCount(card);//功能函式

          If(判斷陣列是不是空的)

          {

                 如果是空的break

         }

         else

         {

              If(判斷陣列中是否含有順子或者刻子(三張))

               {

                    //根據張數處理

                    If(count  ==  1)

                     {
                         If(判斷card能否組成順子)
                         {

                              能就把這個順子從牌組中刪掉

                          }

                         else

                        {

                               break

                        }

                    }            

                               
                   If(count  ==  2)

                    {

                               If(判斷card能否組成2個順子)

                               {

                                        能就把這2個順子從牌組中刪掉

                                }

                              else

                               {

                                      break

                               }

                    }

 

                    If(count  ==  3)

                    {

                             If(判斷card能否組成3個順子)

                             {

                                      能就把這3個順子從牌組中刪掉

                               }

                              else

                             {

                                      不能就把這個刻子刪掉

                              }

                      }

 

                      If(count  ==  4)

                      {

                             If(判斷card能否組成4個順子)

                             {

                                    能就湊夠12張了,一定可以胡

                                    return true

                             }

                             else

                             {

                                       If(能否拿出一張和後面的牌組成順子)

                                       {

                                              能就把這個順子和刻子都刪掉

                                       }

                                       else

                                       {

                                               否則break

                                        }

                           }

                     }

                }

               else

                {

                       //陣列不為空,沒有順,沒有刻,一定沒胡

                       如果沒有break

                }

           }

        }


         陣列為空或者while被break到這裡

         If(判斷cardgroup是否為空(全部完整移除))

         {

                 是就表示胡return  true

          }

}

 

二、實現

    bool TingCard(byte[] JiangArray, byte[] Cards, int type)
    {
        byte[] cardgroup = Cards;
        while (JiangCount < JiangNumber)
        {
            byte[] jiang = new byte[2];//兩張一樣的
            jiang[0] = JiangArray[JiangCount];
            jiang[1] = JiangArray[JiangCount];
            JiangCount++;

            cardgroup = GameLogic.DeleteArr(jiang, Cards);//DeleteItem(jiang, Cards);
            if (cardgroup == null) return true;
            cardgroup = GameLogic.SortCard1(cardgroup);//Sort(cardgroup);

            while (!IsNilGrop(cardgroup))
            {
                if (IsHaveLine(cardgroup) || IsHaveThree(cardgroup))
                {
                    byte card = cardgroup[0];
                    int cardcount = GetCardCount(card, cardgroup);
                    if (cardcount == 1)
                    {
                        byte [] line = GetLine(cardgroup,card,1);
                        if (line!= null)
                        {
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (cardcount == 2)
                    {
                        byte[] line = GetLine(cardgroup, card,2);
                        if (line != null)
                        {
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                        }
                        else
                        {
                            break;
                        }
                    }
                    else if (cardcount == 3)
                    {
                        byte[] line = GetLine(cardgroup, card, 3);
                        if (line != null)
                        {
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                            cardgroup = GameLogic.DeleteArr(line, cardgroup);
                        }
                        else
                        {
                            cardgroup = GameLogic.DeleteArr(new byte[] {card, card, card}, cardgroup);
                        }
                    }
                    else if (cardcount == 4)
                    {
                        byte[] line = GetLine(cardgroup, card, 4);
                        if (line != null) return true;
                        else
                        {
                            byte[] line1 = GetLine(cardgroup, card, 1);
                            if (line1 != null)
                            {
                                cardgroup = GameLogic.DeleteArr(line1, cardgroup);
                                cardgroup = GameLogic.DeleteArr(new byte[] { card, card, card }, cardgroup);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                }
                else
                {
                    break;
                }
            }

            if (IsNilGrop(cardgroup))
            {
                return true;
            }
        }
        return false;

    }


只上了核心部分程式碼,這時候有的小夥伴會發現,當cardcount == 3的時候,如果可以組成3個順子就直接把三個順子刪掉,如果出現其中一個要和其他牌組成順子的話,會不會報錯,放心吧不會的!這個特殊情況是不存在的,自己擺一擺就知道啦


後來自己發現了一個漏洞,就是沒有考慮到新增完了有5張的情況,要加個break,不然會死迴圈