现在的位置: 首页 > 综合 > 正文

扑克牌斗牛游戏

2012年12月22日 ⁄ 综合 ⁄ 共 8215字 ⁄ 字号 评论关闭

2013-02-14 wcdj  大年初五,情人节

过年和家人玩扑克牌斗牛游戏(地道的发音是 Dou Ou),规则很简单,每个人发五张牌,如果三张牌之和是10,20或30则称为一个牛(Ou),其余两张牌相加之和模10,若没有牛则选最大的一张牌进行大小点比较,若大小点一样则再比较黑红梅方,玩家人数不限,一个人做庄,然后拿点零花钱,后面就看各自的运气了。

抽空将此游戏简单用代码实现了下,一些地方还可以优化。

// 2013-02-14 wcdj

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#include <time.h>

using namespace std;


// 每人总共发5张牌
#define PK_NUM 5
// 扑克牌总共40张, 1到10, 黑红梅方
#define PK_TOTAL_NUM 40

const string pk[PK_TOTAL_NUM] = {
							"1d","1c","1b","1a",
							"2d","2c","2b","2a",
							"3d","3c","3b","3a",
							"4d","4c","4b","4a",
							"5d","5c","5b","5a",
							"6d","6c","6b","6a",
							"7d","7c","7b","7a",
							"8d","8c","8b","8a",
							"9d","9c","9b","9a",
							"10d","10c","10b","10a", };

const string pk_des[PK_TOTAL_NUM] = {
							"黑桃1","红桃1","梅花1","方片1",
							"黑桃2","红桃2","梅花2","方片2",
							"黑桃3","红桃3","梅花3","方片3",
							"黑桃4","红桃4","梅花4","方片4",
							"黑桃5","红桃5","梅花5","方片5",
							"黑桃6","红桃6","梅花6","方片6",
							"黑桃7","红桃7","梅花7","方片7",
							"黑桃8","红桃8","梅花8","方片8",
							"黑桃9","红桃9","梅花9","方片9",
							"黑桃10","红桃10","梅花10","方片10" };

typedef struct st_Player {
	// 玩家名字
	char szName[64];
	// 玩家是否是庄家
	bool bIsMasterPlayer;
	// 玩家的游戏币数量
	int iCoins;
    // 玩家随机选取的扑克
	string strPKList[PK_NUM];
	// 玩家赢的次数
	int iWinNum;
	// 玩家输的次数
	int iLoseNum;
	// 最大扑克
    int iMaxPK;
    string strMaxPK;
    string strMaxPKDes;

} stPlayer;

// 玩家的数量
int iPlayerNum = 0;
// 庄家只能有一个
bool bHasChoosedMasterPlayer = false;
// 玩家列表
vector<stPlayer> vecPlayer;
// 随机选牌用
string pk_bak[PK_TOTAL_NUM];
int iChoosed = 0;
// 扑克描述map
map<string, string> mapPK;


int PrintPlayerInfo(stPlayer &player)
{
	if (player.bIsMasterPlayer)
		printf("庄家【%s】:赢【%d】输【%d】剩余游戏币【%d】\n",
				player.szName, player.iWinNum, player.iLoseNum, player.iCoins);
	else
		printf("玩家【%s】:赢【%d】输【%d】剩余游戏币【%d】\n",
				player.szName, player.iWinNum, player.iLoseNum, player.iCoins);

    printf("本局抽中的扑克:【");
    for (int i = 0; i != PK_NUM; ++i)
    {
        if (i == PK_NUM-1)
            printf("%s】", mapPK[player.strPKList[i]].c_str());
        else
            printf("%s\t", mapPK[player.strPKList[i]].c_str());
    }

    return 0;

}

int RandChoosePK(stPlayer &player)
{
    for(int i = 0; i != PK_NUM; ++i, ++iChoosed)
    {
        // 要剔除已经选过的扑克
        int r = rand() % (PK_TOTAL_NUM - iChoosed);
		// 保存选出的扑克
		player.strPKList[i] = pk_bak[r];
		// 把最后一个元素提到选中的那个元素的位置, 为了效率不改变原数组的顺序
        pk_bak[r] = pk_bak[PK_TOTAL_NUM - iChoosed - 1];
    }

    return 0;
}

int InitPlayerInfo(int idx, stPlayer &player)
{
	printf("\n\n输入玩家%d的名字:", idx);
	scanf("%s", player.szName);

	player.bIsMasterPlayer = false;
	if (bHasChoosedMasterPlayer == false)
	{
		printf("请选择是否当庄家? y/n:");
		char szInput[64] = {0};
		scanf("%s", szInput);
		if (0 == strcmp(szInput, "y")) {
			player.bIsMasterPlayer  = true;
			bHasChoosedMasterPlayer = true;
		}
		else
			player.bIsMasterPlayer = false;
	}

	printf("请【%s】输入要下注的游戏币数量:", player.szName);
	scanf("%d", &player.iCoins);

	player.iWinNum  = 0;
	player.iLoseNum = 0;
	player.iMaxPK   = 0;

	// 开始发牌
	RandChoosePK(player);

	PrintPlayerInfo(player);

	return 0;

}

