我可能是个比较乱的目录

  • 斗牛规则
  • 创建牌库
  • 删除牌库
  • 洗牌
  • 扑克的打印
  • 扑克牌相关函数试验
  • 按照斗牛规则发牌
  • 游戏的实现
  • 未来可改进
  • 全部源码

与女朋友喜欢玩斗牛纸牌游戏。一直想用C语言实现发牌,今天终于决定要写了。经过测试效果不错。

斗牛规则

可能各地区规则有所差异。我们使用的规则是,牌库只有A至10。是每人依次抽五张纸牌。使用其中三张组合成10的整倍数,剩余两张对10取余数即是玩家点数。比较玩家之间的点数大小。点数大的获胜。

创建牌库

扑克牌一共52张加两张大小王。所以可以使用1 ~ 54来表示牌面和花色。其中:
1 ~ 13表示【红桃A】 ~ 【红桃K】;
14 ~ 26表示【方片A】 ~ 【方片K】;
27 ~ 39表示【方片A】 ~ 【方片K】;
40 ~ 52表示【方片A】 ~ 【方片K】;
53表示【小王】,54表示【大王】。

由此有了一个清晰的创建牌库的思路,即创建一个1 ~ 45的数列即可。

static char Poker_num[13][3]= { "A","2","3","4","5","6","7","8","9","10","J","Q","K" };
static char Poker_col[4][5] = { "红桃","方片","黑桃","梅花"}; typedef int PokerChar ;
typedef struct Poker_Type
{PokerChar Card[54];
}Poker_Typedef;/*创建扑克牌库*/
Poker_Typedef* Create_Poker (void)
{Poker_Typedef* temp;temp = (Poker_Typedef*)malloc (sizeof (PokerChar) * 54);if (temp == NULL){printf ("创建扑克牌库失败 ( > _ < )!\r\n");return NULL;}return temp;
}/*初始化扑克牌*/
void Poker_Init (Poker_Typedef* poker)
{int i = 0;for (i; i < 54; i++){poker->Card[i] = i + 1;}
}

删除牌库

因为使用的是动态分配内存,所以需要释放内存。

/*删除扑克牌库*/
void Delete_Poker (Poker_Typedef* poker)
{Poker_Init (poker);free (poker);
}

洗牌

洗牌即是重复多次随机抽取两张扑克互换位置。

/*洗牌*/
void Shuffle_Poker (Poker_Typedef* poker, int times)
{int i = 0;int a = 0, b = 0;PokerChar temp_card =0;srand ((unsigned)time (NULL));   //设置随机数种子for(i = 0; i< times; i++){//rand()%(b-a+1)+aa = rand() % 54;  /*下标取值范围0~53*/b = rand() % 54;temp_card = poker->Card[a];poker->Card[a] = poker->Card[b];poker->Card[b] = temp_card;}
}

扑克的打印

我们需要将每一张牌显示出来,简单思考一下我们的牌库规则,就可以想到:
任何一张牌非王牌对13取余得到的结果就应该是牌面的大小,如果是13的整倍数得到的结果是0。任何一张非王牌对13取整得到的结果可以得到花色的结果。所以需要先处理两张王牌,其他的牌就可以进行取整和取余计算。

在做这步之前我们需要对牌面的数组进行调整。原因是当扑克牌为13的倍数时取整结果为0,所以我们可以将“K”放在 Poker_num[0][3]。

/*打印单张牌面*/
void Print_Card (PokerChar card)
{int color = NULL;int num = NULL;if ((card < 1) || (card > 54)){printf ("你拿了张假牌吧!(= o =).z Z\r\n");}else{if (card == 53){printf ("【 小王 】 ");}else if (card == 54){printf ("【 大王 】 ");}else{if (card % 13 == 0){color = card / 13 - 1;}else{color = card / 13;      /*得到花色*/}num = card % 13;        /*得到牌面*/printf ("【%s%2s】 ", Poker_col[color],Poker_num[num] );}}
}
/*打印整副牌面*/
void Print_Poker(Poker_Typedef* poker)
{int i = 0;printf("整副扑克牌是:\r\n");for (i = 0; i < 54; i++){if (i % 13 == 0)    /*打印13张就换行显示*/{printf("\r\n");}Print_Card(poker->Card[i]);}printf("\r\n 扑克牌展示完毕(O^u^O)\r\n");
}

扑克牌相关函数试验

完成上面内容后可以测试一下扑克牌相关函数的效果。

