麻将数据牌集合
private int[] cardDataArray =
{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};
思路 :麻将胡牌算法为3n*2(其中2为将牌、3n为顺子或者刻子)
1、首先查找所有可以作为将牌的牌。用剩余的牌来判断是否是可以胡的。
2、剩余的牌打上断点、用数量作为值来判断是否符合顺子或者刻子的算法。
3、符合返回true 不符合返回false.
代码如下
public bool huLegal(int cacheCard, int[] cbHandCard)
{
int first = cbHandCard.Length;
int mianNeed = NeedMain(cbHandCard);
int[] card = new int[first + 1];
for (int i = 0; i < first; i++)
{
card[i] = cbHandCard[i];
}
card[first] = cacheCard;
SortCardList(card);
if (mianNeed == 0)
{
if (cbHandCard[0] == cacheCard) return true;
else return false;
}
else
{
if ((first + 1) % 3 != 2) return false;
else
{
int[] jiangs = getJiang(card, first + 1);
List<int[]> mians = quJiangArrs(card, jiangs, first + 1);
int size = mians.Count;
bool[] ones = new bool[size];
int[] breaks;
for (int i = 0; i < size; i++)
{
breaks = getBreaks(mians[i], first - 1);
if (breaksCheck(breaks, breaks.Length))
{
ones[i] = false;
}
else
{
int[] miansparts = allParts(mians[i], breaks);
ones[i] = finalHu(miansparts, miansparts.Length);
}
}
for (int i = 0; i < size; i++)
{
if (ones[i]) return true;
}
}
}
return false;
}
接下来为上个方法所用到的一些方法
/// 是否需要将牌(玩家剩余一张牌是不需要)
int NeedMain(int[] cbHandCard)
{
int last = cbHandCard.Length;
if (last <= 1)
{
return 0;
}
return 1;
}
/// 排序手中的牌
public void SortCardList(int[] handCard)
{
List<int> sortTemp = new List<int>(handCard);
sortTemp.Sort();
for (int i = 0; i < sortTemp.Count; i++)
{
handCard[i] = sortTemp[i];
}
}
/// 查找所有的将牌
int[] getJiang(int[] cbHandCard, int cbHandCardCount)
{
int[] arr = new int[cbHandCardCount];
int count = 1;
for (int i = 1; i < cbHandCardCount; i++)
{
if (cbHandCard[i] == cbHandCard[i - 1])
{
if (count == 1) arr[i - 1] = cbHandCard[i];
count += 1;
}
else count = 1;
}
return arr;
}
/// 去除将牌、返回所有牌的情况(因为可能有多种牌做奖牌)、
// List 集合中每一个索引对应的数组都是一种排列方式
List<int[]> quJiangArrs(int[] card, int[] jiangs, int length)
{
List<int[]> list = new List<int[]>();
for (int i = 0; i < length; i++)
{
if (jiangs[i] != 0)
{
int[] src = new int[length];
int[] arr = new int[length - 2];
for (int j = 0; j < length; j++)
{
src[j] = card[j];
}
src[i] = 0x00;
src[i + 1] = 0x00;
SortCardList(src);
Array.Copy(src, 2, arr, 0, length - 2);
list.Add(arr);
}
}
return list;
}
/// 查找去除将牌后的断点(没有连续的牌就是一个断点)
/// 返回的数组为断点所在索引的集合 例如(3 4 5 7 8 9) 断点集合{0,3,6}
int[] getBreaks(int[] cbHandCard, int cbHandCardCount)
{
int[] breaks = new int[22];//首位0
int count = 1;
for (int i = 1; i < cbHandCardCount; i++)
{
if ((cbHandCard[i] - cbHandCard[i - 1]) > 1)
{
breaks[count] = i;
count += 1;
}
}
breaks[count] = cbHandCardCount;
int[] breakss = new int[count + 1];//首位0 尾位length
for (int i = 0; i < count + 1; i++)
{
breakss[i] = breaks[i];
}
return breakss;
}
/// <summary>
/// 断点后、检查所断的牌型是不是顺子或者刻子
/// 手牌 3 4 5 7 8 9 -- 断点后 0 3 6 (将牌已被丢出)
/// </summary>
/// <param name="breaks"> breaks 为断点后 下标的集合</param>
/// <param name="length"></param>
/// <returns> false 表示断牌为顺子或者刻字 true表示不符合胡牌规则 </returns>
bool breaksCheck(int[] breaks, int length)
{
for (int i = 1; i < length; i++)
{
if (breaks[i] % 3 != 0)
return true;
}
return false;
}
/// <summary>
/// 根据手牌和断点的数组 返回经过处理的牌型
/// </summary>
/// <param name="cbHandCard"> cbHandCard -- 去除将牌后的手牌</param>
/// <param name="breaks"> breaks -- 标记断点后的索引</param>
/// <returns></returns>
int[] allParts(int[] cbHandCard, int[] breaks)
{
int partnum = breaks.Length - 1; //断点个数
int[] parts = new int[partnum];
int[] arr;
for (int i = 0; i < partnum; i++)
{
arr = new int[breaks[i + 1] - breaks[i]];
for (int j = 0; j < breaks[i + 1] - breaks[i]; j++)
{
arr[j] = cbHandCard[breaks[i] + j];
}
// arr集合表示 去除将牌后的手牌根据断点分别放入的牌
parts[i] = getWei(arr, arr.Length);
}
return parts;
}
因为3n中的牌型的类型不确定。所以此处采取一种拆解法
举例 (五万、五万、五万、六万、七万、七万、八万、八万、九万)
因为此为连续的牌型、所以放入一个集合中、用牌的数量来表示 (3 1 2 2 1)
分析:取出三张牌 (3 1 2)来判断这三张牌中是否有三张相等的、如果有则去除首位 余 1 2 (后两位 2 1)
继续取出三张牌 ( 1 2 2) 三张都大于等于1 递减一 排除顺子 余 1 1 (后一位 1)
剩下三张(1 1 1) 可胡
以上思路代码实现
bool isMianPart(int cbCardWei)
{
int cache = cbCardWei;
for (int i = 0; i < 9; i++)
{
cache = carryChange(cache);
if (cache == 0) return true;
}
return false;
}
int carryChange(int cbCardWei)
{
int keyNum = 3;
int result = cbCardWei;
int weilength = (int)Mathf.Log10(cbCardWei) + 1;
int weihead = (int)(cbCardWei / Mathf.Pow(10, (weilength - keyNum)));
if (carry(weihead) != 0)
{
result = (int)(cbCardWei - (carry(weihead) * Mathf.Pow(10, (weilength - keyNum))));
}
else
{
keyNum = 2;
weihead = (int)(cbCardWei / Mathf.Pow(10, (weilength - keyNum)));
if (carry(weihead) != 0)
{
result = (int)(cbCardWei - (carry(weihead) * Mathf.Pow(10, (weilength - keyNum))));
}
else
{
keyNum = 1;
weihead = (int)(cbCardWei / Mathf.Pow(10, (weilength - keyNum)));
if (carry(weihead) != 0)
{
result = (int)(cbCardWei - (carry(weihead) * Mathf.Pow(10, (weilength - keyNum))));
}
}
}
return result;
}
int carry(int key)
{
switch (key)
{
case 3: return 3;
case 4: return 3;
case 31: return 30;
case 32: return 30;
case 33: return 33;
case 44: return 33;
case 111: return 111;
case 112: return 111;
case 113: return 111;
case 114: return 114;
case 122: return 111;
case 123: return 111;
case 124: return 111;
case 133: return 111;
case 134: return 111;
case 141: return 141;
case 142: return 141;
case 143: return 141;
case 144: return 144;
case 222: return 222;
case 223: return 222;
case 224: return 222;
case 233: return 222;
case 234: return 222;
case 244: return 222;
case 311: return 300;
case 312: return 300;
case 313: return 300;
case 314: return 300;
case 322: return 300;
case 323: return 300;
case 324: return 300;
case 331: return 330;
case 332: return 330;
case 333: return 333;
case 334: return 333;
case 341: return 330;
case 342: return 330;
case 343: return 330;
case 344: return 333;
case 411: return 411;
case 412: return 411;
case 413: return 411;
case 414: return 414;
case 422: return 411;
case 423: return 411;
case 424: return 411;
case 433: return 411;
case 434: return 411;
case 441: return 441;
case 442: return 441;
case 443: return 441;
case 444: return 444;
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)