One By One扑克牌游戏(C++)
用我们方言说就是类似“骡子冲”的游戏,游戏双方各拿一定数目的扑克牌,每次每个人打一张牌,排成一列。如果打出的牌有一样的,那么这两张牌(包括这两张牌),全部按顺序拿到打出第二张相同牌的玩家手中,且放在手中牌底。最后,谁先把牌打完,谁输。
思路:
- 将出牌双方看成两个队列,将桌子看成栈。
- 队列中,一个变量依次增加表示打出第几张牌,第二个变量表示经手的牌的总数(包括打出和拿到的),使用容器保存手中的牌。
- 栈中,一个变量表示桌子上牌的数量-1(top),使用容器储存牌,top访问。
- 在主函数中,创建一个容器用于标记全部牌的数量,传入到游戏进行函数中。
注意C++版本的栈(桌子)因为牌数量的变化,添加打出的牌的方式也会不同,下标添加或者push_back()。
#include <iostream> #include <vector> #include <ctime> using namespace std; struct poker { vector<int> data;//储存手中的牌 int ShCard;//表示打出的第几张牌 int ReCard;//表示经手的牌的总数 }; struct tack { vector<int> data;//储存桌面上的牌 int pop;//表示栈顶 }; void Game(poker *val, tack *sal, vector<int> &vec) { int temp = val->data[val->ShCard]; if (vec[temp] == 0) {//当打出的牌在桌面上不存在 ++(val->ShCard);//下次出牌序列加一 ++(sal->pop);//桌面上的牌加一,对尾向后移动 if (sal->pop >= static_cast<int>(sal->data.size()))//因为桌面上的牌,存在被收走或是增加,所以需要判断 sal->data.push_back(temp); else sal->data[sal->pop] = temp; vec[temp] = 1;//标记牌面 } else {//当打出的牌在桌面上存在 ++(val->ShCard); val->data.push_back(temp);//将牌收回到手牌尾部 ++(val->ReCard);//经手手牌总数加一 while (sal->data[sal->pop] != temp) {//循环拿取桌面上的牌,直到再次遇到和打出牌,牌面相同的牌 vec[sal->data[sal->pop]] = 0;//标记清零 val->data.push_back(sal->data[sal->pop]);//桌面拿牌 --(sal->pop);//桌面队尾前移 ++(val->ReCard);//经手手牌总数加一 } //最后一张需要拿的牌,和打出牌牌面相同的牌 vec[sal->data[sal->pop]] = 0; val->data.push_back(sal->data[sal->pop]); --(sal->pop); ++(val->ReCard); } } //输出牌面信息函数 void Display(poker *Value) { for (int i = Value->ShCard; i < Value->ReCard; ++i) { cout << Value->data[i] << " "; } cout << endl; } int main() { int n = 1; vector<int> arr(16, 0); poker p1, p2; tack t; t.pop = -1; p1.ReCard = 0; p1.ShCard = 0; p2.ReCard = 0; p2.ShCard = 0; srand((unsigned)time(NULL)); for (int i = 0; i < 8; ++i) {//初始化,随机拿牌8张 int temp = rand() % 13 + 1; p1.data.push_back(temp); ++(p1.ReCard); } for (int i = 0; i < 8; ++i) { int temp = rand() % 13 + 1; p2.data.push_back(temp); ++(p2.ReCard); } cout << "刚开始时,David和Jack的牌:" << endl; Display(&p1); Display(&p2); while (p1.ReCard > p1.ShCard && p2.ReCard > p2.ShCard) { /*循环判断的条件是,一个可以想象队头和队尾,ShCard队头,ReCard队尾,打出一张牌 队头加一,表示下次打出下一张牌,获得一张牌,队尾后移加一,表示经手牌总数加一, 当两者相同,表示将手中的牌打完。 */ Game(&p1, &t, arr); Game(&p2, &t, arr); //输出牌面信息 cout << "第" << n << "轮" << endl; cout << "David手中的牌:"; Display(&p1); cout << "Jack手中的牌:"; Display(&p2); ++n; cout << "桌上的牌:"; for (int i = 0; i <= t.pop; ++i) { cout << t.data[i] << " "; } cout << endl; cout << endl; } if (p2.ShCard == p2.ReCard) { cout << "David赢!" << endl; cout << "手中还有" << p1.ReCard - p1.ShCard << "张牌" << endl; } else { cout << "Jack赢!" << endl; cout << "手中还有" << p2.ReCard - p2.ShCard << "张牌" << endl; } system("PAUSE"); return 0; }