麻將查胡演算法 資料結構設計與實現
根據前面一片部落格傳送門,演算法介紹,這裡來實現核心部分
中間用到的一些功能函式,大家自己搞定吧,我把核心演算法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,不然會死迴圈