斗地主(5)

稀里糊涂的写了几天  真是自己都全乱了。不管了 等框架搭好后再调吧。。


判断当前选中牌的类型,大小,这个函数嘛,,有点长。。感觉是不是不应该这么复杂。。

//判断牌型   1为王炸,2为炸弹,3为单牌,4为对牌,5为三张牌,6为三带一,7为三带二
//					8为单顺,9为双顺,10,为三顺(飞机不带翅膀),11为飞机带翅膀单牌,12为四带二单牌,13为四带二副对牌,14为飞机带翅膀对牌
//					-1为牌不符合规定
POKE_TYPE PokeManager::JudgePokeType(list<POKE> listpoke)
{
	int type = -1;
	int value = -1;
	int length = listpoke.size();
	POKE *poke = new POKE[length];
	list<POKE>::iterator it;
	int i = 0;
	listpoke.sort(CmpView);//进行从小到大排序
	for(it = listpoke.begin(); it != listpoke.end(); ++it)
		poke[i++] = *it;
	POKE temppoke;
	list<POKE> triochain;
	switch(length)
	{
	case 0:
		type = -1;
		break;
	case 1:type = 3;//3单牌
		break;
	case 2:
		if((poke[0].view + poke[1].view) == 29)	//1王炸
			type = 1;
		else if(poke[0].view == poke[1].view)	//4对牌
			type = 4;
		else 
			type = -1;
		break;
	case 3:
		if(poke[0].view == poke[1].view && poke[0].view == poke[1].view)//5三张
			type = 5;
		else 
			type = -1;
		break;
	case 4:// 4445  5666
		if(poke[0].view == poke[1].view && poke[0].view == poke[2].view && poke[0].view == poke[3].view)//2炸弹
			type = 2;
		else if(poke[1].view  == poke[2].view && (poke[1].view == poke[0].view || poke[1].view == poke[3].view))//6三带一
			type = 6;
		else 
			type = -1;
		break; 
	case 5://3带2  单顺     //44678   45678    44455   33444
		if((poke[0].view == poke[1].view && poke[3].view == poke[4].view) && (poke[2].view == poke[0].view || poke[2].view == poke[4].view))//7 三带二	
			type = 7;
		else if(CheckChain(poke,length) && !FindIllegalConnecting(listpoke))	//单顺
			type = 8;
		else 
			type = -1;
		break;
	case 6://4带2张单牌  单顺  双顺  三顺
		if(FindSame(listpoke,4,&temppoke))//4带2张单牌
		{
			int i,x = 0,view1,view2;
			for(i = 0; i < length; i++)
			{if(poke[i].view != temppoke.view)
				{if(++x == 0) view1 = poke[i].view; 
				else view2 = poke[i].view;}}
			if(view1 != view2) type = 12;
			else type = -1;
		}
		else if(CheckChain(poke,length) && !FindIllegalConnecting(listpoke))//8单顺
			type = 8;
		else if(CheckPairChain(poke,length) && !FindIllegalConnecting(listpoke))//9双顺
			type = 9;
		else if(CheckTrioChain(poke,length,triochain) && !FindIllegalConnecting(listpoke))//飞机不带翅膀
			type = 10;
		else
			type = -1;
		break;
		//三顺   6 333444    8 33344456    10 4445556677    12 333444555678   16 33344455566678910
	case 7://单顺  飞机带单翅膀
	case 9: case 11:case 13:
	case 15:case 17:case 19:
		if(CheckChain(poke,length) && !FindIllegalConnecting(listpoke))//8单顺
			type = 8;
		else if(CheckTrioChain(poke,length,triochain) == 11 && !FindIllegalConnecting(listpoke))//11飞机带单翅膀
			type = 11;
		else 
			type = -1;
		break;
	case 8://单顺  双顺   三顺带双翅
	case 10:case 12:case 14:
	case 16:case 18:case 20:
		if(length == 8)
		{
			if(CheckFourWithTwoPairs(poke,&temppoke))//13 四带二张对牌
			{
				type = 13;
				break;
			}
		}
		if(CheckChain(poke,length) && !FindIllegalConnecting(listpoke))//8单顺
			type = 8;
		else if(CheckPairChain(poke,length) && !FindIllegalConnecting(listpoke))//9双顺
			type = 9;
		else if(CheckTrioChain(poke,length,triochain) == 14 && !FindIllegalConnecting(listpoke))//11飞机带单翅膀
			type = 14;
		else 
			type = -1;
		break;
	}
	return CalValue(poke,length,type,temppoke,triochain);
}


判断牌型各种的小函数

