C/C++实现桥牌发牌程序

  • 问题描述
  • 程序主要功能设计
  • 程序运行结果
  • 随机数库设计
  • C语言实现
  • C++实现

问题描述

实现一个桥牌发牌的程序,规则是:扑克牌54张去掉大小王剩下52张花色牌就是一副牌,发牌就是一人一张轮着发,最后平均分给东,西,南,北四个玩家每人13张牌。为描述问题方便,2至9的牌张使用对应字符‘2’‘9’,字符‘T’表示10,还有就是‘J’‘K’‘Q’‘A’。同时按照规则需要,要统计每个玩家的牌点值,记每张2~10为0点,J为1点,Q为2点,K为3点,A为4点。

习题来源于学堂在线MOOC平台《基于linux的C++》课程。(原来的要求是要实现一个完整的桥牌游戏库的。但是桥牌规则实在是看不懂。。。)


程序主要功能设计

  1. 重复生成52个随机数并映射为每张扑克牌。原则是按照花色顺序(梅花<方块<红桃<黑桃)和牌号顺序(2~10,J,Q,K,A)进行映射,例如梅花2<梅花3,……,梅花A<方块2,……,黑桃K<黑桃A。
  2. 发牌状态实时更新(利用延时函数和清屏函数),并且模拟实际中玩家抽到牌并把牌及时插入到正确大小位置的过程;同时及时更新统计手牌数目和计算手牌点数。
  3. 玩家抽牌、打出牌的过程,相当于手牌组数据结构既有增有减,又始终保持稳定的顺序,用链表比较适合存储这样的数据结构。
  4. 用到随机数库random.h,能够生成指定区间内的随机整数或是随机小数。
  5. 分别用C和C++面向对象语法实现。

程序运行结果

GCC编译的。Ubuntu上的运行结果。

windows环境下也试过,很卡顿,不流畅。


随机数库设计

直接抄老师上课讲的,生成随机数用。
random.h

#ifndef RANDOM_H
#define RANDOM_Hvoid Randomize();//设置随机数种子
int GenerateRandomNumber(int low, int high);//生成随机整数
double GenerateRandomReal(double low, double high);//生成随机小数#endif

random.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include "random.h"using namespace std;void Randomize()
{srand((int) time(NULL));
}int GenerateRandomNumber(int low, int high)
{double _d;if (low > high){printf("区间不对\n");exit(1);}_d = (double)rand() / ((double)RAND_MAX + 1.0);//RAND_MAX在stdlib.h中有定义//+1.0好像是确保生成0到1左闭右开区间,具体记不得了return (low + (int)(_d * (high - low + 1)));//+1也是为了使映射平均、正确
}double GenerateRandomReal(double low, double high)
{double _d;if (low > high){printf("区间不对\n");exit(2);}_d = (double)rand() / ((double)RAND_MAX);return (low + _d * (high - low));
}

C语言实现

