Files
collorettoes/ckliu-ver.cpp
ChenKaiLiuG 867c249e63 Upload 1.cpp
Signed-off-by: ChenKaiLiuG <ckliu119@gmail.com>
2025-12-30 06:02:26 +00:00

574 lines
13 KiB
C++

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <string>
#include <array>
#include <algorithm>
#include <windows.h>
using namespace std;
int try_num(string b)
{
int bb;
try
{
bb = stoi(b);
}
catch (invalid_argument)
{
return -1;
}
return bb;
}
string cardname[21];
int score[7];
//define cardname
array<int, 21> calculate(int arr[40])
{
array<int, 21> cal;
fill(cal.begin(), cal.end(), 0);
for (int j = 0; j < 40; j++)
{
if (arr[j] == -1)
continue;
else
cal[arr[j]]++;
}
return cal;
}
//calculate card amount
void display_p(int arr[][40], int num)
{
for (int i = 0; i < num; i++)
{
array<int, 21> cal = calculate(arr[i]);
cout << "Player " << i + 1 << ":";
for (int j = 1; j <= 7; j++)
if (cal[j] != 0)
cout << " " << cardname[j] << "*" << cal[j];
if (cal[10] != 0)
cout << " " << cardname[10] << "*" << cal[10];
if (cal[20] != 0)
cout << " " << cardname[20] << "*" << cal[20];
cout << "\n";
}
}
void display_s(int arr2[][3], int flag[5], int num)
{
for (int i = 0; i < num; i++)
{
cout << "Stack " << i + 1 << ": ";
for (int j = 0; j < 3; j++)
{
if (arr2[i][j] == 1)
cout << " \033[31m red \033[0m";
else if (arr2[i][j] == 2)
cout << " \033[93m orange \033[0m";
else if (arr2[i][j] == 3)
cout << " \033[93m yellow \033[0m";
else if (arr2[i][j] == 4)
cout << " \033[32m green \033[0m";
else if (arr2[i][j] == 5)
cout << " \033[34m blue \033[0m";
else if (arr2[i][j] == 6)
cout << " \033[95m pink \033[0m";
else if (arr2[i][j] == 7)
cout << " \033[0m gray \033[0m";
else if (arr2[i][j] == 10)
cout << " rainbow_colortto ";
else if (arr2[i][j] == 20)
cout << " +2_point ";
}
if (flag[i] == 2)
cout << "(taken)";
cout << "\n";
}
}
void getcard(int deck[76], bool vis[76], int stack[5][3], int flag_s[5], int pynum, int& counter, int cp_chk)
{
if (counter == 16)
{
cout << "\033[91mThis is the last round.\033[0m" << endl;
counter--;
}
int card = -1;
while (true)
{
int a = rand() % 76;
if (vis[a] != true)
{
card = deck[a];
vis[a] = true;
break;
}
}
//initial and random a card
cout << "\033[94mPicked card is [";
if (card == 1)
cout << "\033[31m red \033[0m";
else if (card == 2)
cout << "\033[93m orange \033[0m";
else if (card == 3)
cout << "\033[93m yellow \033[0m";
else if (card == 4)
cout << "\033[32m green \033[0m";
else if (card == 5)
cout << "\033[34m blue \033[0m";
else if (card == 6)
cout << "\033[95m pink \033[0m";
else if (card == 7)
cout << "\033[0m gray \033[0m";
else if (card == 10)
cout << " rainbow_coloretto ";
else if (card == 20)
cout << " +2_point ";
cout << "\033[94m].\033[0m\n";
//display card
int b;
if (cp_chk == 0)
{
cout << "Choose a avaliable stack to add card:";
label_addcard:
string input_b;
cin >> input_b;
b = try_num(input_b);
b--;
}//manual input
else
{
do
{
b = rand() % pynum; //random choose a stack
} while (flag_s[b] != 0); //check stack avaliable
}
if (b >= 0 && b < pynum && flag_s[b] == 0) //check stack avaliable
{
for (int i = 0; i < 3; i++)
{
if (stack[b][i] == -1)
{
stack[b][i] = card;
counter--;
break;
}
}
cout << "\033[92mThere are " << counter << " cards left.\033[0m" << endl;
}
else
{
cout << "Input error,choose avaliable stack again:";
goto label_addcard;
}
//add card to stack
}
void getstack(int arr3[40], int arr4[5][3], int flag[5], int num, int cp_chk)
{
int c;
if (cp_chk == 0)
{
cout << "Choose a stack to get:";
label_getstack:
string input_c;
cin >> input_c;
c = try_num(input_c);
c--;
if (c < 0 || c >= num || flag[c] == 2)
{
cout << "Input error,choose again:";
goto label_getstack;
}
//range of c illeagal
}
//statement of decide stack
else
{
bool ff = false;
do
{
c = rand() % num; //random choose a stack
ff = false;
for (int f = 0; f < 3; f++)
{
if (arr4[c][f] != -1)
ff = true;
}
} while (flag[c] == 2 || ff == false); // check stack is not taken
}
bool ff = false;
for (int f = 0; f < 3; f++)
{
if (arr4[c][f] != -1)
ff = true;
}
if (ff == false)
{
cout << "Input error,choose again:";
goto label_getstack;
}
//choice of c illegal
for (int i = 0; i < 40; i++) //find empty space on player
{
if (arr3[i] == -1)
{
for (int j=0;j<3;j++)
arr3[i+j] = arr4[c][j];
break;
}
}
flag[c] = 2;
}
int main()
{
srand(time(0));
//preparing
cardname[1] = "\033[31m red \033[0m";
cardname[2] = "\033[93m orange \033[0m";
cardname[3] = "\033[93m yellow \033[0m";
cardname[4] = "\033[32m green \033[0m";
cardname[5] = "\033[34m blue \033[0m";
cardname[6] = "\033[95m pink \033[0m";
cardname[7] = " gray ";
cardname[10] = " rainbow_coloretto ";
cardname[20] = " +2_point ";
//calculate owned card
cout << "Enter number of player:";
label_pynum:
string input_pynum; //initial player amount
cin >> input_pynum;
int pynum = try_num(input_pynum);
if (pynum > 5 || pynum < 3)
{
cout << "Input error,enter number of player again:";
goto label_pynum;
}
//enter amount of player
cout << "Enable 1 client(player) mode (enter yes):";
string cpmod;
cin >> cpmod;
cout << "\n";
//check other players become computer
int player[5][40];
int stack[5][3];
for (int p0 = 0; p0 <= 4; p0++)
{
fill(player[p0], player[p0] + 40, -1);
fill(stack[p0], stack[p0] + 3, -1);
}
//initial all array
int cplayer[5];
if (cpmod == "yes" || cpmod == "y")
{
fill(cplayer, cplayer + 5, -1);
cplayer[0] = 0; //player itself
for (int i = 1; i < pynum; i++)
cplayer[i] = 1;
}
//set computer other players
int counter = 77 - pynum;
int allcard[76];
int apcont = 0;
for (int i1 = 1; i1 <= 7; i1++) //append color card
{
/* 7 color red=1
orange=2
yellow=3
green=4
blue=5
pink=6
gray=7 */
for (int j1 = 1; j1 <= 9; j1++)
{
allcard[apcont] = i1;
apcont++;
}
}
for (int k1 = 64; k1 <= 66; k1++) //append rainbow card
{
/* 3 rainbow=10 */
allcard[apcont] = 10;
apcont++;
}
for (int l1 = 67; l1 <= 76; l1++) //append 2point card
{
/* 10 2point=20 */
allcard[apcont] = 20;
apcont++;
}
bool vis[76];
for (int m1 = 0; m1 <= 75; m1++)
vis[m1] = false;
bool vis_chk[7] = { 0,0,0,0,0,0,0 };
for (int n1 = 0; n1 < pynum; n1++)
{
while (true)
{
int x = rand() % 76;
if (allcard[x] >= 1 && allcard[x] <= 7 && vis[x] != true && vis_chk[allcard[x]-1] != true)
{
player[n1][0] = allcard[x];
vis[x] = true;
vis_chk[allcard[x]-1] = true;
break;
}
}
}
//distribute 1st card
//START GAME
int starter = rand() % pynum; //initial starter
label_round:
int flag_p[5] = { -1,-1,-1,-1,-1 }; //initial take stack check
int flag_s[5] = { -1,-1,-1,-1,-1 }; //initial stack full check
/* flag condition flag=-1 ,unused
flag= 0 ,not take/taken
flag= 1 ,player has taken stack/stack is full
flag= 2 ,stack is taken */
fill(flag_p, flag_p + pynum, 0);
fill(flag_s, flag_s + pynum, 0);
//initial flag array
for (int s0 = 0; s0 < 5; s0++)
fill(stack[s0], stack[s0] + 3, -1);
//initial stack
while (true) //a round
{
bool chk_allp = false;
for (int _i2 = starter; _i2 < starter + pynum; _i2++) //chance for each player
{
int i2 = _i2 % pynum; //limit i2 in num
if (flag_p[i2] == 1)
continue;
//player has taken a stack,pass
for (int j2 = 0; j2 < pynum; j2++)
{
if (flag_s[j2] != 2 && stack[j2][0] != -1 && stack[j2][1] != -1 && stack[j2][2] != -1)
flag_s[j2] = 1;
}
//check each stack full
bool chk_alls_e = false;
for (int k2 = 0; k2 < pynum; k2++)
{
for (int l2 = 0; l2 < 3; l2++)
{
if (flag_s[k2] == 2) //if stack is taken,pass
continue;
else if (stack[k2][l2] != -1) //if exist card in stacks,then choose mode
chk_alls_e = true;
}
}
//check all stack empty
bool chk_alls_f = false;
for (int l2 = 0; l2 < pynum; l2++) //check all stack full
{
if (flag_s[l2] == 0) //if exist unfull stacks,then choose mode
chk_alls_f = true;
}
if (cplayer[i2] == 1) //robot action
{
if (chk_alls_e == false)
{
cout << "It's player " << i2 + 1 << "'s turn." << endl;
//display current condition
cout << "Player " << i2 + 1 << " (AI) chooses card.\n";
getcard(allcard, vis, stack, flag_s, pynum, counter, cplayer[1]);
}
else if (chk_alls_f == false) //all stacks are full,choose stack
{
cout << "It's player " << i2 + 1 << "'s turn." << endl;
//display current condition
cout << "Player " << i2 + 1 << " (AI) chooses stack.\n";
getstack(player[i2], stack, flag_s, pynum, cplayer[1]);
flag_p[i2] = 1;
starter = i2;
}
else
{
int action = rand() % 2; // random "card" or "stack" action
if (action == 0)
{
cout << "It's player " << i2 + 1 << "'s turn." << endl;
//display current condition
cout << "Player " << i2 + 1 << " (AI) chooses card.\n";
getcard(allcard, vis, stack, flag_s, pynum, counter, 1);
}
else
{
cout << "It's player " << i2 + 1 << "'s turn." << endl;
//display current condition
cout << "Player " << i2 + 1 << " (AI) chooses stack.\n";
getstack(player[i2], stack, flag_s, pynum, 1);
flag_p[i2] = 1;
starter = i2;
}
}
}
else //human action
{
cout << "It's player " << i2 + 1 << "'s turn." << endl;
cout << "===========================================================" << endl;
display_p(player, pynum);
cout << "-----------------------------------------------------------" << endl;
display_s(stack, flag_s, pynum);
cout << "===========================================================" << endl;
//display current condition
if (chk_alls_e == false)
{
getcard(allcard, vis, stack, flag_s, pynum, counter, cplayer[0]);
}
else if (chk_alls_f == false) //all stacks are full,choose stack
{
getstack(player[i2], stack, flag_s, pynum, cplayer[0]);
flag_p[i2] = 1;
starter = i2;
}
else //choose action todo
{
cout << "Choose action (card or stack):";
label_action:
string input;
cin >> input;
if (input == "card" || input == "c")
{
getcard(allcard, vis, stack, flag_s, pynum, counter, 0);
}
else if (input == "stack" || input == "s")
{
getstack(player[i2], stack, flag_s, pynum, 0);
flag_p[i2] = 1;
starter = i2;
}
else
{
cout << "Input error,choose action again:(Type card or stack)";
goto label_action;
}
}
}
cout << "Player " << i2 + 1 << "'s turn finished.\n" << endl;
Sleep(1000);
for (int m2 = 0; m2 < pynum; m2++)
{
if (flag_p[m2] != 1) //if exist unpinned player,continue this round
chk_allp = true;
}
//check all player pinned
if (chk_allp == false)
break;
}
if (chk_allp == false)
{
cout << "\033[93mThis round is over.\033[0m\n" << endl;
Sleep(1000);
break;
}
}
if (counter > 15)
{
cout << "\033[93mStart new round!\033[0m\n" << endl;
Sleep(1000);
goto label_round;
}
score[1] = 1;
score[2] = 3;
score[3] = 6;
score[4] = 10;
score[5] = 15;
score[6] = 21;
cout << "===========================================================" << endl;
display_p(player, pynum);
cout << "===========================================================" << endl;
int score_p[5];
fill(score_p, score_p + 5, 0);
for (int i3 = 0; i3 < pynum; i3++)
{
array<int, 21> cal = calculate(player[i3]);
score_p[i3] += cal[20] * 2;
cal[20] = 0;
for (int j3 = 1; j3 <= 3; j3++)
{
auto it = max_element(cal.begin(), cal.begin() + 8);
int cardsum = *it;
*it = 0;
//take most coloretto
if (cardsum + cal[10] > 6)
{
cal[10] = cardsum + cal[10] - 6;
cardsum = 6;
}
else
{
cardsum += cal[10];
cal[10] = 0;
}
score_p[i3] += score[cardsum];
}
for (int k3 = 1; k3 <= 7; k3++)
{
int cardsum = cal[k3];
score_p[i3] -= score[cardsum];
}
}
cout << "Ranking:" << endl;
for (int i = 0; i < pynum; i++)
{
auto it = max_element(score_p, score_p + pynum);
cout << i + 1 << " Place: Player " << it - score_p + 1 << ", score: " << *it << endl;
*it = 0;
}
}