急!!!C++扑克牌怎么洗牌 洗牌发牌存牌,求大神解答

&>&C++代码实现洗牌发牌排序功能
C++代码实现洗牌发牌排序功能
上传大小:3.81MB
C++代码实现洗牌,发牌,排序的功能,不会的小伙伴可以参考一下。
综合评分:0
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
longxingzhu
综合评分:
积分/C币:3
综合评分:
积分/C币:3
综合评分:
积分/C币:3
综合评分:
积分/C币:3
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
C++代码实现洗牌发牌排序功能
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
linghunjiujiu
举报的资源分:
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*详细原因:
C++代码实现洗牌发牌排序功能博主最新文章
博主热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)c++ 扑克牌洗牌发牌模拟_百度知道
c++ 扑克牌洗牌发牌模拟
把牌发给四个人
我有更好的答案
); }}void&Poker:;,&#39,'5','J';To&nbsp.h#ifndef&
a&=&Q', '2'::Shuffle(){ int&r&1&#39,'9', '2'_SIZE&=&,','7&#39,DEF_POKER;1' } ~Poker(void);__POKER_H__#define& inline&void&Swap(&,'9'__POKER_H__#include&&random&#include&&8&#39,'4';buffer&the&playing&player //&@lastLen&&&the&SHUFFLE_TIMES&=&nbsp,'5';@playerPokerBuf&the&char*&pokerBuff,int&size);,&#39,'4','J'.h&#define&=&{ '&nbsp,'6';0,_curPoker[r]&SHOW_10()& printf(&10&&)const&int&);9',&#39,'3';i&=&A' for(&int&&Poker{public: Poker(void) {
srand((int)time(0));
memcpy(&,'2',&#39,'1';,'&t; void&ShowPoker(&const&_curPvoid&of&J'++i&) {
r&=&nbspHi,这里给以一份新鲜出炉的实例代码。P4*_SIZE&;a,'Q';SHUFFLE_TIMES: char&_curPoker[POKER_SIZE];};#endifPcount&of&the&const&int&
b&=&++i&) {
if(&i&player //&@len&&&&&&&the&nbsp,'9';&&i&POKER_SIZE;K', '2';POKER_SIZE;static&char&&DEF_POKER[POKER_SIZE]&%&13&==0&,','Q'number&cards&for&int&i&3&#39,'7';4'6'The&Player //&4' void&Shuffle(); void&nbsp,'1';,'5&#39,'A'&;char*&playerPokerBuf[];,&#39,int&len,int&
if(&0;,&#39,'Q';,&#39.cpp#include&&Poker.h&,'A',&#39,'K';7'leaving void&DealCards(&,'
Swap(&_curPoker[i];of&,'_curPoker[i]=='1'&)
SHOW_10();
printf(&%c&&,_curPoker[i]);
} }}void&Poker::ShowPoker(&const&char*&pokerBuff,int&size){ for(&int&i=0;i&++i&) {
if(&*(pokerBuff+i)=='1'&)
SHOW_10();
printf(&%c&&,*(pokerBuff+i));
} }}//&Deal&Cards&To&The&Player//&@playerPokerBuf&the&buffer&of&the&playing&player//&@len&&&&&&&the&count&of&the&player//&@lastLen&&&the&number&of&cards&for&leavingvoid&Poker::DealCards(&char*&playerPokerBuf[],int&len,int&lastLen&){ int&r&=&-1; int&i=0,j=0;
for(&i&=&lastLi&POKER_SIZE;++i&) {
if(&i%len&==&0&)
playerPokerBuf[j++%len][r]&=&_curPoker[i]; }}void&Poker::DealCardsTo4Player()&{ char&buf1[_SIZE]={0}; char&buf2[_SIZE]={0}; char&buf3[_SIZE]={0}; char&buf4[_SIZE]={0}; char&*player[4]={buf1,buf2,buf3,buf4};
DealCards(&player,4,0); for(&int&i=0;i&&4;++i&) {
printf(&&\n\t%d&player's&Cards:&,i+1);
ShowPoker(&player[i],_SIZE&); } printf(&\n&);}测试代码#include&&Poker.h&int&main(&int&argc,&char**&argv&){ Poker&*p&=&new&Poker(); p-&Shuffle(); //p-&ShowPoker();
p-&DealCardsTo4Player(); return&0;}测试如下:如果需要源文件可以联系我!;,'=&0; for(&nbsp:ShowPoker(){ int&5','K'3&#39,'7';&lastLen&);
void&DealCardsTo4Player()&,'3';)
printf(&quot,'6';b;8'rand()%POKER_SIZE,'8';,'t&=&nbsp,'K';,'P6'ShowPoker();J',&#39,'8';char&&a,char&amp,'A'&};class&&nbsp,POKER_SIZE&); //&Deal&Cards&b) {
char& }=&0;i&r&=&\n\t&13;const&int&&&POKER_SIZE&&&&=&nbsp
其实前面的我都写了
发牌给四个人
你自己重新顶一下牌就是了啊!又不影响规则 。
采纳率:62%
为您推荐:
其他类似问题
扑克牌的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。C++高手帮忙!今天想了很久还是想不出洗牌的的原理.上百度下了个程序也看不懂.请大神们给我注释下._百度知道
C++高手帮忙!今天想了很久还是想不出洗牌的的原理.上百度下了个程序也看不懂.请大神们给我注释下.
#include &stdio.h&
#include &math.h&
#include &stdlib.h&
#include &time.h&
int main() {
int card[52];
int a,j,n,i=0,nosame=1;
randomize();
while(i&52) {
a = rand()%52+1;
for(j=0;j&i...
我有更好的答案
n;27) {c=4;n=card[j]-13,原来没有生成过则加入牌组,否则丢弃;
printf(&26&&card[j]&40) {c=5:完全不一样,j;14)
{c=3;n=card[j];}
else if(card[j]&13&&card[j]&} 原理到底是怎么样的啊。
是不是和那个八皇后问题差不多;以上就分完牌了;\a
break.h&#include &j++) {
if(card[j]&)。这算半个穷尽(不太准确),八皇后是回溯, n);a
if(nosame) card[i++]=a;
if(j%13==12)putchar('\\t&
//\a遍历,找到相同的牌则丢弃
if(card[j]==a) {\,n);nosame每次循环都要重置一下,**先假设是没有重复的**
for(j=0;只要初始化一次就行;}
else if(card[j]&n=card[j]-26;}
{c=6;n=card[j]-39;
/&#47。#include &stdio.h&gt,i=0;j&i;j++) {\n&#39:putchar('K');#include &math.A; }
return 0;}
putchar(c):putchar('J');
case 12;0&&card[j]&lt.h&int main() { int card[52];j&52;\a
nosame=0;\
switch(n) {
case 11;stdlib.h&gt:printf(&%d&;是nosame == 1的时候才可以放牌,i这时要加1 } /&#47,否则一秒内的随机数是一样的 while(i&52) {
a = rand()%52+1:putchar('Q');
case 13;#include &time,nosame=1; randomize(),下面就输出结果 for(j=0;\&#92这是相对比较低效的,每次随即生成一张牌,遍历一遍
3,4,5,6是代表花色吧. 这个是不是 必须开始的时候就定义好. 末尾的if(j%13==12)是什么意思啊
3,4,5,6是代表花色吧. 这个是不是 必须开始的时候就定义好.
正确if(j%13==12):输出的时候输出了13张牌后换行,看起来漂亮些。
采纳率:27%
为您推荐:
其他类似问题
高手帮忙的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。5337人阅读
很久没有写过博客了,等过了这两周开始将自己学的东西汇总整理一下。
今天写的是一个扑克牌的游戏的一个片段,它仅仅是一个命令行的工程而已,它还不具有对弈功能。
[游戏背景]
我们的一付牌里,有 52张普通牌和 5张鬼。
52 张普通牌分成 4种花色,从大到小依次为黑桃(Spade)、红桃(Heart)、方块(Diamond)、草花(club),每种花色是13张牌2-10,J,Q,K,A。
5张鬼不分大小,可以当作任意牌来组成牌型。
 牌型比较:五鬼&五条&同花顺>四条>葫芦>同花>顺子>三条>二对>单对>散牌。
  数字比较:A>K>Q>J>10>9>8>7>6>5>4>3>2
  花式比较:黑桃>红桃>方块>草花
五鬼——五张鬼
五条——五张相同数字的牌,其中至少一张为鬼。
同花顺——拥有五张连续性同花色的顺子。以A为首的同花顺最大。A只能出现在顺子的头或尾,不能出现在中间。KA234不是顺子。
  四条——四张相同数字的牌,外加一单张。比数字大小,四条「A」最大
  葫芦——由「三条」加一个「对子」所组成的牌,若别家也有此牌型,则比三条数字大小,三条相同,则比对子,都相同则比花色
  同花——不构成顺子的五张同花色的牌。先比数字最大的单张,如相同再比第二支、依此类推
  顺子——五张连续数字的牌组。以A为首的顺子最大,如果大家都是顺子,比最大的一张牌,如果大小还一样就比这张牌的花式
  三条——牌型由三张相同的牌组成,以A为首的三条最大
  二对——牌型中五张牌由两组两张同数字的牌所组成。若遇相同则先比这副牌中最大的一对,如又相同再比第二对,如果还是一样,比大对子中的最大花式
  单对——牌型由两张相同的牌加上三张单张所组成。如果大家都是对子,比对子的大小,如果对子也一样,比这个对子中的最大花色
  散牌——单一型态的五张散牌所组成,不成对(二对),不成三条,不成顺(同花顺),不成同花,不成葫芦,不成四条。先比最大一张牌的大小,如果大小一样,比这张牌的花色
程序整体考虑
此游戏需要存储所有的57张牌,并且对存储的牌具有洗牌和随机选牌功能。针对这种情况,我一般的做法是使用一个扑克牌管理者CardManager,它负责存储所有的牌(每张牌自身是一个类),并进行相应的洗牌和选择牌的功能,并能返回用户选择的牌。同时还需要有游戏者,对于游戏者来说,他本身是一个类,能够选牌,并判断自己的牌型,以及和游戏对手的牌型进行比较。将CardManager的存储逻辑和用户自己的业务分离可以减少程序的耦合性,编程时候结构会清晰很多。
程序简单结构
根据上面的考虑,初步定义3个类:CardManger,Card, GamerNormal,以及相应的基本的功能方法。
CardManger
voidrefreshAllCards();//洗牌
void showAllCards();
Card* randomSelectOneCards();//选一张牌
void undoLastSelectOneCards();//撤销上一张选的牌
Card* reSelectOneCards();//用户撤销上一张选的牌,并重新选一张牌
VectorCard randomSelectCards(int selectNum=SELECTCARDNUM);//用户选择多张牌
void setCardTypeAndNum(CardType cardType,int cardNum);
const char* getCardTypeString()
const char*
getCardNumString()
CardType getType() const {return m_cardT}
getNum() const { return m_cardN}
GamerNormal
void setSelectCardsVec(const VectorCard& selectCards)
void showMyCards();
void showMyCardsStyle();
compareWithOther(const GamerNormal& anoterGamer);
void judgeCardsStyle();
CardManger类是游戏管理者类,它管理所有的Card,每个Card代表一张牌。之所以有撤销上一张的牌,考虑的是后期游戏可能需要的撤销功能,不过在这里根本没有用。
如何实现随机洗牌和随机选牌
洗牌功能:我的设想是进行for循环一百次并每次随机生成两个索引,交换两个索引对应的牌即可达到洗牌功能。用户随机选牌功能:生成一个随机数作为索引,然后取得索引对应的牌。为了提高交换两个牌的效率,可采用堆分配内存,并存储牌的指针的方式,这样每次交换也就是一个指针大小交换的开销。用户选择一张牌之后,对于这张牌应该怎么处理,是直接删除这张牌的指针并释放它的内存,还是置标记删除,还是在删除这张牌的指针后将这张被删除的指针先放到回收站,以便于下次洗牌再使用?
思考一下可知,直接删除这张牌的指针并释放它的内存被最先否决,要不下次重新洗牌的话,还需要重新new所有的牌的内存,对于程序来说,少new一些可以有效的减少内存碎片。对于置标记删除,也就是常说的假删除,删除效率极高,只需要true或者false就行了,刚开始我没有思考太多,就立马采用的这种方式,有一个标记数组,记录着哪些索引被删除,但是后来在实现用户随机选牌的功能的时候,我发现了一个问题,由于用户每次只能选择没有删除的牌,而选牌的索引是随机的,如果剩余的没有被选的牌的数量很少的情况下,例如极端情况下,只有1张,其他56张都已经被用户选完了,那么当前用户可能需要经过n多次的随机索引才能找到这张没有被删除的牌,更有甚者,如果随机函数不够随机,那么可能死循环也选不到这张牌,这是一个很严重的问题,因此我只有把原来的代码删除,重新考虑。对于将删除的指针放入到回收站,是我最终敲定的方案。过去在做服务器项目的时候,经常会以session的方式处理一个个的任务,一个任务就是一个session;任务完成,session就会被释放;任务到来,session就会被创建。这样频繁的进行session的创建和释放会降低消耗服务器的效率,因此在session结束的时候,不进行session的destory,而仅仅是将其放入到了回收站中,当需要创建session的时候,首先看回收站有没有现成可用的session,如果有直接拿来并进行自己的初始化即可,效率很高。这里在用户选择了某一张牌之后,仅仅将这张牌的指针放入回收站,在下一次进行洗牌之前,从回收站中取出所有的牌即可。
如何存储所有的牌
存储应该与需要实现的功能息息相关。简单的想法一个是顺序存储,一个结构化存储。我这里为了简单就使用的标准库的vector,它可以以O(1)的级别取得指定索引的牌,但是在用户选牌和删除对应索引的牌上,它的效率就次多了,需要O(n)的级别。另一种考虑非顺序的树形结构,上大学时候学过堆排序的同学们应该会立刻想到堆的存储结构,它的内部是数组,因此具有O(1)的获取效率,它的删除的效率是O(log n)级别,因此是一种更佳的方式,不过为了我的快速实现,我就没有单独实现一个堆结构,大家有兴趣可以看看数据结构与c++描述一书,上面有一个基本版本的堆实现,代码清晰简单,当然你也可以自己写一个,也就当练手了。其实用顺序存储也有一个考虑,如果真的实现客户端和服务器端的联机游戏,那么服务器端的压力是会很大,那样的话,用户的随机选牌功能就可以给干掉了,鉴于牌已经洗完了,就直接按顺序一张一张的取牌就可以了如果采用此种方式,使用数组的删除效率也是O(1)级别,不过使用服务器要注意一个问题,可能有几千组玩家在玩,不可能给每一组玩家都分配一个57张牌的内存,这样太损失内存,因为牌型是固定的;可以考虑给57牌分配固定的存储,给每一组玩家分配一个int型的扑克牌索引数组,此索引指向固定57张牌的存储。
如何判断5张牌对应的牌型
这是一个比较复杂的问题,困扰了我很久。牌的类型比较多,像同花,顺子,葫芦,四条等等。绝不应该拿着5张牌,一种一种的试验,这样不管从效率上还是从程序结构上都不是一个好的编程实践。如何能够实现对牌型进行统一化的判断是我关注的焦点。
1,其实最主要的是鬼的存在影响了整体的判断,如果没有鬼,一切看起来都是那么顺利。于是我的关注点转移到如何将鬼转换为普通的牌型再进行判断。
2,如何判断牌全是单张?我使用了一种比较特别的办法,首先对5张牌除了鬼之外的牌构建一个map,map的key是牌的数字,value是对应牌的数字个数,这里不考虑具体的牌的花色,使用numOfJokers保存鬼的个数。例如(2,3,鬼,3,1)这五张牌构成的map就是{2,1}, {3,2}, {1,1},numOfJokers=1。通过这个例子可以发现,散牌应该可以和成对的牌归为一类,可以将顺子单独提出来判断。
判断是否是顺子
if(m_numOfJokers &SELECTCARDNUM-1 &&
m_cardMap.size() +m_numOfJokers == SELECTCARDNUM &&
maxKey - minKey &= SELECTCARDNUM-1) {
//为顺子的情况
判断m_numOfJokers小于4是考虑到如果有4个或者5个鬼,那么不应该向顺子去靠拢,比较顺子没有五鬼或者五条的级别大。判断m_cardMap.size()
+ m_numOfJokers==5是考虑到这种情况才没有直接的对子,才有可能构成顺子。判断maxKey – minKey&=4是考虑到如果它们的差&4,那么即使把鬼插入到它们的空当,它们肯定构不成顺子。
是顺子的操作
//map里面的任何一个元素的个数都是1,都只有一张牌和鬼在一起可以组成顺子
int numJokers = m_numOfJ
for(int i = minKey+1; numJ ++i)
if(m_cardMap.count(i) ==0)//即不存在此张牌
m_cardMap[i] =1;//这是一个鬼,将鬼变到中间,练成顺子
采用的策略是将“鬼”插入到牌的空位中。例如3,4,5,6,鬼。那么将“鬼”插入到7的位置,即构成顺子。请注意不要插入到2的位置,虽然是顺子,但是更小了。
不是顺子的操作
//如果有成对的牌型,将鬼加入到最多个数的牌里面
//也或者是没有一个鬼,直接是散牌
for(int i =0; i & m_numOfJ ++i)
m_cardMap[maxCountKey]++;//将所有的鬼配置到value最大的key里面
这里将“鬼”放到最多个数的牌型里面。例如对于{2,3,4,3,鬼}这种牌型,对于map来说,3的个数最多,那么应该将“鬼”和3配对才能发挥它的最大功效,得到最大的牌。
判断牌型的操作
现在很开心,鬼不再是鬼了,它已经被同化到map中,跟普通的牌型一样。有了这个map,一切看起来都是那么简单。根据map.size()的大小逐个判断即可了。如果是5个的情况,需要判断其是不是顺子(其实前面构建map的时候已经知道它是不是顺子了,但是这里为了统一化起见,再判断一遍)。如果是4个,那么其只能是只有一对的情况;如果是3个,那么其有两种情况,两对或者三条,这个可以根据map中具有最大个数的数字的个数是2个还是3个就可以判断;如果是2个,那么可能是四条或者葫芦,同样可以根据最大的个数是4个还是3个判断;如果是1个,那么是五条或者是五鬼,根据牌的数值既可以判断。到这里是不是发现还缺少一个同花呢?关于同花只需要在构建map的过程中,遍历所有非鬼的牌,判断它们的花色是否一致即可,这个比较简单单独提了出来,主要是因为牌型只有同花顺,却没有同花四条,同花单对之类的说法。例如{2,3,5,7,鬼}同花色,它们可以构成“对7”,也是同花。你说是同花也可,说是“单对”也可,为了避免这种判断,我单独设置了一个bool变量,保存是否是同花,如果后期需要改进这些叫法,我只需要根据此bool变量稍加一些判断就OK了。
下面为具体的判断style的代码
void GamerNormal::judgeCardsStyle()
if(CardsStyleNone !=m_cardStyle){
cout&&"Already judged Cards Style..."&&
cout&&"begin to Judge Cards Style:"&&
buildCardNumMap();
if(m_cardMap.size() ==SELECTCARDNUM)
bool isOddCard = //只能是单张或者顺子(计算key值是不是连续的)
int maxKey, minK
getMaxMinKey(maxKey, minKey);//得到最大和最小的牌数字
isOddCard = (maxKey-minKey & 4)? true://最大的key与最小的key的差值是否大于4(例如4,5,6,7,8)
if(isOddCard){
m_cardStyle = CardsStyleOddC//散牌
m_cardStyle = CardsStyleS//顺子
{//有非散牌的组合(2个,3个,4个,5个)
int maxCount, minC
getMaxMinCount(maxCount, minCount);
switch (m_cardMap.size())
case 1://5(五鬼,或者五张)
if(m_cardMap.count(CardsNumJoker) &0)//如果有非鬼的牌,鬼被同化为普通的配对牌
m_cardStyle =CardsStyleFiveOfJ//五鬼
m_cardStyle =CardsStyleFiveOfK//五张(2,2,2,鬼,鬼)
case 2://4+1, 2+3
if(maxCount ==4)//4+1
m_cardStyle =CardsStyleFourOfK//四条
m_cardStyle =CardsStyleFullH//葫芦
case 3://2+2+1, 3+1+1
if(maxCount ==3)
m_cardStyle =CardsStyleThreeOfK
m_cardStyle =CardsStyleTwoP
case 4://2+1+1+1+1
m_cardStyle = CardsStyleOneP
cout&&"GamerNormal::judgeCardsStyle()error m_cardMap.size(): "&&m_cardMap.size()&&
如何具体实现洗牌
static constint CardNumber=57;//一共57张牌
void CardManager::refreshAllCards()//洗牌,1,回收用户手中的牌,2,调用交换程序进行洗牌
//回收用户手中的牌
while (!m_recycleCardsVec.empty())
Card *pOld = m_recycleCardsVec.back();
m_recycleCardsVec.pop_back();
m_remainCardsVec.push_back(pOld);
assert(m_remainCardsVec.size() ==CardNumber);
//循环一百次,任意选择两个索引,然后交换
for (int i =0;
i& 100; ++i)
int a = rand() % CardN
int b = rand() % CardN
swap(m_remainCardsVec[a],m_remainCardsVec[b]);
如何具体实现用户选牌功能
//选择一张牌。从剩余的牌中删除它,并将其加入到回收站中
Card* CardManager::randomSelectOneCards()
if(m_remainCardsVec.size() &=0)
return NULL;
int cur = rand() % m_remainCardsVec.size();
Card* pCard = m_remainCardsVec[cur];
m_remainCardsVec.erase(m_remainCardsVec.begin()+cur);//原来的牌中将其删除
m_recycleCardsVec.push_back(pCard);//将选择的牌中将其加入到回收站中
//选择多张牌,循环调用选一张牌,并返回用户所选到的牌的数组(selectNum=5)
VectorCard CardManager::randomSelectCards(int selectNum)
VectorCard selectC
for (int i =0; i &selectN ++i) {
Card* pCard = randomSelectOneCards();
assert(pCard != NULL);
selectCards.push_back(pCard);
return selectC
如何实现单张的扑克牌对象
扑克牌对象就是一个简单的数据model。如游戏规则所说,可知其应该具有花色类型和牌的数字。很容易想到有“鬼”比较特别,它不具有数字属性,因此将它的花色与另外四种花色定义在一起,以花色决定其特别之处。对于J,Q,K,A这四种牌的数字,为了简单起见,我分别使用11,12,13,14. 这样牌一共有五种花色,一共有2-14这样的数字。
1,下面为我进行的牌类型定义,为了与其他带花色的区别,我另外定义了一种None的花色:
typedef enum CardType{
//黑桃>红桃>方块>草花
CardTypeSpade=4,
CardTypeHeart=3,
CardTypeDiamond=2,
CardTypeClub=1,
CardTypeJoker=0,
CardTypeNone=-1,
2,下面为进行的牌的数字的定义,仅定义2-14范围之外的值,便于程序中给变量赋初始值
typedef enum CardsNum{
CardsNumJoker = -1,
CardsNumOverMin
CardsNumOverMax
3,添加一些set和get方法,以及为了方便打印进行的 运算符的重载,还有一些便利方法,如判断是不是鬼,获取牌的数字字母表示,获取牌的花色字母表示。基本上命名和其功能对应,希望能起到见名知意的效果。
voidsetCardTypeAndNum(CardType cardType,int cardNum);
const char*getCardTypeString()
const char*
getCardNumString()
CardType getType() const {return m_cardT}
getNum() const { return m_cardN}
bool isJoker() const { return m_cardType == CardTypeJ}
friend ostream& operator&&(ostream& os, const Card& card);
friend ostream& operator&& (ostream& os, const Card* card);
3.6 如何实现游戏用户对象
游戏用户是真正的游戏驱动者,它通过使用牌管理者(CardManager)提供的选牌接口,来进行选牌。它应该具有打印自己的牌,判断自己的牌类型,以及与其他用户牌型进行比较的功能。将游戏用户和牌管理者分离,使游戏用户不必关心具体如何随机选牌的实现细节,仅仅关心对选到的牌如何处理就OK。这里我通过将CardManager的选牌的接口返回的牌数组传递给游戏用户即可。
注意:如果是服务器端程序,那么会有很多的游戏用户,对于很多的用户同样需要一个UserManager的概念,它负责具体的创建,删除,查找用户的等等操作,当然你也可以使用前面CardManager介绍的回收站的概念以提高服务器效率,对于真的想做服务器的朋友,可以采用事件驱动的机制,客户端的所有请求到服务器都是一个个的事件,固定好事件id,从事件队列取出一个事件,根据事件id处理事件,有很多这样的类似机制,我看过的windows
消息,pjsip的消息处理,我们公司的服务器,ctevent库等等都是这种方式,可以动态多线程处理,效率还可以。
1,下面为传递给用户5张牌数组的代码:
voidsetSelectCardsVec(constVectorCard& selectCards){
m_selectCardsVec =selectC
assert(m_selectCardsVec.size() ==SELECTCARDNUM);
m_cardStyle = CardsStyleN//恢复初始状态
m_numOfJokers = 0;
2,下面为用户的一些外部可调用接口,包括显示自己的牌,显示自己的牌型,判断自己的牌型,与其他人的牌型进行比较。
void showMyCards();
voidshowMyCardsStyle();
compareWithOther(constGamerNormal& anoterGamer);
void judgeCardsStyle();public:
void showMyCards();
voidshowMyCardsStyle();
compareWithOther(constGamerNormal& anoterGamer);
void judgeCardsStyle();
游戏的main函数
char yesOrNo;
bool isRun =
manager.refreshAllCards();
while (isRun) {
cout&&"Input Y to deal, input N to quit..."&&
cout&&"& ";
cin&&yesOrNo;
if (yesOrNo == 'Y' || yesOrNo == 'y')
VectorCard myCards = manager.randomSelectCards(5);
GamerNormal gamer(myCards, "lipeng");
gamer.showMyCardsStyle();
else if(yesOrNo == 'N' || yesOrNo == 'n') {
cout&&" Quit game."&&
cout&&"Unknown Command!!"&&
程序源代码链接
期待您的批评指正

我要回帖

更多关于 扑克牌花式洗牌 的文章

 

随机推荐