首页 > 技术文章 > One By One扑克牌游戏(C++)

Mayfly-nymph 2018-12-29 22:27 原文

用我们方言说就是类似“骡子冲”的游戏,游戏双方各拿一定数目的扑克牌,每次每个人打一张牌,排成一列。如果打出的牌有一样的,那么这两张牌(包括这两张牌),全部按顺序拿到打出第二张相同牌的玩家手中,且放在手中牌底。最后,谁先把牌打完,谁输。

 

思路:

  • 将出牌双方看成两个队列,将桌子看成栈。
  • 队列中,一个变量依次增加表示打出第几张牌,第二个变量表示经手的牌的总数(包括打出和拿到的),使用容器保存手中的牌。
  • 栈中,一个变量表示桌子上牌的数量-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;
}

 

推荐阅读