#include <cstdio>
#include <cstdlib>
#include "random.h"const int PLAYER_NUM = 4;//4个玩家
const int HUASE_NUM = 4;//4种花色
const int CARD_NUM = 52;//52张牌
const int NUM_OF_EVERY_HUASE = 13;//每种花色13张牌
const int NUM_OF_SHOUPAI = 13;//每个人13张手牌,这个变量没用上
const char* player_name[PLAYER_NUM] = {"East", "South", "West", "North"};
const char* huase_name[HUASE_NUM] = {"梅花", "方块", "红桃", "黑桃"};
const char paihao[NUM_OF_EVERY_HUASE] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};enum {EAST, SOUTH, WEST, NORTH};int flag[CARD_NUM] = {0};//记录发牌是否重复
int cnt = 0;//发牌计数struct card {int order;//每张牌在1到52中的顺序是它的本质属性,牌的花色与名字可以由顺序计算出来。struct card *next;
};struct every_player {int dianshu;int num_of_shoupai;int who;//玩家编号(1到4,对应enum东南西北)struct card *shoupai;
};//代表每个玩家的结构体,有点数、手牌张数,玩家编号,手牌的链表 三个属性struct every_player Players[PLAYER_NUM];//包含4个玩家的结构体数组void insert_card(int order, struct every_player *player);//这个函数是玩家在抽到牌后将牌插入手中合适位置的过程
void print_card(struct every_player *player);//这个函数打印玩家手牌
void delay(int i,int j);  //延时函数int main()
{printf("程序将给4个桥牌玩家发牌:东家,南家,西家,北家\n""并且会实时刷新点数、手牌数和发牌情况。\n\n");printf("马上发牌,请稍等:\n\n");delay(999999999,999999999);for (int i = 0; i < PLAYER_NUM; ++i) {Players[i].dianshu = 0;Players[i].num_of_shoupai = 0;Players[i].shoupai = NULL;Players[i].who = i;}//初始化结构体Randomize();while(1) {if(cnt == CARD_NUM)break;system("clear");//windows环境下的清屏好像是CLS函数int fapai = GenerateRandomNumber(0, CARD_NUM - 1);if (!flag[fapai]){flag[fapai]++;cnt++;int player_number = cnt % PLAYER_NUM;//当前抽牌玩家insert_card(fapai, &Players[player_number]);//玩家抽牌并把牌放到正确顺序上。printf("玩家  手牌数  点数:\n");for (int i = 0; i < PLAYER_NUM; ++i) {print_card(&Players[i]);}delay(99999999,888888);}}printf("正在结束,请稍等。。。\n");delay(999999999,999999999);return 0;
}void insert_card(int order, struct every_player *player)//参考了《C语言程序设计:现代方法》
{struct card *cur, *prev, *new_node;//prev将在循环中起追踪作用new_node = (card *)malloc(sizeof(struct card));if (new_node == NULL) {printf("内存分配错误!\n");exit(0);//此程序只有发牌,所以只有malloc没有free}new_node->order = order;for (cur = player->shoupai, prev = NULL;cur != NULL && new_node->order > cur->order;prev = cur, cur = cur->next);new_node->next = cur;if (prev == NULL)player->shoupai = new_node;//本来链表是空的,new_node成为首节点elseprev->next = new_node;//本来链表不是空的,普通情况switch(order % NUM_OF_EVERY_HUASE) {case 9 :player->dianshu += 1;break;case 10:player->dianshu += 2;break;case 11:player->dianshu += 3;break;case 12:player->dianshu += 4;break;default:player->dianshu += 0;break;}player->num_of_shoupai++;
}void print_card(struct every_player *player)
{struct card *p;printf("%5s    %2d     %2d: ", player_name[player->who], player->num_of_shoupai, player->dianshu);if (player->num_of_shoupai == 0) {printf("\n");return;}for (p = player->shoupai; p != NULL; p = p->next)printf(" %7s%c", huase_name[p->order / NUM_OF_EVERY_HUASE],paihao[p->order % NUM_OF_EVERY_HUASE]);printf("\n");
}void delay(int i,int j)  //延时函数
{for( ;j>0 ;j--)for( ;i>0 ;i--);
}

C++实现

随机数库还是用的一样的。输入输出我还是更习惯用scanf printf。