/*打印整副牌面*/
void Print_Poker(Poker_Typedef* poker)
{int i = 0;printf("整副扑克牌是:\r\n");for (i = 0; i < 54; i++){if (i % 13 == 0)    /*打印13张就换行显示*/{printf("\r\n");}Print_Card(poker->Card[i]);}printf("\r\n 扑克牌展示完毕(O^u^O)\r\n");
}
/*测试洗牌函数使用*/
int Test_Shuffle_Poker (void)
{Poker_Typedef* POKER_Niuniu;std::cout << "创建一副扑克 ...(* ̄0 ̄)/\n";POKER_Niuniu = Create_Poker ();     /*创建扑克牌*/if (!POKER_Niuniu) {return 0;}Poker_Init (POKER_Niuniu);            /*初始化扑克牌*/Print_Poker(POKER_Niuniu);             /*打印扑克牌*/std::cout << "开始洗牌 (. >_<).\n";Shuffle_Poker (POKER_Niuniu, 20);       /*洗牌*/Print_Poker (POKER_Niuniu);             /*打印扑克牌*/Poker_Init (POKER_Niuniu);Delete_Poker (POKER_Niuniu);           /*释放内存*/
}

执行上面代码就能看到扑克牌创建后的效果和洗牌完毕后的效果

这里洗牌20次,显然不够乱,还可以洗牌更多次数。洗牌函数也需要优化,随机数抽取互换经常性的抽不到头和尾。

按照斗牛规则发牌

根据斗牛的规则,可以每轮为两位玩家分别从牌库发5张牌。也可以提前将牌库的牌分配好,分别发到每个玩家自己的小牌库(依次讲牌库中的牌分给玩家,没人牌库20张)然后每回合从各个咱家的小牌库顺序抽取5张。我是用的是第二种方法。(如果游戏规则里面获胜玩家在下一回合先抽牌就不能使用第二种方法)。

/*牛牛发牌函数*/
void Deal_Cards(Poker_Typedef* poker)
{int i = 0, j = 0;PokerChar Player1Cards[20] = { 0 };PokerChar Player2Cards[20] = { 0 };int pt = 0;char input = NULL;for (i = 0; i < 54; i++)   //将牌分给两个人{if ((poker->Card[i] % 13) > 0 && (poker->Card[i] % 13 < 11) && (poker->Card[i] != 53) && (poker->Card[i] != 54))   //1~10以内的牌{if (j % 2 == 0){Player1Cards[pt] = poker->Card[i];}else{Player2Cards[pt] = poker->Card[i];pt++;  /*两人都拿了一张牌*/}j++;}}j = 0;pt = 0;std::cout << "开始游戏 0(^o^)0 \r\n" << "    输入任意值继续游戏  | 选择'N'键退出游戏\r\n";std::cin >> input;//scanf_s("%c", &input);while ((input != 'n') | (input != 'N'))    /*输入的值不是n或N*/{if ((input == 'n') || (input == 'N')){break;}std::cout << "\n|-------------------------玩家一------------------------ | -------------------------玩家二-------------------------|\n";printf("| ");for (j = 0; j < 5; j++)   /*发玩家一的牌*/{Print_Card(Player1Cards[pt]);pt++;}printf("| ");j = 0;pt -= 5;for (j = 0; j < 5; j++)  /*发玩家二的牌*/{Print_Card(Player2Cards[pt]);pt++;}printf(" |");printf("\r\n");std::cout << " ------------------------------------------------------------------------------------------------------------------\n\n";if (pt >= 20)     /*如果发完了*/{std::cout << "牌库已经发完啦\r\n";break;}/*继续发牌或退出游戏*/std::cout << "新一回合 \r\n" << "    输入任意值继续游戏   | 选择'N'键退出游戏\r\n";std::cin >> input;//scanf_s("%c", &input);}
}

游戏的实现

主函数的代码如下,将所有内容串起来。

