斗地主出牌算法

根据斗地主出牌规则.对玩家出的牌进行检验.判断是否符合出牌规则.

(关于斗地主的出牌规则网上有很多)

思路:将玩家的牌按升序排序.然后将牌进行拆分,分存在4个数组中.拆分规则如下:

假设有牌:333\444\555\789

则拆分后数组中的数据如下

arr[0]:345789

arr[1]:345

arr[2]:345

arr[3]:null

可以看出拆分规则是:如果遇到相同数字的牌则存到下一个数组的末尾.

拆分完后可以根据各数组的存储情况判定玩家出牌的类型,上面例子arr[3]为空.可以排除掉4带1(2).炸.的情况根据arr[2]为顺子且个数大于1,且arr[2]中存放的牌的张数乘以3刚好等于arr[0]的张数+arr[1]的张数.则可以判定是三带一的飞机.其他类型的牌也有相似的规律.以下是该算法的核心源代码.本算法用C#编写.

using System;
using System.Collections.Generic;
using System.Text;

namespace LordLibrary
{

/*

*以下程序版权由林奕霖所有,有兴趣的朋友可以用来交流和探讨.但请别用于商业用途.否则后果自负.

*您可以自由拷贝修改此源代码,但必须保留此注释.

*/

public class CheckType
{

private static int[][] DiffRow(int[] nums)
{
int[][] list = new int[4][];
for (int i = 0; i < list.Length; i++)
{
list[i] = new int[20];
}
int[] rowIndex = new int[4];
int columIndex = 0;

for (int i = 0; i < nums.Length; i++)
{
if (i + 1 < nums.Length)
{
if (nums[i] != 0)
{
list[columIndex][rowIndex[columIndex]] = nums[i];
rowIndex[columIndex]++;
}

if (nums[i] == nums[i + 1])
{
columIndex++;
}
else
{
columIndex = 0;
}
}
else if (nums[i] != 0)
list[columIndex][rowIndex[columIndex]] = nums[i];
}
return list;
}


private static int checkListCount(int[][] list, int rowIndex, int compStart, int rowMaxCount)
{

/* LIST 代表单顺.

*DOUB 代表双顺.

*FEI0 代表三顺.

*FEI1 代表三带一的飞机

*FEI2 代表三带二的飞机

*FOR1 代表四带1

*FOR2 代表四带2

*ROCK 代表大小王

*/
int listCount = 1;
for (int i = compStart; i < rowMaxCount - 1; i++)
{
if (list[rowIndex][i] + 1 == list[rowIndex][i + 1])
listCount++;
else
listCount = 1;
}
return listCount;
}
public static string getCardType(int[] nums)
{
int[][] list = DiffRow(nums);
int[] counts = new int[4];
for (int k = 0; k < 4; k++)
{
counts[k] = Array.IndexOf(list[k], 0);
}
int MaxValue = 0;
int listCount = 0;
string type = string.Empty;
//当第4行牌的数量为1的时候
#region
if (counts[3] == 1)
{
int index = Array.IndexOf(list[2], list[3][0]);
switch (counts[2])
{
case 1:
MaxValue = list[3][0];
if (counts[0] == 1)
{
type = "BOMB:4:" + MaxValue;
}
else if (counts[0] + counts[1] == 4)
{
type = "FOR1:6:" + MaxValue;
}
else if (counts[0] == counts[1] && counts[0] == 3)
{
type = "FOR2:8:" + MaxValue;
}

break;
case 2:
if (list[2][0] + 1 == list[2][1] && counts[1] == counts[2] && counts[0] == 3)
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + counts[2] + ":" + MaxValue;
} break;
case 3:
if (checkListCount(list, 2, 0, counts[2]) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + counts[2] + ":" + MaxValue;
}
else if (Array.IndexOf(list[2], list[3][0]) == 0 && counts[0] == counts[2])
{
if ((listCount = checkListCount(list, 2, 1, counts[2])) == counts[2] - 1)
{
MaxValue = list[2][counts[2] - 1];
type = "FEI2:" + listCount + ":" + MaxValue;
}

}
else if (Array.IndexOf(list[2], list[3][0]) == counts[2] - 1 && counts[0] == counts[2])
{
if ((listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1)
{
MaxValue = list[2][counts[2] - 2];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
break;
case 4:
if (index == 0 && counts[0] == counts[1] && counts[0] == 5)
{
if ((listCount = checkListCount(list, 2, 1, counts[2])) == counts[2] - 1)
{
MaxValue = list[2][counts[2] - 1];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
else if (index == counts[2] - 1 && counts[0] == counts[1] && counts[0] == 5)
{
if ((listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1)
{
MaxValue = list[2][counts[2] - 2];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
else if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
break;
case 5:
if (index == 0)
{
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if (listCount == counts[2] - 1 && counts[0] == counts[1])
{
if (counts[0] + 1 == 2 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI2:" + listCount + ":" + MaxValue;
}
else if (2 * (counts[0] + 1) == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
}
else if (index == counts[2] - 1)
{
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if ((listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1 && counts[0] == counts[1])
{
if (counts[0] + 1 == 2 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI2:" + listCount + ":" + MaxValue;
}
else if (2 * (counts[0] + 1) == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
}
else
{
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
break;
case 6:
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if (index == 0 && listCount == counts[2] - 1 && counts[0] + counts[1] + 2 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if (index == counts[2] - 1 && (listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1 && counts[0] + counts[1] + 2 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI1:" + listCount + ":" + MaxValue;
}
break;
}
}
#endregion
//当第4行牌的数量为2的时候
#region
if (counts[3] == 2)
{
switch (counts[2])
{

default:
if (counts[2] >= 2 && counts[2] < 6)
{
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
break;
case 6:
int firstIndex = Array.IndexOf(list[2], list[3][0]);
int secIndex = Array.IndexOf(list[2], list[3][1]);

if (secIndex == 1)
{
if ((listCount = checkListCount(list, 2, 2, counts[2])) == counts[2] - 2 && counts[0] == counts[1] && counts[0] + 2 == 2 * (counts[2] - 2))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
else if (secIndex == counts[2] - 1)
{
if (firstIndex == 0)
{
if ((listCount = checkListCount(list, 2, 1, counts[2] - 1)) == counts[2] - 2 && counts[0] == counts[1] && counts[0] + 2 == 2 * (counts[2] - 2))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
else if (firstIndex == secIndex - 1)
{
if ((listCount = checkListCount(list, 2, 0, counts[2] - 2)) == counts[2] - 2 && counts[0] == counts[1] && counts[0] + 2 == 2 * (counts[2] - 2))
{
MaxValue = list[2][counts[2] - 3];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
}
if ((listCount = checkListCount(list, 2, 1, counts[2])) == counts[2] - 1 && 2 * counts[0] + 3 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if ((listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1 && 2 * counts[0] + 3 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI1:" + listCount + ":" + MaxValue;
}


break;
}
}
#endregion
//当第4行牌的数量大于2的时候
#region
if (counts[3] > 2)
{
if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2] && counts[0] + counts[1] + counts[3] == 3 * counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
#endregion
//当第4行牌的数量为0,第三行牌的数量大于0
#region
if (counts[3] == 0 && counts[2] > 0)
{

if ((listCount = checkListCount(list, 2, 0, counts[2])) == counts[2])
{
if (counts[0] == counts[2])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI0:" + listCount + ":" + MaxValue;
}
else if (counts[0] + counts[1] == 3 * counts[2])
{

MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if (counts[0] + counts[1] == 4 * counts[2] && counts[0] == counts[1])
{
MaxValue = list[2][counts[2] - 1];
type = "FEI2:" + listCount + ":" + MaxValue;
}
}
if ((listCount = checkListCount(list, 2, 1, counts[2])) == counts[2] - 1 && counts[0] + counts[1] + 1 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 1];
type = "FEI1:" + listCount + ":" + MaxValue;
}
else if ((listCount = checkListCount(list, 2, 0, counts[2] - 1)) == counts[2] - 1 && counts[0] + counts[1] + 1 == 3 * (counts[2] - 1))
{
MaxValue = list[2][counts[2] - 2];
type = "FEI1:" + listCount + ":" + MaxValue;
}
}
#endregion
//当第3行牌的数量为0,第二行牌的数量大于0
#region
if (counts[2] == 0 && counts[1] > 0)
{
if (counts[0] == 1)
{
MaxValue = list[1][counts[1] - 1];
listCount = counts[1];
type = "DOUB:" + listCount + ":" + MaxValue;
}
else
{
if (counts[1] > 2 && counts[0] == counts[1] && (listCount = checkListCount(list, 1, 0, counts[1])) == counts[1])
{
MaxValue = list[1][counts[1] - 1];
type = "DOUB:" + listCount + ":" + MaxValue;
}
}
}
#endregion
//当第2行牌的数量为0
#region
if (counts[1] == 0)
{
if (counts[0] == 1)
{
MaxValue = list[0][counts[0] - 1];
listCount = counts[0];
type = "LIST:" + listCount + ":" + MaxValue;
}
else if (counts[0] == 2 && list[0][0] == 16 && list[0][1] == 17)
{
type = "ROCK:2:17";
}
else if (counts[0] >= 5 && (listCount = checkListCount(list, 0, 0, counts[0])) == counts[0])
{
MaxValue = list[0][counts[0] - 1];
listCount = counts[0];
type = "LIST:" + listCount + ":" + MaxValue;
}
}
#endregion
String[] cmd= type.Split(new char[]{':'});
int big = Array.IndexOf(nums, 16);
int small = Array.IndexOf(nums, 17);
if (cmd.Length > 0 && cmd[0]!=string.Empty)
{
if ((cmd[0]=="LIST" || cmd[0]=="DOUB" || cmd[0]=="FEI0" || cmd[0]=="FEI1"|| cmd[0]=="FEI2")&& (int.Parse(cmd[1]))>1)
{
type = int.Parse(cmd[2]) > 14 ? string.Empty : type;
}
else if (cmd[0] == "FOR1" || cmd[0] == "FOR2")
{
type = (big >0 && small>0) ? string.Empty : type;
}
}
return type;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值