tsqc即同色全出,出掉该颜色所有牌。 不出拿牌输入-1

#include<cstdio>
#include<iostream>
#include<ctime>
#include<algorithm>
#include<windows.h>
#include <stdlib.h>
using namespace std;
struct card{
	int colour,number;
}a[117],x[5][117],diu[117],last2,last;
int card_amount,diu_amount,k[5],point1,point2,first;
bool turn = true;
bool cmp(card ab,card cd){
	if(ab.colour != cd.colour) return ab.colour < cd.colour;
	return ab.number > cd.number;
}
void flash_again(){
	card last0 = diu[diu_amount];
	diu_amount--;
	while(diu_amount){
		card_amount++;
		a[card_amount] = diu[diu_amount];
		diu_amount--;
	}
	diu_amount = 1;
	diu[1] = last0;
	random_shuffle(a + 1,a + card_amount + 1);
	return;
}
void givecard(int person,int amount){
	for(int i = 1;i <= amount;i++){
		k[person]++;
		x[person][k[person]] = a[card_amount];
		card_amount--;
		if(card_amount == 0) flash_again();
	}
//	sort(x[person] + 1,x[person] + k[person] + 1,cmp);
	return;
}
void waiting(){
	int start = time(0),end = time(0);
	while(end - start <= 1) end = time(0);
	return;
}
int use(){
	if(x[first][k[first]].number == 54 && rand() % 7 == 0) return k[first];
	if(x[first][1].colour == x[first][k[first]].colour && x[first][2].number == 13 && x[first][1].colour == last.colour) return 2;
	if(x[first][1].colour == x[first][k[first]].colour && x[first][3].number == 13 && x[first][1].colour == last.colour) return 3;
	for(int i = 1;i <= k[first];i++)
		if(last.colour == x[first][i].colour)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].number == last.number)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].colour == 5)
			return i;
	return -1; 
}
int use(int xx){
	if(x[first][1].colour == x[first][k[first]].colour && x[first][2].number == 13 && x[first][2].colour == diu[diu_amount].colour) return 2;
	if(x[first][1].colour == x[first][k[first]].colour && x[first][3].number == 13 && x[first][1].colour == diu[diu_amount].colour) return 3;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].number == xx && (last.colour == x[first][i].colour || last.number == x[first][i].number))
			return i;
	if(x[first][k[first]].number == 54 && rand() % 7 == 0) return k[first];
	for(int i = 1;i <= k[first];i++)
		if(last.colour == x[first][i].colour)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].number == diu[diu_amount].number)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].colour == 5)
			return i;
	return -1;
}
int use(int xx,bool b){
	if(x[first][1].colour == x[first][k[first]].colour && x[first][2].number == 13 && x[first][1].colour == diu[diu_amount].colour) return 2;
	if(x[first][1].colour == x[first][k[first]].colour && x[first][3].number == 13 && x[first][1].colour == diu[diu_amount].colour) return 3;
	if(last.colour == x[first][xx].colour || last.number == x[first][xx].number)
		return xx;
//	if(x[first][k[first]].number == 54 && rand() % 4 == 0) return k[first];
	for(int i = 1;i <= k[first];i++)
		if(last.colour == x[first][i].colour)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].number == diu[diu_amount].number)
			return i;
	for(int i = 1;i <= k[first];i++)
		if(x[first][i].colour == 5)
			return i;
	return -1;
}
int nnext(){
	if(turn) return first % 4 + 1;
	else return(first + 2) % 4 + 1;
}
int llast(){
	if(!turn) return first % 4 + 1;
	else return(first + 2) % 4 + 1;
}
void usecard(int xx){
	if(first != 4){
		printf("等待玩家%d出牌......\n",first);
		waiting();
//		waiting();
	}
	if(xx == -1){
		printf("由于玩家%d不想出牌,所以获得牌堆顶一张牌。\n",first);
		givecard(first,1);
		if(x[first][k[first]].colour != last.colour && x[first][k[first]].number != diu[diu_amount].number && x[first][k[first]].colour != 5) return;
		if(first != 4){
			usecard(k[first]);
			return;
		}
		else{
			SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
			printf("获得了:\n");
			switch(x[4][k[4]].colour){
				case 1:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY | FOREGROUND_RED);break;
				case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
				case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
				case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
				case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
			}
//			printf("{%d}",i);
			switch(x[4][k[4]].number){
				case 11:printf("转向 ");break;
				case 12:printf("禁止 ");break;
				case 13:printf("TSQC ");break;
				case 14:printf("+[2] ");break;
				case 50:printf("WILD ");break;
				case 54:printf("+[4] ");break;
				default:printf("(0%d) ",x[4][k[4]].number);break;
			}
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
				printf("保留(0)还是打出(1)?\n");
				bool b;
				cin >> b;
				if(b){
					usecard(k[first]);
					return;
				}
				else return;
			}
	printf("\n");
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
	last2 = last;
	if(x[first][xx].number / 10 != 5) printf("玩家%d出",first);
	switch(x[first][xx].colour){
		case 1:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);break;
		case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
		case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
		case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
		case 5:break;
	}
	switch(x[first][xx].number){
		case 11:printf("转向 ");break;
		case 12:printf("禁止 ");break;
		case 13:printf("TSQC ");break;
		case 14:printf("+[2] ");break;
		case 50:break;
		case 54:break;
		default:printf("(0%d) ",x[first][xx].number);break;
	}
	diu_amount++;
	last = x[first][xx];
	diu[diu_amount] = x[first][xx];
	x[first][xx] = x[first][k[first]];
	k[first]--;
	sort(x[first] + 1,x[first] + k[first] + 1,cmp);
	if(last.colour == 5){
		if(first == 4){
			printf("你要换成什么颜色(1红,2黄,3蓝,4绿)\n");
			int abc;
			scanf("%d",&abc);
			last.colour = abc;
			last.number = diu[diu_amount].number;
		}
		else{
			int cc[5] = {};
			for(int i = 1;i <= k[first];i++)
				cc[x[first][i].colour]++;
			first = nnext();
			first = nnext();
			for(int i = 1;i <= k[first];i++)
				cc[x[first][i].colour]++;
			first = nnext();
			first = nnext();
			int ccc = 1;
			for(int i = 1;i <= 4;i++)
				if(cc[i] > cc[ccc]) ccc = i;
			if(k[first] == 1) ccc = x[first][1].colour;
			first = nnext();
			first = nnext();
			if(k[first] == 1) ccc = x[first][1].colour;
			first = nnext();
			first = nnext();
			last.colour = ccc;
			last.number = diu[diu_amount].number ;
			printf("玩家%d出",first);
			switch(last.colour){
				case 1:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);break;
				case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
				case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
				case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
				case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
			}
			if(last.number == 50) printf("WILD");
			else printf("+[4]");
		}
	}
	if(last.number == 13){
		printf("\n丢弃的牌有:\n");
		switch(last.colour){
			case 1:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);break;
			case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
			case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
			case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
			case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
		}
		diu_amount--;
		for(int i = 1;i <= k[first];i++){
			if(x[first][i].colour == last.colour){
				switch(x[first][i].number){
					case 11:printf("转向 ");break;
					case 12:printf("禁止 ");break;
					case 13:printf("TSQC ");break;
					case 14:printf("+[2] ");break;
					default:printf("(%d) ",x[first][i].number);break;
				}
				diu_amount++;
				diu[diu_amount] = x[first][i];
				x[first][i] = x[first][k[first]];
				k[first]--;
				i--;
				sort(x[first] + 1,x[first] + k[first] + 1,cmp);
				printf(" ");
			}
		}
		diu_amount++;
		diu[diu_amount] = last;
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
	printf("\n");
	return; 
}
bool game(){
	if(point1 > 500) return false;
	if(point2 > 500) return true;
	srand(time(NULL));
	for(int i = 1;i <= 4;i++){
		for(int j = 0;j <= 28;j++){
			if(j / 2 == 10) continue;
			card_amount++;
			a[card_amount].colour = i;
			a[card_amount].number = j / 2;
		}
		card_amount++;
		a[card_amount].colour = 5;
		a[card_amount].number = 50;
		card_amount++;
		a[card_amount].colour = 5;
		a[card_amount].number = 54;
	}
	diu_amount++;
	diu[diu_amount] = a[card_amount];
	last = diu[diu_amount];
	card_amount--;
	first = rand() % 4 + 1;
	random_shuffle(a + 1,a + card_amount + 1);
	random_shuffle(a + 1,a + card_amount + 1);
	random_shuffle(a + 1,a + card_amount + 1);
	random_shuffle(a + 1,a + card_amount + 1);
	for(int i = 1;i <= 4;i++) givecard(i,7);
	for(int person = 1;person <= 4;person++) sort(x[person] + 1,x[person] + k[person] + 1,cmp);
	while(diu[diu_amount].colour == 5 || diu[diu_amount].number == 11 || diu[diu_amount].number == 13){
		card_amount++;
		random_shuffle(a + 1,a + card_amount + 1);
		diu[diu_amount] = a[card_amount];
		card_amount--;
	}
	last = diu[diu_amount];
	for(int i = 1;i <= 4;i++) x[i][0].colour = 1;
	while(k[1] * k[2] * k[3] * k[4]){
		if(last.number  == 11){
			turn = !turn;
			first = nnext();
			first = nnext();
			last.number = 111;
			continue;
		}
		if(last.number  == 14){
			givecard(first,2);
			sort(x[first] + 1,x[first] + k[first] + 1,cmp);
			if(turn) first = first % 4 + 1;
			else first = (first + 2) % 4 + 1;
			last.number = 114;
			continue;
		}
		if(last.number  == 12){
			first = nnext();
			last.number = 112;
			continue;
		}
		if(last.number == 54){
			int person;
			if(first == 4){
				printf("上家使用+4,你是否质疑?(1表示质疑,0表示不质疑)\n");
				bool b;
				cin >> b;
				if(b == 0){
					givecard(4,4);
					person = first;
					sort(x[person] + 1,x[person] + k[person] + 1,cmp);
					if(turn) first = first % 4 + 1;
					else first = (first + 2) % 4 + 1;
					last.number = 154;
					continue;
				}
				else{
					card aaaaa = last;
					last = last2;
					first = llast();
					if(use(50,1) != -1 && use(50,1) != 54){
						givecard(first,6);
						person = first;
						sort(x[person] + 1,x[person] + k[person] + 1,cmp);
						first = nnext();
						printf("质疑成功!\n");
//						first = nnext();
					}
					else{
						printf("质疑失败\n");
						first = nnext();
						givecard(first,6);
						person = first;
						sort(x[person] + 1,x[person] + k[person] + 1,cmp);
						first = nnext();
						person = first;
						last = aaaaa;
						continue;
					}
					last = aaaaa;
					last.number = 154;
				}
			}
			else{
				bool b = false;
				if(k[llast()] >= 8) b = true;
				if(k[nnext()] == 1) b = true;
				if((rand() % 7) < 2) b = true;
				if(b == 0){
					givecard(first,4);
					person = first;
					sort(x[person] + 1,x[person] + k[person] + 1,cmp);
					if(turn) first = first % 4 + 1;
					else first = (first + 2) % 4 + 1;
					last.number = 154;
					continue;
				}
				else{
					card aaaaa = last;
					last = last2;
					first = llast();
					if(use(50,1) != -1 && use(50,1) != 54){
						givecard(first,4);
						person = first;
						sort(x[person] + 1,x[person] + k[person] + 1,cmp);
						first = nnext();
						printf("质疑成功!\n");
//						first = nnext();
					}
					else{
						printf("质疑失败\n");
						first = nnext();
						givecard(first,6);
						person = first;
						sort(x[person] + 1,x[person] + k[person] + 1,cmp);
						first = nnext();
						person = first;
						last = aaaaa;
						last.number = 154;
						continue;
					}
					last = aaaaa;
					last.number = 154;
				}
			}
		}
		printf("弃牌堆顶的牌:");
		switch(last.colour){
			case 1:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);break;
			case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
			case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
			case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
			case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
		}
		switch(last.number){
			case 11:printf("转向 ");break;
			case 111:printf("转向 ");break;
			case 12:printf("禁止 ");break;
			case 112:printf("禁止 ");break;
			case 13:printf("TSQC ");break;
			case 113:printf("TSQC ");break;
			case 14:printf("+[2] ");break;
			case 114:printf("+[2] ");break;
			case 50:printf("WILD ");break;
			case 54:printf("+[4] ");break;
			case 154:printf("+[4] ");break;
			default:printf("(0%d) ",last.number);break;
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
		printf("\n");
//		if(last.number == 112) last.number = 12;
		printf("由玩家%d出牌......\n",first);
		for(int i = 1;i <= 4;i++) sort(x[i] + 1,x[i] + k[i] + 1,cmp);
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
		printf("你的牌:\n");
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
		for(int i = 1;i <= k[4];i++){
			if(x[4][i].colour != x[4][i - 1].colour){
				if(i != 1) printf("\n");
				switch(x[4][i].colour){
					case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
					case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
					case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
					case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
				}
			}
			printf("{%d}",i);
			switch(x[4][i].number){
				case 11:printf("转向 ");break;
				case 12:printf("禁止 ");break;
				case 13:printf("TSQC ");break;
				case 14:printf("+[2] ");break;
				case 50:printf("WILD ");break;
				case 54:printf("+[4] ");break;
				default:printf("(0%d) ",x[4][i].number);break;
			}
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
		printf("\n你队友的牌:\n");
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);
		for(int i = 1;i <= k[2];i++){
			if(x[2][i].colour != x[2][i - 1].colour){
				if(i != 1) printf("\n");
				switch(x[2][i].colour){
					case 2:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED);break;
					case 3:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);break;
					case 4:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);break;
					case 5:SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);break;
				}
			}
			switch(x[2][i].number){
				case 11:printf("转向 ");break;
				case 12:printf("禁止 ");break;
				case 13:printf("TSQC ");break;
				case 14:printf("+[2] ");break;
				case 50:printf("WILD ");break;
				case 54:printf("+[4] ");break;
				default:printf("(0%d) ",x[2][i].number);break;
			}
		}
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE);
		printf("\n各个玩家的手牌数目:\n玩家1:%d\n玩家2:%d\n玩家3:%d\n玩家4:%d\n",k[1],k[2],k[3],k[4]);
		if(first != 4){
			if(rand() % 6 == 0 && k[(first + 1) % 4 + 1] == 1 && x[first][k[first]].number == 54) usecard(k[first]);
			else usecard(use());
		}
			else{
				int aa = 10000;
				while((aa > k[first]) || (x[4][aa].colour != 5 && x[4][aa].colour != last.colour && x[4][aa].number != last.number && aa != -1)){
					printf("你要使用第几张卡?\n");
					scanf("%d",&aa);
				}
				usecard(aa);
			}
			if(turn) first = first % 4 + 1;
			else first = (first + 2) % 4 + 1;
	}
	if(k[1] * k[3] == 0){
	for(int i = 1;i <= k[2];i++){
		switch(x[2][i].number){
			case 54:point1 += 50;break;
			case 11:point1 += 20;break;
			case 12:point1 += 20;break;
			case 13:point1 += 20;break;
			case 14:point1 += 20;break;
			default:point1 += x[2][i].number;break;
			}
		}
		for(int i = 1;i <= k[4];i++){
			switch(x[4][i].number){
				case 54:point1 += 50;break;
				case 11:point1 += 20;break;
				case 12:point1 += 20;break;
				case 13:point1 += 20;break;
				case 14:point1 += 20;break;
				default:point1 += x[4][i].number;break;
			}
		}
		printf("你于本局游戏输了\n现在的比分: \n敌%d:%d我\n",point1,point2);
	}
	else{
		for(int i = 1;i <= k[1];i++){
			switch(x[1][i].number){
				case 54:point2 += 50;break;
				case 11:point2 += 20;break;
				case 12:point2 += 20;break;
				case 13:point2 += 20;break;
				case 14:point2 += 20;break;
				default:point2 += x[1][i].number;break;
			}
		}
		for(int i = 1;i <= k[3];i++){
			switch(x[3][i].number){
				case 54:point2 += 50;break;
				case 11:point2 += 20;break;
				case 12:point2 += 20;break;
				case 13:point2 += 20;break;
				case 14:point2 += 20;break;
				default:point2 += x[3][i].number;break;
			}
		}
		printf("你于本局游戏赢了\n现在的比分: \n敌%d:%d我\n",point1,point2);
	}
	waiting();
	waiting();
	waiting();
	for(int i = 1;i <= 4;i++) k[i] = 0;
	system("cls");
	return game();
}
int main(){
	printf("欢迎来到[uno]游戏!\n本局游戏采用的规则: tsqc\n");
	if(game()) printf("你赢了!\n");
	else printf("你输了。\n");
	return 0;
}