#include <cstdio>
#include <cstdlib>
#include "random.h"const int PLAYER_NUM = 4;//4个玩家
const int HUASE_NUM = 4;//4种花色
const int CARD_NUM = 52;//52张牌
const int NumOfEveryHuaSe = 13;//每种花色13张牌
//const int NUM_OF_SHOUPAI = 13;//每个人13张手牌
const char* PlayerName[PLAYER_NUM] = {"East", "South", "West", "North"};
const char* HuaSeName[HUASE_NUM] = {"梅花", "方块", "红桃", "黑桃"};
const char PaiHaoName[NumOfEveryHuaSe] = {'2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A'};enum {EAST, SOUTH, WEST, NORTH};int flag[CARD_NUM] = {0};//记录发牌是否重复
int cnt = 0;//发牌计数void delay(int i,int j);//延时函数class CardNode {//单张牌用一个节点存储
public:int order;//每张牌在1到52中的顺序是它的本质属性,牌的花色与名字可以由顺序计算出来。class CardNode *next;const char * HuaSe() { return HuaSeName[order / NumOfEveryHuaSe]; }const char PaiHao() { return PaiHaoName[order % NumOfEveryHuaSe]; }int DianShu();//计算每张牌点数
};class CCardInHand {//一副手牌用一个链表存储
protected:class CardNode * first;int number;//手牌数量friend class CPlayer;
public:CCardInHand(): first(NULL), number(0) {}~CCardInHand() {while (first) {CardNode * tmp = first;first = first->next;delete tmp;}}
};class CPlayer {private:int player;//玩家编号(1到4,对应enum东南西北)int dianshu;//手牌总计点数CCardInHand card;//手牌牌组
public:CPlayer(int _player): player(_player), dianshu(0) {}//~CPlayer();void InsertCard(int order);//抽牌把牌放到正确位置void PrintCard();//打印手牌信息const char * Name() { return PlayerName[player]; }
};int CardNode::DianShu() {switch(order % NumOfEveryHuaSe) {case 9 :return 1;case 10:return 2;case 11:return 3;case 12:return 4;default:return 5;}
}void CPlayer::InsertCard(int order) {CardNode *cur, *prev, *NewNode;//有序链表的查询和插入,prev将在循环中起追踪作用NewNode = new CardNode;if (NewNode == NULL) {printf("内存分配错误!\n");exit(0);}NewNode->order = order;for (cur = card.first, prev = NULL;cur != NULL && NewNode->order > cur->order;prev = cur, cur = cur->next);NewNode->next = cur;if (prev == NULL)card.first = NewNode;//本来链表是空的,new_node成为首节点elseprev->next = NewNode;//本来链表不是空的,普通情况dianshu += NewNode->DianShu();card.number++;
}void CPlayer::PrintCard() {CardNode *p;printf("%5s    %2d     %2d: ", Name(), card.number, dianshu);if (card.number == 0) {printf("\n");return;}for (p = card.first; p != NULL; p = p->next)printf(" %7s%c", p->HuaSe(),p->PaiHao());printf("\n");
}int main()
{printf("程序将给4个桥牌玩家发牌:东家,南家,西家,北家\n""并且会实时刷新点数、手牌数和发牌情况。\n\n");printf("马上发牌,请稍等:\n\n");delay(999999999,999999999);CPlayer Players[PLAYER_NUM] = {EAST, SOUTH, WEST, NORTH};Randomize();while(1) {if(cnt == CARD_NUM)break;system("clear");int fapai = GenerateRandomNumber(0, CARD_NUM - 1);if (!flag[fapai]){flag[fapai]++;cnt++;int player_number = cnt % PLAYER_NUM;//当前抽牌玩家Players[player_number].InsertCard(fapai);//玩家抽牌并把牌放到正确顺序上。printf("玩家  手牌数  点数:\n");for (int i = 0; i < PLAYER_NUM; ++i) {Players[i].PrintCard();}delay(99999999,888888);}}printf("正在结束,请稍等。。。\n");delay(999999999,999999999);return 0;
}void delay(int i,int j)  //延时函数
{for( ;j>0 ;j--)for( ;i>0 ;i--);
}

C/C++实现桥牌发牌程序相关推荐

  1. java桥牌发牌程序,java桥牌发牌算法 | 学步园

    参考文章: ---------------------------------------------------------------------------------------------- ...

  2. 实现tinyc语言的扫描程序_适合编程小白的C语言设计习题,实现自动发牌程序!源码分享!...

    C语言自动发牌程序,供大家参考,具体内容如下: 一副扑克有52张牌,打桥牌时应将牌分给4个人.请设计一个程序完成自动发牌的工作.要求:黑桃用S (Spaces)表示,红桃用H (Hearts)表示,方 ...

  3. java扑克发牌程序_Java多线程实现扑克牌发牌程序实例

    import java.util.*; import java.awt.*; import javax.swing.*; public class CardBuffer                 ...

  4. 红心大战c语言程序设计教程课后答案,[原创]Windows 红心大战随机发牌程序分析...

    [调试逆向] [原创]Windows 红心大战随机发牌程序分析 2007-11-27 23:28 13191 [调试逆向] [原创]Windows 红心大战随机发牌程序分析 2007-11-27 23 ...

  5. java swing 模拟发牌_用java设计一个发牌程序

    展开全部 // 发牌程序. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CardBuf ...

  6. Python面向对象编程扑克牌发牌程序,另含大量Python代码!

    1. 题目 编写程序, 4名牌手打牌,计算机随机将52张牌(不含大小鬼)发给4名牌手,在屏幕上显示每位牌手的牌. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后, ...

  7. python交互界面实例_Python面向对象编程扑克牌发牌程序,另含大量Python代码!

    1. 题目 编写程序, 4名牌手打牌,计算机随机将52张牌(不含大小鬼)发给4名牌手,在屏幕上显示每位牌手的牌. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后, ...

  8. python 斗地主发牌_Python_斗地主发牌程序

    1)1副牌(52+2=54张) 2)有大小王,用提供的国王和皇后的符号表示大小王 3)54张牌发给3个玩家,每人17张牌,并有3张底牌. 4)输出3个玩家的牌,按照由小到大,黑红梅方的顺序. 5)输出 ...

  9. 斗地主(^-^)发牌程序

    有很多朋友斗想编一个自己的小游戏,今天我为大家带来的是,如何用java封装对象写斗地主的发牌程序. 首先我们知道一副牌一共有54张,其中大小王是特殊的没有4个花色,其余牌都是有是个花色的. 所以我们根 ...

