C/C++实现桥牌发牌程序
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++》课程。(原来的要求是要实现一个完整的桥牌游戏库的。但是桥牌规则实在是看不懂。。。)
程序主要功能设计
- 重复生成52个随机数并映射为每张扑克牌。原则是按照花色顺序(梅花<方块<红桃<黑桃)和牌号顺序(2~10,J,Q,K,A)进行映射,例如梅花2<梅花3,……,梅花A<方块2,……,黑桃K<黑桃A。
- 发牌状态实时更新(利用延时函数和清屏函数),并且模拟实际中玩家抽到牌并把牌及时插入到正确大小位置的过程;同时及时更新统计手牌数目和计算手牌点数。
- 玩家抽牌、打出牌的过程,相当于手牌组数据结构既有增有减,又始终保持稳定的顺序,用链表比较适合存储这样的数据结构。
- 用到随机数库random.h,能够生成指定区间内的随机整数或是随机小数。
- 分别用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++实现桥牌发牌程序相关推荐
- java桥牌发牌程序,java桥牌发牌算法 | 学步园
参考文章: ---------------------------------------------------------------------------------------------- ...
- 实现tinyc语言的扫描程序_适合编程小白的C语言设计习题,实现自动发牌程序!源码分享!...
C语言自动发牌程序,供大家参考,具体内容如下: 一副扑克有52张牌,打桥牌时应将牌分给4个人.请设计一个程序完成自动发牌的工作.要求:黑桃用S (Spaces)表示,红桃用H (Hearts)表示,方 ...
- java扑克发牌程序_Java多线程实现扑克牌发牌程序实例
import java.util.*; import java.awt.*; import javax.swing.*; public class CardBuffer ...
- 红心大战c语言程序设计教程课后答案,[原创]Windows 红心大战随机发牌程序分析...
[调试逆向] [原创]Windows 红心大战随机发牌程序分析 2007-11-27 23:28 13191 [调试逆向] [原创]Windows 红心大战随机发牌程序分析 2007-11-27 23 ...
- java swing 模拟发牌_用java设计一个发牌程序
展开全部 // 发牌程序. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CardBuf ...
- Python面向对象编程扑克牌发牌程序,另含大量Python代码!
1. 题目 编写程序, 4名牌手打牌,计算机随机将52张牌(不含大小鬼)发给4名牌手,在屏幕上显示每位牌手的牌. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后, ...
- python交互界面实例_Python面向对象编程扑克牌发牌程序,另含大量Python代码!
1. 题目 编写程序, 4名牌手打牌,计算机随机将52张牌(不含大小鬼)发给4名牌手,在屏幕上显示每位牌手的牌. 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后, ...
- python 斗地主发牌_Python_斗地主发牌程序
1)1副牌(52+2=54张) 2)有大小王,用提供的国王和皇后的符号表示大小王 3)54张牌发给3个玩家,每人17张牌,并有3张底牌. 4)输出3个玩家的牌,按照由小到大,黑红梅方的顺序. 5)输出 ...
- 斗地主(^-^)发牌程序
有很多朋友斗想编一个自己的小游戏,今天我为大家带来的是,如何用java封装对象写斗地主的发牌程序. 首先我们知道一副牌一共有54张,其中大小王是特殊的没有4个花色,其余牌都是有是个花色的. 所以我们根 ...
最新文章
- Ehcache学习笔记(一)基础入门
- PHP+JS动态显示当前时间
- 跟我一起使用electron搭建一个文件浏览器吧
- vb ftp linux,VB FTP上传和下载模块
- android获取该控件在屏幕,android获取屏幕宽高与获取控件宽高(三种方法)
- 一元线性回归多元线性回归
- exchange server 2010 OWA 附件功能只支持IE浏览器
- 用C语言实现猜数字游戏
- java单点登录解决方案_N多系统单点登录,实现、解决方案。四种解决方案
- Spring Security Oauth2 JWT、第三方登录、单点登录讲解,并使用Oauth2.0结合微服务进行单点登录
- 语音社交聊天app受欢迎的特点有哪些?
- 记录团队日常工作清单用什么办公软件?
- 2021计算机夏令营保研经历(中科院计算所,南京大学人工智能学院等)
- centos7.5安装Jenkins
- 什么是开源网络情报?有什么特点?
- 实现聊天发送语音消息功能
- win10 桌面颜色变成灰色
- 福利彩票选号盘(silverlight5 开源)
- python通过ssh通道连接PostgreSQL数据库(mysql等类同)
- Jackknife法和bootstrap法(自助法与刀切法)
热门文章
- 微信小程序报错 net::ERR_CONNECTION_TIMED_OUT
- Caesar(恺撒)密码加密解密-----Java实现
- 微信小程序学习笔记 ( 小程序主体学习 二 逻辑层 app.js 扩展 高级食用方法)
- 【Unity】通过2种方法实现摄像机的移动,旋转,放缩
- revit输入序列号闪退_针对revit启动闪退的一般性解决方法
- java盒图_Java图形化界面设计——布局管理器之BoxLayout布局(盒式布局)
- 15.12.1 美化的秒表
- 报错:Error: Could not create FontSet for font ‘-adobe-helvetica-medium-r-normal-*
- 文件传输的几种常用方法
- PROTEUS最新版本下载CSDN_剪映4k版本下载-剪映4k版本60帧画质最新版v4.4.4