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下载地址: