#include #include #include #include #include #include #include #include using namespace std; // test input int try_num(string b) { int bb; try { bb = stoi(b); //try int } catch (invalid_argument) // catch invaild input { return -1; } return bb; } string cardname[21]; int score[7]; //define cardname array calculate(int arr[40]) { array cal; fill(cal.begin(), cal.end(), 0); // initilize for (int j = 0; j < 40; j++) { if (arr[j] == -1) continue; // pass blank 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 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"; } } //display players' cards 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++) { // show color by ANSI code 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)"; // mark taken cards cout << "\n"; } } //dispaly stack 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 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; } }