//查看连牌中是否有大王小王 和2	
bool PokeManager::FindIllegalConnecting(list<POKE> listpoke)
{
	list<POKE>::iterator it;
	for(it = listpoke.begin(); it != listpoke.end(); ++it)
	{
		if(it->view == 2 || it->view == 14  || it->view == 15)
			return true;
	}
	return false;
}

//查看牌中是否有多张相同牌
bool PokeManager::FindSame(list<POKE> listpoke, int samenum, POKE *temppoke)
{
	list<POKE>::iterator tempIt,it;
	int count = 0;
	bool isexist = false;
	for(tempIt = listpoke.begin(); tempIt != listpoke.end(); ++tempIt)
	{
		for(it = listpoke.begin(); it != listpoke.end(); ++it)
		{
			if(tempIt == it)
				count++;
		}
		if(count == samenum)
		{
			*temppoke = *tempIt;
			if(!isexist)
				isexist = true;
			else
				isexist = false;
		}
	}
	return false;
}

//检查是否为顺牌
bool PokeManager::CheckChain(POKE *poke, int num)
{
	POKE *vpoke = ValueSort(poke,num);
	for(int i = 0; i < num - 1; i++)
	{
		if(vpoke[i].value + 1 != vpoke[i+1].value)
			return false;
	}
	delete vpoke;
	return true;
}
//检查是否为双顺牌
bool PokeManager::CheckPairChain(POKE *poke, int num)
{
	POKE *vpoke = ValueSort(poke,num);
	for(int i = 0; i < num - 2; i+=2)
	{
		if((vpoke[i].value + 1 != vpoke[i+2].value) || (vpoke[i].value != vpoke[i+1].value))
			return false;
	}
	delete vpoke;
	return true;
}
//检查是否为三顺牌
int PokeManager::CheckTrioChain(POKE *poke, int num, list<POKE> &triochain)
{
	POKE *vpoke = ValueSort(poke,num);
	int value1,value2;
	int count = 1;
	bool solo = false, pair = false;//三顺带的是solo(单张)还是pair(对牌),不能同时为true
	value1 = vpoke[0].value;
	for(int i = 0; i < num; i++)
	{
		value2= vpoke[i].value;
		if(value1 == value2)
			count++;
		else
		{
			if(count == 1)
				solo = true;
			else if(count == 2)
				pair = true;
			else if(count == 3)
				triochain.push_back(vpoke[i-1]);
			else if(count > 3)
				break;
			count = 1;
			value1 = value2; 
		}
	}
	delete vpoke;
	if(solo && !pair)
		return 11;
	else if(!solo && pair)
		return 14;
	else 
		return -1;
}
//检查是否为四带两张对牌
bool PokeManager::CheckFourWithTwoPairs(POKE *poke, POKE *temppoke)
{
	int view1,view2;
	int count = 1;
	int pairnums = 0;
	view1 = poke[0].view;
	for(int i = 0; i < 8; i++)
	{
		view2 = poke[i].view;
		if(view1 == view2)
			count++;
		else
		{
			if(count == 2)
				pairnums++;
			else if(count == 4)
				*temppoke = poke[i-1];
			else
				return false;
			count = 1;
			view1 = view2;
		}
	}
	if(pairnums == 2)
		return true;
	else
		return false;
}

为了不使原按view排序的序列混乱,写了一个按value排序并返回的小函数

//以value为基准排序
POKE* PokeManager::ValueSort(POKE *poke, int num)
{
	POKE *vpoke = new POKE[num];
	for(int i = 0; i < num; i++)
	{
		vpoke[i] = poke[i];
	}
	sort(vpoke,vpoke+num,CmpValue);
	return vpoke;
}
最后 计算当前牌的值

//计算牌型的大小
POKE_TYPE PokeManager::CalValue(POKE *poke, int length, int type, POKE valuepoke, list<POKE> valuetriochain)
{//三带一 算第2张牌  3444 4445   三带二算第3张牌    33444 44455 飞机带翅膀
	// 1 2 3 4 5 8 9 10 
	POKE_TYPE poketype;
	sort(poke,poke+length,CmpValue);
	sort(valuetriochain.begin(),valuetriochain.end(),CmpValue);
	int value = 0;
 	switch(type)
	{
	case 1:case 2:case 3:case 4:case 5:case 8:case 9:case 10:
		value = poke[0].value;
		break;
	case 6:case 7:
		value = poke[2].value;
		break;
	case 11:case 14://飞机单翅 飞机双翅
		value = valuetriochain.begin()->value;
		break;
	case 12:case 13://四带二单 四带二双
		value = valuepoke.value;
		break;
	}
}

额额 ,这几天比较忙,家里搬家,程序写的很混乱,这么长的代码,是不是不应该啊~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值