// 计算是否有牛, 有牛的规则是三张牌加起来等于10/20/30即可
int CalcNiu(stPlayer &player)
{
	// C(3,5)==10, 即三张牌有10种组合情况
	if ( (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[1].c_str())+atoi(player.strPKList[2].c_str())) % 10 == 0 )
	{
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[3].c_str())+atoi(player.strPKList[4].c_str()))%10,
               mapPK[player.strPKList[3]].c_str(), mapPK[player.strPKList[4]].c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[2]].c_str());
	}
	else if ( (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[1].c_str())+atoi(player.strPKList[3].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[2].c_str())+atoi(player.strPKList[4].c_str()))%10,
               mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[4]].c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[3]].c_str());
    }
    else if ( (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[1].c_str())+atoi(player.strPKList[4].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[2].c_str())+atoi(player.strPKList[3].c_str()))%10,
               mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[3]].c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[4]].c_str());
    }
    else if ( (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[2].c_str())+atoi(player.strPKList[3].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[1].c_str())+atoi(player.strPKList[4].c_str()))%10,
               mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[4]].c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[3]].c_str());
    }
    else if ( (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[2].c_str())+atoi(player.strPKList[4].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[1].c_str())+atoi(player.strPKList[3].c_str()))%10,
               mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[3]].c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[4]].c_str());
    }
    else if ( (atoi(player.strPKList[1].c_str())+atoi(player.strPKList[2].c_str())+atoi(player.strPKList[3].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[4].c_str()))%10,
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[4]].c_str(),
               mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[3]].c_str());
    }
    else if ( (atoi(player.strPKList[1].c_str())+atoi(player.strPKList[2].c_str())+atoi(player.strPKList[4].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[3].c_str()))%10,
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[3]].c_str(),
               mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[4]].c_str());
    }
    else if ( (atoi(player.strPKList[1].c_str())+atoi(player.strPKList[3].c_str())+atoi(player.strPKList[4].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[2].c_str()))%10,
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[2]].c_str(),
               mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[3]].c_str(), mapPK[player.strPKList[4]].c_str());
    }
    else if ( (atoi(player.strPKList[2].c_str())+atoi(player.strPKList[3].c_str())+atoi(player.strPKList[4].c_str())) % 10 == 0 )
    {
        printf("牛%d【%s\t%s】【%s\t%s\t%s】\n",
               (atoi(player.strPKList[0].c_str())+atoi(player.strPKList[1].c_str()))%10,
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[1]].c_str(),
               mapPK[player.strPKList[2]].c_str(), mapPK[player.strPKList[3]].c_str(), mapPK[player.strPKList[4]].c_str());
    }
    else
    {
        // 无牛, 则计算最大的扑克点数

        for (int i = 0; i != PK_NUM; ++i)
        {
            if (atoi(player.strPKList[i].c_str()) > player.iMaxPK)
            {
                player.strMaxPK    = player.strPKList[i];
                player.strMaxPKDes = mapPK[player.strPKList[i]];
                player.iMaxPK      = atoi(player.strPKList[i].c_str());
            }
            // 如果点数一样大还要比较黑红梅方, 比如10a和10b
            else if (atoi(player.strPKList[i].c_str()) == player.iMaxPK
                      && strcmp(player.strPKList[i].c_str(), player.strMaxPK.c_str()) > 0)
            {
                player.strMaxPK    = player.strPKList[i];
                player.strMaxPKDes = mapPK[player.strPKList[i]];
                player.iMaxPK      = atoi(player.strPKList[i].c_str());
            }

        }
        printf("无牛, 最大牌为【%s】【%s\t%s\t%s\t%s\t%s】\n",
               player.strMaxPKDes.c_str(),
               mapPK[player.strPKList[0]].c_str(), mapPK[player.strPKList[1]].c_str(), mapPK[player.strPKList[2]].c_str(),
               mapPK[player.strPKList[3]].c_str(), mapPK[player.strPKList[4]].c_str());

    }

	return 0;
}


int main()
{
    // 初始化相关参数
    time_t rawtime;
    struct tm * timeinfo;
    time(&rawtime);
    timeinfo = localtime(&rawtime);
    printf("当前时间:%s", asctime(timeinfo));

	srand((unsigned int)time(0));

    printf("请输入玩家个数:");
	scanf("%d", &iPlayerNum);
	printf("当前玩家个数为:%d\n", iPlayerNum);


	// 游戏开始,
	char szGoOn[64] = "y";
	while (0 == strcmp(szGoOn, "y"))
	{
		// 重置选牌范围
		iChoosed = 0;

		// 重置玩家信息
		vecPlayer.clear();

		// 重选庄家
		bHasChoosedMasterPlayer = false;

        // 重置扑克
        for(int i = 0; i != PK_TOTAL_NUM; ++i)
        {
            // 随机选牌使用
            pk_bak[i] = pk[i];
            // 扑克描述
            mapPK[pk[i]] = pk_des[i];
        }


		// 随机选牌
		for (int i = 0; i != iPlayerNum; ++i)
		{
			stPlayer player;
			InitPlayerInfo(i+1, player);
			vecPlayer.push_back(player);

		}

		// 必须有一个庄家, 没有则重选
		if (!bHasChoosedMasterPlayer)
		{
			printf("\n\n对不起, 游戏中必须有一个庄家, 游戏重新开始\n");
			continue;
		}


		printf("\n\n-----------------------------------------------------\n");
		// 开始斗牛, 计算每个玩家最大的牌
		vector<stPlayer>::iterator iter = vecPlayer.begin();
		for (; iter != vecPlayer.end(); ++iter)
        {
			if (iter->bIsMasterPlayer)
                printf("庄家【%s】:", iter->szName);
            else
                printf("玩家【%s】:", iter->szName);
            CalcNiu(*iter);
        }
		printf("-----------------------------------------------------\n");

		printf("\n\n是否进行下一局呢? y/n:");
		scanf("%s", szGoOn);
	}


    // Game Over
    printf("斗牛游戏结束\n");
    system("pause");

	return 0;
}


上面代码使用CodeBlocks编译成功。

Code::Blocks下载地址:

http://www.codeblocks.org/downloads/binaries 

抱歉!评论已关闭.