- C20250020's blog
uno
- 2023-11-24 10:18:05 @
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;
}