问题描述
实现一个桥牌发牌的程序,规则是:扑克牌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_H
void 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',