{char input_main = 'Y';  /*键盘输入存储*/Poker_Typedef* POKER_Niuniu;POKER_Niuniu = Create_Poker();     /*创建扑克牌*/if (!POKER_Niuniu) {return 0;}std::cout << "-------------------------------- * 牛牛发牌器  * --------------------------------\n";printf("\r\n");printf("          *********         *********\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   **********    *   *\r\n");printf("          *                         *\r\n");printf("          *  *******       *******  *\r\n");printf("          *  **            **       *\r\n");printf("          *                         *\r\n");printf("          ***************************\r\n");printf("                 **         **       \r\n");printf("                 **    **   **       \r\n");printf("                 *************       \r\n");printf("\r\n\r\n");while ((input_main != 'n') | (input_main != 'N')){Poker_Init(POKER_Niuniu);            /*初始化扑克牌*/Shuffle_Poker(POKER_Niuniu, 25);       /*洗牌*/Deal_Cards(POKER_Niuniu);     /*循环发牌*/std::cout << "是否开始新一轮游戏?(Y/N) \n" << "    输入任意值继续游戏   | 选择'N'键退出游戏\r\n";std::cin >> input_main;
//      scanf_s("%c", &input_main);if ((input_main == 'n') || (input_main == 'N')){break;}}/*结束游戏,清理内存*/Delete_Poker(POKER_Niuniu);           /*释放内存*/return 0;
}


好了!!!现在我们可以没有纸牌一样玩斗牛了。
第一回合:
玩家一:
有牛!牛7
三张牌:【红桃A】 【红桃4】【黑桃5】
两张牌:【梅花4】【黑桃3】

玩家二:
有牛!牛9
三张牌:【红桃5】 【红桃7】【方片8】
两张牌:【红桃3】【方片6】

玩家二胜利!

未来可改进

1.洗牌函数可以优化,做到洗牌更无序。
2.可增加斗牛计算函数,即可以实现自动算出分值(这样好像就失去的游戏的乐趣了)

全部源码

/*poker.h*/#ifndef _POKER_H_
#define _POKER_H_typedef int PokerChar ;//extern char Poker_num[13] = { '1','2','3','4','5','6','7','8','9','10','J','Q','K' };
//extern char Poker_col[4] = {'♠','♥','♣','♦'};typedef struct Poker_Type
{PokerChar Card[54];}Poker_Typedef;Poker_Typedef* Create_Poker (void);
void Delete_Poker (Poker_Typedef* poker);
void Poker_Init (Poker_Typedef* poker);
void Print_Card (PokerChar card);
void Print_Poker (Poker_Typedef* poker);
void Shuffle_Poker (Poker_Typedef* poker, int times);#endif
/*poker.cpp*/
/*扑克牌相关函数实现*/
#include "poker.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>static char Poker_num[13][3]= {"K" , "A","2","3","4","5","6","7","8","9","10","J","Q"};
static char Poker_col[4][5] = { "红桃","方片","黑桃","梅花"}; // ASCII码对应的字符,其中,6为黑桃,5为草花,4为方片,3为红桃/*创建扑克牌库*/
Poker_Typedef* Create_Poker (void)
{Poker_Typedef* temp;temp = (Poker_Typedef*)malloc (sizeof (PokerChar) * 54);if (temp == NULL){printf ("创建扑克牌库失败 ( > _ < )!\r\n");return NULL;}return temp;
}/*初始化扑克牌*/
void Poker_Init (Poker_Typedef* poker)
{int i = 0;for (i; i < 54; i++){poker->Card[i] = i + 1;}
}/*删除扑克牌库*/
void Delete_Poker (Poker_Typedef* poker)
{Poker_Init (poker);free (poker);
}/*洗牌*/
void Shuffle_Poker(Poker_Typedef* poker, int times)
{int i = 0;int a = 0, b = 0;PokerChar temp_card = 0;srand((unsigned)time(NULL));   //设置随机数种子for (i = 0; i < times; i++){//rand()%(b-a+1)+aa = rand() % 54;  /*下标取值范围0~53*/b = rand() % 54;temp_card = poker->Card[a];poker->Card[a] = poker->Card[b];poker->Card[b] = temp_card;}
}/*打印单张牌面*/
void Print_Card (PokerChar card)
{int color = NULL;int num = NULL;if ((card < 1) || (card > 54)){printf ("你拿了张假牌吧!(= o =).z Z\r\n");}else{if (card == 53){printf ("【 小王 】 ");}else if (card == 54){printf ("【 大王 】 ");}else{if (card % 13 == 0){color = card / 13 - 1;}else{color = card / 13;      /*得到花色*/}num = card % 13;        /*得到牌面*/printf ("【%s%2s】 ", Poker_col[color],Poker_num[num] );}}
}/*打印整副牌面*/
void Print_Poker(Poker_Typedef* poker)
{int i = 0;printf("整副扑克牌是:\r\n");for (i = 0; i < 54; i++){if (i % 13 == 0)    /*打印13张就换行显示*/{printf("\r\n");}Print_Card(poker->Card[i]);}printf("\r\n 扑克牌展示完毕(O^u^O)\r\n");
}
// Poker_niuniu.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include <iostream>
#include "poker.h"/*测试洗牌函数使用*/
int Test_Shuffle_Poker (void)
{Poker_Typedef* POKER_Niuniu;std::cout << "创建一副扑克 ...(* ̄0 ̄)/\n";POKER_Niuniu = Create_Poker ();     /*创建扑克牌*/if (!POKER_Niuniu) {return 0;}Poker_Init (POKER_Niuniu);            /*初始化扑克牌*/Print_Poker(POKER_Niuniu);             /*打印扑克牌*/std::cout << "开始洗牌 (. >_<).\n";Shuffle_Poker (POKER_Niuniu, 20);       /*洗牌*/Print_Poker (POKER_Niuniu);             /*打印扑克牌*/Poker_Init (POKER_Niuniu);Delete_Poker (POKER_Niuniu);           /*释放内存*/
}/*牛牛发牌函数*/
void Deal_Cards(Poker_Typedef* poker)
{int i = 0, j = 0;PokerChar Player1Cards[20] = { 0 };PokerChar Player2Cards[20] = { 0 };int pt = 0;char input = NULL;for (i = 0; i < 54; i++)   //将牌分给两个人{if ((poker->Card[i] % 13) > 0 && (poker->Card[i] % 13 < 11) && (poker->Card[i] != 53) && (poker->Card[i] != 54))   //1~10以内的牌{if (j % 2 == 0){Player1Cards[pt] = poker->Card[i];}else{Player2Cards[pt] = poker->Card[i];pt++;  /*两人都拿了一张牌*/}j++;}}j = 0;pt = 0;std::cout << "开始游戏 0(^o^)0 \r\n" << "    输入任意值继续游戏  | 选择'N'键退出游戏\r\n";std::cin >> input;//scanf_s("%c", &input);while ((input != 'n') | (input != 'N'))    /*输入的值不是n或N*/{if ((input == 'n') || (input == 'N')){break;}std::cout << "\n|-------------------------玩家一------------------------ | -------------------------玩家二-------------------------|\n";printf("| ");for (j = 0; j < 5; j++)   /*发玩家一的牌*/{Print_Card(Player1Cards[pt]);pt++;}printf("| ");j = 0;pt -= 5;for (j = 0; j < 5; j++)  /*发玩家二的牌*/{Print_Card(Player2Cards[pt]);pt++;}printf(" |");printf("\r\n");std::cout << " ------------------------------------------------------------------------------------------------------------------\n\n";if (pt >= 20)     /*如果发完了*/{std::cout << "牌库已经发完啦\r\n";break;}/*继续发牌或退出游戏*/std::cout << "新一回合 \r\n" << "    输入任意值继续游戏   | 选择'N'键退出游戏\r\n";std::cin >> input;//scanf_s("%c", &input);}
}int main()
{char input_main = 'Y';Poker_Typedef* POKER_Niuniu;POKER_Niuniu = Create_Poker();     /*创建扑克牌*/if (!POKER_Niuniu) {return 0;}std::cout << "-------------------------------- * 牛牛发牌器  * --------------------------------\n";printf("\r\n");printf("          *********         *********\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   *         *   *   *\r\n");printf("          *   *   **********    *   *\r\n");printf("          *                         *\r\n");printf("          *  *******       *******  *\r\n");printf("          *  **            **       *\r\n");printf("          *                         *\r\n");printf("          ***************************\r\n");printf("                 **         **       \r\n");printf("                 **    **   **       \r\n");printf("                 *************       \r\n");printf("\r\n\r\n");while ((input_main != 'n') | (input_main != 'N')){Poker_Init(POKER_Niuniu);            /*初始化扑克牌*/Shuffle_Poker(POKER_Niuniu, 25);       /*洗牌*/Deal_Cards(POKER_Niuniu);     /*循环发牌*/std::cout << "是否开始新一轮游戏?(Y/N) \n" << "    输入任意值继续游戏   | 选择'N'键退出游戏\r\n";std::cin >> input_main;
//      scanf_s("%c", &input_main);if ((input_main == 'n') || (input_main == 'N')){break;}}/*结束游戏,清理内存*/Delete_Poker(POKER_Niuniu);           /*释放内存*///Test_Shuffle_Poker(); /*洗牌测试代码*/return 0;
}

【C语言】写一个斗牛小游戏的发牌器相关推荐

  1. ChatGPT实现用C语言写一个扫雷小游戏

    前几天我们利用 ChatGPT实现用C语言写一个学生成绩管理系统 其过程用时不到30秒,速度惊人 今天又让ChatGPT用C语言写了一个扫雷小游戏,它的回答是:抱歉,我是AI语言模型,无法编写程序. ...

  2. 使用C语言写一个扫雷小游戏

    前言 相信扫雷游戏小伙伴们肯定都玩过吧,学习了C语言中的数组.函数等基础内容之后就可以自己写一个简易的扫雷小游戏了,今天就我写扫雷小游戏的过程及思路写一篇博客,希望大家看完我的博客能有所收获. 软件及 ...

  3. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  4. 用C语言做一个迷宫小游戏

    用C语言做一个迷宫小游戏,以下是代码段 这个迷宫游戏使用了递归回溯算法来寻找通往出口的路径.迷宫中的墙用'#'表示,路径用空格表示,入口和出口分别用'S'和'E'表示,已走过的路径用'*'表示.在生成 ...

  5. 【笔记】用vs2017 c语言写 贪吃蛇 小游戏

    目录 文章目录 前言 一.贪吃蛇游戏 设计逻辑 二.详细介绍 1.设置界面(界面大小,背景颜色) 2.设置贪吃蛇的身体并显示 3.使之能够移动并能够穿墙 4.添加食物并让蛇吃掉 5.设置背景音乐 完整 ...

  6. 教你前端如何用js写一个跑酷小游戏

    在线体验地址:http://summer.pkec.net/ 源码地址:https://gitee.com/ihope_top/juejin-summer 前言 不知不觉夏天又到了,提到夏天你们能想到 ...

  7. ES6 手写一个“辨色”小游戏

    1. 前言 依稀记得几年前朋友圈流行的辨色小游戏,找出颜色不同的矩形.前些天突发奇想,打算自己手写一个类似的游戏,话不多说,先上 Demo . --项目源码 本实例基于 ES6 实现,并兼容 ie9及 ...

  8. html5翻卡片游戏,用 JavaScript 写一个卡片小游戏

    小游戏使用了HTML5,CSS3和JavaScript的基本的技术. 将讨论数据属性.定位.透视.转换.flexbox.事件处理.超时和三元组. 你不需要在编程方面有太多的知识和经验就能看懂,不过还是 ...

  9. python俄罗斯方块小游戏实验报告,童年的记忆——如何用python写一个俄罗斯方块小游戏!...

    谈到记忆里的小游戏,俄罗斯方块是大家一定会想到的一款游戏,自己写出来的应该玩起来更有感觉,然后就写了一个俄罗斯方块的游戏 给大家分享一下这个游戏的源码 先用python创建一个py文件 定义这次程序所 ...

最新文章

  1. PHP mysql 事务处理实例
  2. 跳一跳python源码下载_微信跳一跳python代码实现
  3. 计算机伺服系统的作用是,伺服系统简介及其在数控加工中的应用
  4. python通讯录管理系统 tk_通讯录管理系统课程设计
  5. c# MEF框架(四 见证奇迹的时刻之实战应用)
  6. 数据挖掘--挖掘建模-时序模式-ARIMA模型
  7. 加上mvc:resources后controller访问404
  8. Linux操作系统应用领域详解
  9. 网络安全-wifi攻防
  10. 华为机顶盒视频播放代码
  11. Knockout.js入门级
  12. 血管分割技术文献综述
  13. Android技术开发 必备网站及使用工具
  14. Jenkins执行shell命令,提示Pseudo-terminal will not be allocated because stdin is not a terminal.
  15. 【Excel】正态分布函数 NORM.DIST / 标准差STDEV.S、STDEV.P
  16. VO、DTO、DO、PO
  17. XCTF 攻防世界Web题目 mfw
  18. Java调用kjb文件
  19. langconv 安装 | python繁体 简体转换
  20. c/c++中的标识符解析

热门文章

  1. loj 6184 无心行挽 虚树+DP+倍增
  2. 【数据处理】PS动作功能(附:下雨效果)
  3. 发现内存不能read和written的原因以及解决方法
  4. 【科研工具】【MikTex】MikTex安装和使用
  5. 矩阵键盘基于51(UcosII)计算器小项目
  6. 8、ABPZero系列教程之拼多多卖家工具 添加手机注册登录功能
  7. Nagios监控服务器与客户端的安装
  8. 二进制、八进制、十进制、十六进制的英文及简写
  9. 用python对数据进行主成分分析、类概念描述及特征化分析-实验报告
  10. reduceByKey