斗地主游戏实现10:代码之五(牌处理)

1. card_op.h

#ifndef GAME_CARD_OP
#define GAME_CARD_OP
void sameVCard(int *,int *,unsigned char *,unsigned char,int);
int afterPlayHander(oppose_landocrat_playing_info *,unsigned char ,unsigned char *,unsigned char,card_type);
int getMinFitCards(card_type *, const unsigned char *,unsigned char ,unsigned char*,unsigned char);
#endif /* GAME_CARD_OP */

 

2. card_op.c

#include "game.h"

static int getFitSeq(unsigned char *,int ,unsigned char ,int ,int );
/* 出牌后处理 */
int afterPlayHander(oppose_landocrat_playing_info *playing_info,unsigned char player,unsigned char *playcards,unsigned char play_num,card_type ctype)
{
	if(playing_info->pre_player != -1) {
		xfree(playing_info->pre_cards);
	}
	int i;
	for(i = 0; i< play_num; i++) {
			playing_info->player_remain_cards[player][i] = 0;
	}
	sort_card(playing_info->player_remain_cards[player],playing_info->player_remain_count[player]);
	playing_info->next_player = (player + 1) % oppose_landocrat.player_count;
	playing_info->player_remain_count[player] -= play_num;
	playing_info->pre_player = player;
	playing_info->pre_cards = playcards;
	playing_info->pre_card_count = play_num;
	playing_info->pre_card_type = ctype;
	playing_info->players[player]->sendCardTimes++;
	if(ctype == CARD_TYPE_FOUR_BOMB || ctype == CARD_TYPE_ROCKET) {
		(playing_info->bomb_counts)++;
	}
	return 0;
}
void sameVCard(int *isc,int *start,unsigned char *nRcards,unsigned char nRnum,int snum) {
	int *tmpnum =NULL;
	tmpnum =getSameValueNum(nRcards,nRnum,1);
	isc[0] = tmpnum[4],isc[4] = tmpnum[3],isc[3] = tmpnum[2],isc[2]=tmpnum[1],isc[1]=tmpnum[0];
	xfree(tmpnum);
	start[4] = 0;
	start[0] = 0;
	start[3] = isc[4] * 4;
	start[2] = start[3] + isc[3] * 3;
	start[1] = start[2] + isc[2] * 2;
	if(snum > 1 && snum < 4) {
		unsigned char cardTmp[nRnum];
		int cv,i,j,k,rsum;
		k = 0;
		rsum = 0;
		for(cv = 4; cv >= snum; cv--) {
			if(isc[cv]) {
				for(i = 0; i < isc[cv]; i++) {
					for(j = 0; j < snum; j++) {
						cardTmp[k*snum+j] = nRcards[start[cv]+j];
					}
					for(; j < cv; j++) {
						cardTmp[nRnum - rsum -1] = nRcards[start[cv]+j];
						rsum++;
					}
					k++;
				}
				isc[cv]= 0;
			}
		}
		if(k > 0) {
			rsum = k*snum;
			isc[snum] = k;
			sort_card(cardTmp,rsum);
			for(cv = snum - 1; cv >= 1; cv--) {
				for(i = 0; i < isc[cv]; i++) {
					for(j = 0; j < cv; j++) {
						cardTmp[rsum] = nRcards[start[cv]+cv*i+j];
					}
					rsum++;
				}
			}
			sort_card(cardTmp+k*snum,nRnum - k*snum);
			memcpy(nRcards,cardTmp,nRnum);
			isc[1] = nRnum - k*snum;
			isc[2] = 0;
			isc[3] = 0;
			isc[4] = 0;
			isc[0] = 0;
			isc[snum] = k;
			start[3] = isc[4] * 4;
			start[2] = start[3] + isc[3] * 3;
			start[1] = start[2] + isc[2] * 2;
		}
		
	}

}
int getMinFitCards (card_type *ctype, const unsigned char *pcards,unsigned char card_num,unsigned char*nRcards,unsigned char nRnum) {
	int i,j;
	unsigned char tmpcard;
	unsigned char cardTmp[nRnum];
	int withSinal[3];
	int windex = 0;
	int usqc;
	int fitc;
	int isc[5];
	int start[5];
	
	sort_card(nRcards,nRnum);
	if(*ctype > CARD_TYPE_THREE_DOUBLE)
		sameVCard(isc,start,nRcards,nRnum,0);
	/*isRock = sameVCard(isc,start,nRcards,nRnum,0);*/
	switch(*ctype) {
		/* 单张牌 01 */
		case CARD_TYPE_SIGNAL:
			for(i = 0; i < nRnum; i++) {
				if((pcards[0] - 1) / 4 < (nRcards[i] - 1) / 4) {
					tmpcard = nRcards[i];
					nRcards[i] = nRcards[0];
					nRcards[0] = tmpcard;
					return 1;
				}
			}
			break;
		/* 一对牌 02 */
		case CARD_TYPE_DOUBLE:
			if(nRnum < card_num)
				break;
			for(i = 0; i < nRnum - 1; i++) {
					if((nRcards[i] -1) / 4 > (pcards[0] -1) / 4 && (nRcards[i] -1) / 4 == (nRcards[i+1] -1) / 4) {
						for(j = 0; j < 2; j++) {
							tmpcard = nRcards[i + j];
							nRcards[i + j] = nRcards[j];
							nRcards[j] = tmpcard;
						}
						return 2;
					}
			}
			break;
		
		/* 火箭(一对王) 03 */
		case CARD_TYPE_ROCKET:
			return 0;
		/* 三张牌 04 */
		case CARD_TYPE_THREE:
			if(nRnum < card_num)
				break;
			for(i = 0; i < nRnum - 2; i++) {
					if((nRcards[i] -1) / 4 > (pcards[0] -1) / 4 
						&& (nRcards[i] -1) / 4 == (nRcards[i+1] -1) / 4
						&& (nRcards[i+1] -1) / 4 == (nRcards[i+2] -1) / 4) {
						for(j = 0; j < 3; j++) {
							tmpcard = nRcards[i + j];
							nRcards[i + j] = nRcards[j];
							nRcards[j] = tmpcard;
						}
						return 3;
					}
			}
			break;
		/* 三带一 05 */
		case CARD_TYPE_THREE_SIGNAL:
			if(nRnum < card_num)
				break;
			sameVCard(isc,start,nRcards,nRnum,3);
			if(isc[3]) {
				for(i = 0; i < isc[3]; i++) {
					if(nRcards[start[3] + i * 3] > pcards[0]) {
						int fitPos = -1;
						if(isc[1]) {
							for(j = 0; j < isc[1]; j++) {
								tmpcard = nRcards[start[1] + j];
								if((tmpcard - 1) / 4 != (nRcards[start[3]] - 1) / 4) {
									fitPos = start[1] + j;
									break;
								}
							}
						}

						if(fitPos >= 0) {
							for(j = 0; j < 3; j++) {
								tmpcard = nRcards[start[3] + i * 3 + j];
								nRcards[start[3] + i * 3 + j] = nRcards[j];
								nRcards[j] = tmpcard;
							}
							tmpcard = nRcards[fitPos];
							nRcards[fitPos] = nRcards[3];
							nRcards[3] = tmpcard;
							return 4;
						}

						
					}
				}
			}
			break;
		/* 三带一对 06 */
		case CARD_TYPE_THREE_DOUBLE:
			if(nRnum < card_num)
				break;
			sameVCard(isc,start,nRcards,nRnum,3);
			if(isc[3]) {
				for(i = 0; i < isc[3]; i++) {
					if(nRcards[start[3] + i * 3] > pcards[0]) {
						int fitPos = -1;
						for(j = 0; j < 3; j++) {
								tmpcard = nRcards[start[3] + i * 3 + j];
								nRcards[start[3] + i * 3 + j] = nRcards[j];
								nRcards[j] = tmpcard;
						}
						sameVCard(isc,start,nRcards+3,nRnum-3,2);
						if(isc[2]) {
							fitPos = start[3] + isc[3] * 3 + 3;
						}
						
						if(fitPos >= 0) {
							for(j = 0; j < 2; j++) {
								tmpcard = nRcards[fitPos+j];
								nRcards[fitPos+j] = nRcards[3 + j];
								nRcards[3 + j] = tmpcard;
							}
							return 5;
						}
					}
				}
			}
			break;
		/* 炸*弹 07 */
		case CARD_TYPE_FOUR_BOMB:
			return 0;
			/*
			if(nRnum < card_num)
				break;
			for(i = 0; i < isc[4]; i++) {
					if(nRcards[i * 4] > pcards[0]) {
						for(j = 0; j < 4; j++) {
								tmpcard = nRcards[i * 4 + j];
								nRcards[i * 4 + j] = nRcards[j];
								nRcards[j] = tmpcard;
						}
						return 4;
					}
			}*/
			break;
		/* 单顺 08 */
		case CARD_TYPE_SEQUENCE_SIGNAL:
			if(nRnum < card_num)
				break;
			usqc = nRnum-start[3];
			if(isc[1])
			for(i = start[1]; i < nRnum; i++) {
				cardTmp[i-start[1]] = nRcards[i];
			}
			if(isc[2]) {
				for(i = 0; i < isc[2]; i++) {
					cardTmp[isc[1] + i] = nRcards[start[2] + i * 2];
					usqc--;
					cardTmp[usqc] = nRcards[start[2] + i * 2 + 1];
				}
			}
			if(isc[3]) {
				for(i = 0; i < isc[3]; i++) {
					cardTmp[isc[1] + isc[2] + i] = nRcards[start[3] + i * 3];
					usqc--;
					cardTmp[usqc] = nRcards[start[3] + i * 3 + 2];
					usqc--;
					cardTmp[usqc] = nRcards[start[3] + i * 3 + 1];
				}
			}
			fitc= getFitSeq(cardTmp,usqc,pcards[0],card_num,1);
			if(fitc >= 0) {
				for(i = 0; i < card_num; i++) {
					tmpcard = cardTmp[fitc + i];
					cardTmp[fitc + i] = cardTmp[i];
					cardTmp[i] = tmpcard;
				}
				if(isc[4]) {
					for(i = 0; i < isc[4]; i++) {
						for(j = 0; j < 4; j++) {
							nRcards[nRnum - 1 - i*4 -j] =  nRcards[i * 4 + j];
						}
					}
				}
				for(i = 0; i < nRnum-start[3]; i++) {
					nRcards[i] = cardTmp[i];
				}
				return card_num;
			}
			break;
		/* 双顺 09 */
		case CARD_TYPE_SEQUENCE_DOUBLE:
			if(nRnum < card_num)
				break;
			usqc = nRnum-start[3]-isc[1];
			if(isc[1])
			for(i = start[1]; i < nRnum; i++) {
				cardTmp[usqc+i-start[1]] = nRcards[i];
			}
			if(isc[2]) {
				for(i = 0; i < isc[2]; i++) {
					cardTmp[i*2] = nRcards[start[2] + i * 2];
					cardTmp[i*2+1] = nRcards[start[2] + i * 2 + 1];
				}
			}
			if(isc[3]) {
				for(i = 0; i < isc[3]; i++) {
					cardTmp[isc[2]*2 + i * 2] = nRcards[start[3] + i * 3];
					cardTmp[isc[2]*2 + i * 2 + 1] = nRcards[start[3] + i * 3 + 1];
					usqc--;
					cardTmp[usqc] = nRcards[start[3] + i * 3 + 2];
				}
			}
			fitc= getFitSeq(cardTmp,usqc,pcards[0],card_num,2);
			if(fitc >= 0) {
				for(i = 0; i < card_num; i++) {
					tmpcard = cardTmp[fitc + i];
					cardTmp[fitc + i] = cardTmp[i];
					cardTmp[i] = tmpcard;
				}
				if(isc[4]) {
					for(i = 0; i < isc[4]; i++) {
						for(j = 0; j < 4; j++) {
							nRcards[nRnum - 1 - i*4 -j] =  nRcards[i * 4 + j];
						}
					}
				}
				for(i = 0; i < nRnum-start[3]; i++) {
					nRcards[i] = cardTmp[i];
				}
				return card_num;
			}
			break;
		/* 三顺 10 */
		case CARD_TYPE_SEQUENCE_THREE:
			if(nRnum < card_num)
				break;
			if(isc[4]) {
				for(i = 0; i < isc[4]; i++) {
					for(j = 0; j < 3; j++) {
						cardTmp[i*3+j] = nRcards[i*4+j];
					}
					cardTmp[nRnum - i -1] = nRcards[i*4+j];
				}
			}
			for(i = isc[4]*3; i < nRnum - isc[4]; i++) {
				cardTmp[i] = nRcards[i+isc[4]];
			}
			fitc= getFitSeq(cardTmp,nRnum-isc[4]-isc[2]*2-isc[1],pcards[0],card_num,3);
			if(fitc >= 0) {
				for(i = 0; i < card_num; i++) {
					tmpcard = cardTmp[fitc + i];
					cardTmp[fitc + i] = cardTmp[i];
					cardTmp[i] = tmpcard;
				}
				for(i = 0; i < nRnum; i++) {
					nRcards[i] = cardTmp[i];
				}
				return card_num;
			}
			break;
		/* 飞机带翅膀:三顺+同数量的单牌 11 */
		case CARD_TYPE_SEQUENCE_THREE_WINGS_SIGNAL: 
			if(nRnum < card_num)
				break;
			if(isc[4]) {
				for(i = 0; i < isc[4]; i++) {
					for(j = 0; j < 3; j++) {
						cardTmp[i*3+j] = nRcards[i*4+j];
					}
					cardTmp[nRnum - i -1] = nRcards[i*4+j];
				}
			}
			for(i = isc[4]*3; i < nRnum - isc[4]; i++) {
				cardTmp[i] = nRcards[i+isc[4]];
			}
			fitc= getFitSeq(cardTmp,nRnum-isc[4]-isc[2]*2-isc[1],pcards[0],card_num-card_num/4,3);
			if(fitc >= 0) {
				int notNextWings[card_num/4];
				int nextNotWinIndex = card_num/4;
				for(i = 0; i < card_num; i++) {
					tmpcard = cardTmp[fitc + i];
					cardTmp[fitc + i] = cardTmp[i];
					cardTmp[i] = tmpcard;
					if(i % 3 == 0) {
						notNextWings[i/3] = i;
					}
				}
				int hasEmperor = 0;
				for(i = card_num-card_num/4; i < nRnum; i++) {
					int isn = 1;
					for(j = 0; j < nextNotWinIndex; j++) {
						if(hasEmperor && (cardTmp[i] == 57 || cardTmp[i] == 61)) {
							isn = 0;
							break;
						}
						if(!hasEmperor && (cardTmp[i] == 57 || cardTmp[i] == 61))
							hasEmperor = 1;
						if((cardTmp[i] - 1) / 4 == (cardTmp[notNextWings[j]] - 1) / 4) {
							isn = 0;
							break;
						}
					}
					if(isn) {
						cardTmp[nextNotWinIndex++] = i;
					}
					if(nextNotWinIndex == card_num/2)
						break;
				}
				printf("nextNotWinIndex=%d\n",nextNotWinIndex);
					if (nextNotWinIndex == card_num/2) {
						for(i = card_num/4;i < nextNotWinIndex; i++) {
							tmpcard = cardTmp[notNextWings[i]];
							cardTmp[notNextWings[i]] = cardTmp[card_num/4*3+i-card_num/4];
							cardTmp[card_num/4*3+i-card_num/4] = tmpcard;
						}
						return card_num;
					}
			}
			break;
		/* 飞机带翅膀:三顺+同数量的对牌 12 */
		case CARD_TYPE_SEQUENCE_THREE_WINGS_DOUBLE: 
			if(nRnum < card_num)
				break;
			if(isc[4]) {
				for(i = 0; i < isc[4]; i++) {
					for(j = 0; j < 3; j++) {
						cardTmp[i*3+j] = nRcards[i*4+j];
					}
					cardTmp[nRnum - i -1] = nRcards[i*4+j];
				}
			}
			for(i = isc[4]*3; i < nRnum - isc[4]; i++) {
				cardTmp[i] = nRcards[i+isc[4]];
			}
			fitc= getFitSeq(cardTmp,nRnum-isc[4]-isc[2]*2-isc[1],pcards[0],card_num-card_num/5*2,3);
			if(fitc >= 0) {
				int notNextWings[card_num/5*2];
				int nextNotWinIndex = card_num/5;
				for(i = 0; i < card_num; i++) {
					tmpcard = cardTmp[fitc + i];
					cardTmp[fitc + i] = cardTmp[i];
					cardTmp[i] = tmpcard;
					if(i % 3 == 0) {
						notNextWings[i/3] = i;
					}
				}
				int hasEmperor = 0;
				for(i = card_num-card_num/4; i < nRnum; i++) {
					int isn = 1;
					for(j = 0; j < nextNotWinIndex; j++) {
						if(hasEmperor && (cardTmp[i] == 57 || cardTmp[i] == 61)) {
							isn = 0;
							break;
						}
						if(!hasEmperor && (cardTmp[i] == 57 || cardTmp[i] == 61))
							hasEmperor = 1;
						if((cardTmp[i] - 1) / 4 == (cardTmp[notNextWings[j]] - 1) / 4) {
							isn = 0;
							break;
						}
						if(i== nRnum -1 || (cardTmp[i] - 1) / 4 != (cardTmp[i+1] - 1) / 4) {
							i++;
							isn = 0;
							break;
						}
					}
					if(isn) {
						cardTmp[nextNotWinIndex++] = i;
					}
				}
				
					if (nextNotWinIndex == card_num/5*2) {
						for(i = card_num/5;i < nextNotWinIndex; i++) {
							tmpcard = cardTmp[notNextWings[i]];
							cardTmp[notNextWings[i]] = cardTmp[card_num/5*3+i-card_num/5];
							cardTmp[card_num/4*3+i-card_num/4] = tmpcard;
							tmpcard = cardTmp[notNextWings[i]+1];
							cardTmp[notNextWings[i]+1] = cardTmp[card_num/5*3+i-card_num/5+1];
							cardTmp[card_num/5*3+i-card_num/5+1] = tmpcard;
						}
						return card_num;
					}
			}
			break;
		/* 四带两个单牌 13 */
		case CARD_TYPE_FOUR_DOUBLE_SIGNAL: 
			if(nRnum < card_num)
				break;
			if(!isc[4])
				break;
			if(isc[4]+isc[3]+isc[2]+isc[1] < 3)
				break;
			windex = 0;
			for(i = 0; i < isc[4]; i++) {
					if(nRcards[i * 4] > pcards[0]) {
						windex = 0;
						withSinal[windex++] = i*4;
						if(isc[1]) {
							if(!(isc[1] == 2 && nRcards[start[1]] == 57 && nRcards[start[1]] == 61)) {
								withSinal[windex++] = start[1];
								if (isc[1] > 1)
								{
									withSinal[windex++] = start[1]+1;
								}
							}
						}
						if(windex < 3 && isc[2]) {
							withSinal[windex++] = start[2];
							if(windex < 3 && isc[2] > 1)
								withSinal[windex++] = start[2]+2;
						}
						if(windex < 3 && isc[3]) {
							withSinal[windex++] = start[3];
							if(windex < 3 && isc[3] > 1)
								withSinal[windex++] = start[3]+3;
						}
						if(windex < 3 && isc[4]) {
							int start4 = 0;
							if((nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
								withSinal[windex++] = start4;
							start4 += 4;
							if(windex < 3 && isc[4] > 1 && (nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
								withSinal[windex++] = start4;
							start4 += 4;
							if(windex < 3 && isc[4] > 2 && (nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
								withSinal[windex++] = start4;
								
						}
						if(windex == 3) {
							for(j = 0; j < 4; j++) {
								tmpcard = nRcards[withSinal[0]];
								nRcards[withSinal[0]] = nRcards[j];
								nRcards[j] = tmpcard;
							}
							for(j = 1; j < 3; j++) {
								tmpcard = nRcards[withSinal[j]];
								nRcards[withSinal[j]] = nRcards[3+j];
								nRcards[3+j] = tmpcard;
							}
							return card_num;
						}
							
					}
			}

			break;
			/* 四带两对 14 */
			case CARD_TYPE_FOUR_DOUBLE_DOUBLE: 
				if(nRnum < card_num)
					break;
				if(!isc[4])
					break;
				if(isc[4]+isc[3]+isc[2]+isc[1] < 3)
					break;
				int withSinal[3];
				int windex = 0;
				for(i = 0; i < isc[4]; i++) {
						if(nRcards[i * 4] > pcards[0]) {
							windex = 0;
							withSinal[windex++] = i*4;
							if(isc[2]) {
								withSinal[windex++] = start[2];
								if(windex < 3 && isc[2] > 1)
									withSinal[windex++] = start[2]+2;
							}
							if(windex < 3 && isc[3]) {
								withSinal[windex++] = start[3];
								if(windex < 3 && isc[3] > 1)
									withSinal[windex++] = start[3]+3;
							}
							if(windex < 3 && isc[4]) {
								int start4 = 0;
								if((nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
									withSinal[windex++] = start4;
								start4 += 4;
								if(windex < 3 && isc[4] > 1 && (nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
									withSinal[windex++] = start4;
								start4 += 4;
								if(windex < 3 && isc[4] > 2 && (nRcards[start4] -1)/4 != (nRcards[i*4]-1)/4)
									withSinal[windex++] = start4;
									
							}
							if(windex == 3) {
								for(j = 0; j < 4; j++) {
									tmpcard = nRcards[withSinal[0]];
									nRcards[withSinal[0]] = nRcards[j];
									nRcards[j] = tmpcard;
								}
								for(j = 0; j < 1; j++) {
									tmpcard = nRcards[withSinal[j+1]];
									nRcards[withSinal[j+1]] = nRcards[4+j*2];
									nRcards[4+j*2] = tmpcard;
									tmpcard = nRcards[withSinal[j+1]+1];
									nRcards[withSinal[j+1]+1] = nRcards[4+j*2+1];
									nRcards[4+j*2+1] = tmpcard;
								}
								return card_num;
							}
								
						}
				}
				break;

				case CARD_TYPE_ERROR:
					return 0;
				default :
					break;
	}
	

	
	/*
	if(*ctype == CARD_TYPE_FOUR_BOMB) {
		fitR = 0;
		for(i = 0;i < isc[4]; i++) {
			if(nRcards[i*4] > pcards[0]) {
				fitR = i + 1;
				break;
			}
		}
	}
	*/
	/*
	int fitR = 1;
	if(fitR) {
		*ctype = CARD_TYPE_FOUR_BOMB;
		for(i = 0; i < 4; i++) {
			tmpcard = nRcards[(fitR-1)*4+i];
			nRcards[(fitR-1)*4+i] = nRcards[i];
			nRcards[i] = tmpcard;
		}
		return 4;
	}
	if(isRock) {
		*ctype = CARD_TYPE_ROCKET;
		for(i = 0; i < 2; i++) {
			tmpcard = nRcards[nRnum-2+i];
			nRcards[nRnum-2+i] = nRcards[i];
			nRcards[i] = tmpcard;
		}
		return 2;
	}
	*/
	return 0;
}

static int getFitSeq(unsigned char *cards,int card_num,unsigned char preStart,int preCount,int fitValue) {
	int i;
	int rvalue = -1;
	printf("card_num=%d,cards: ",card_num);
	for (i = 0;i < card_num;i++) {
		printf("%d,",(cards[i]-1) / 4 + 3);
	}
	printf("\n");
	if(card_num < preCount)
		return -1;
	sort_card(cards,card_num);
	for(i = 0; i < card_num / fitValue; i++) {
		printf("i=%d,cardvalue=%d\n",i,(cards[i*fitValue] - 1) / 4 + 3);
		if((cards[i*fitValue] - 1) / 4 > (preStart - 1) / 4) {
			break;
		}
	}

	if(i > 0 && ((cards[i*fitValue-fitValue] - 1) / 4 > (preStart - 1) / 4)) {
		printf("(cards[i*fitValue-fitValue] - 1) / 4=%d\n",(cards[i*fitValue-fitValue] - 1) / 4);
		i--;
	}
	if(card_num - i * fitValue < preCount)
		return -1;
	for(; i <= (card_num - preCount) / fitValue; i++) {
		printf("i=%d,fitValue=%d\n",i,fitValue);
		if(cardsIsNumSequence(cards + i * fitValue,preCount,fitValue)) {
			rvalue = i * fitValue;
			break;
		}
	}
	printf("rvalue=%d,fitValue=%d\n",rvalue,fitValue);
	return rvalue;
}

 

你可能感兴趣的:(游戏,J#)