最新文章

  1. Ehcache学习笔记(一)基础入门
  2. PHP+JS动态显示当前时间
  3. 跟我一起使用electron搭建一个文件浏览器吧
  4. vb ftp linux,VB FTP上传和下载模块
  5. android获取该控件在屏幕,android获取屏幕宽高与获取控件宽高(三种方法)
  6. 一元线性回归多元线性回归
  7. exchange server 2010 OWA 附件功能只支持IE浏览器
  8. 用C语言实现猜数字游戏
  9. java单点登录解决方案_N多系统单点登录,实现、解决方案。四种解决方案
  10. Spring Security Oauth2 JWT、第三方登录、单点登录讲解,并使用Oauth2.0结合微服务进行单点登录
  11. 语音社交聊天app受欢迎的特点有哪些?
  12. 记录团队日常工作清单用什么办公软件?
  13. 2021计算机夏令营保研经历(中科院计算所,南京大学人工智能学院等)
  14. centos7.5安装Jenkins
  15. 什么是开源网络情报?有什么特点?
  16. 实现聊天发送语音消息功能
  17. win10 桌面颜色变成灰色
  18. 福利彩票选号盘(silverlight5 开源)
  19. python通过ssh通道连接PostgreSQL数据库(mysql等类同)
  20. Jackknife法和bootstrap法(自助法与刀切法)

热门文章

  1. 微信小程序报错 net::ERR_CONNECTION_TIMED_OUT
  2. Caesar(恺撒)密码加密解密-----Java实现
  3. 微信小程序学习笔记 ( 小程序主体学习 二 逻辑层 app.js 扩展 高级食用方法)
  4. 【Unity】通过2种方法实现摄像机的移动,旋转,放缩
  5. revit输入序列号闪退_针对revit启动闪退的一般性解决方法
  6. java盒图_Java图形化界面设计——布局管理器之BoxLayout布局(盒式布局)
  7. 15.12.1 美化的秒表
  8. 报错:Error: Could not create FontSet for font ‘-adobe-helvetica-medium-r-normal-*
  9. 文件传输的几种常用方法
  10. PROTEUS最新版本下载CSDN_剪映4k版本下载-剪映4k版本60帧画质最新版v4.4.4