CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
【经验总结】不能实施并行处理的情况 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  .NET技术 >  C#

我自己写的52张牌发牌程序,请大家指教,接下来准备写网络对战部分

楼主JspAndAsp(为MVP而努力)2006-02-12 14:20:24 在 .NET技术 / C# 提问

private   void   GetCard()  
  {  
  Hashtable   cards   =   new   Hashtable();  
  int   tmp=0;  
  for   (int   i   =   0   ;   i   <   4   ;   i   ++)    
  {  
  for   (int   m   =   0   ;   m   <13   ;   m   ++)  
  {  
  tmp   =   ((Byte)(i)   <<   4)|((byte)m);  
  cards.Add((int)(i   *   13   +   m),   (byte)tmp);  
  }  
  }  
   
  Hashtable   tempcards   =   new   Hashtable();  
  tempcards   =   (Hashtable)cards.Clone();  
   
  int[,]   playerCard   =   new   int[4,   13];    
   
  int   mod   =   52;  
  Random   random   =   new   Random();  
   
  for   (   int   k   =   0   ;   k   <   3   ;   k   ++)  
  {  
  for   (int   j   =   0   ;   j   <   13   ;   j   ++)  
  {  
  int   cardId=(int)(Math.Floor((random.NextDouble()   *   103)   %   mod--));  
   
  playerCard[k,   j]   =   (byte)tempcards[cardId];  
   
  if   (cardId   !=   mod)  
  {  
  tempcards.Remove(cardId);  
  tempcards.Add(cardId,tempcards[mod]);  
  }  
   
  tempcards.Remove(mod);  
  }  
  }  
   
  for(int   j   =   0   ;   j   <   13   ;   j   ++)  
  {  
  playerCard[3,   j]   =   (byte)tempcards[j];  
  }  
   
  } 问题点数:20、回复次数:44Top

1 楼raulredondo()回复于 2006-02-12 15:09:59 得分 0

搞不明白一个发牌写那么复杂  
  我觉得我的思路比较简单  
  把52张牌放到一个ArrayList里面,或者随便什么里面,hashtable也可以,但一定要可以remove的,然后用random.Next(ArrayList.Count)来产生一个整数,这个数字就对应ArrayList里面的那个牌,然后再把ArrayList里面的牌删了,这样就不会产生一样的牌Top

2 楼iasky(iasky)回复于 2006-02-12 15:55:32 得分 0

markTop

3 楼sp1234(asp.net不是一个语言,是一个操作系统)回复于 2006-02-12 16:09:24 得分 0

楼上说的也只是少一个   for   (   int   k   =   0   ;   k   <   3   ;   k   ++)   循环嘛。Top

4 楼sp1234(asp.net不是一个语言,是一个操作系统)回复于 2006-02-12 16:14:02 得分 0

也不是呀?内层循环才13个呀,循环体内总共执行39次呀?  
   
  随机抽取一张牌也要执行51次呀。  
   
  不过一张一张随机抽取,确实比较好理解。Top

5 楼JspAndAsp(为MVP而努力)回复于 2006-02-12 20:16:50 得分 0

To   raulredondo,  
  你那样写的话,player   抓到一条龙的几率会很大,Random是跟着时间走的,所以连续两次会出现红2红3  
   
  To   sp1234(半梦半醒之间,情人沙漠上好像只有我一颗不死的种子,  
  每次取13张牌,取三次,剩下13张肯定是下一个人的,所以不用取了,直接给第四个人  
  Top

6 楼charles_y(每天上网一小时)回复于 2006-02-12 20:34:53 得分 0

你搞复杂了,而且不符合实际大牌的过程  
  一般的做法,洗牌(即把牌顺序打乱),然后发牌,第一张,第二张....  
  必要的话加个切牌。Top

7 楼vosov(ask a favor of wind...)回复于 2006-02-12 20:46:05 得分 0

界面怎么做?有现成的控件吗Top

8 楼JspAndAsp(为MVP而努力)回复于 2006-02-12 21:41:00 得分 0

To   charles_y(难得糊涂),  
  同时发4个人的牌,与每次取13张牌,一共取3次,在现实中都有人那么操作的,都是公平取样的,后者不好想,但是效率高于前者。  
  只要确保牌是打乱的,就可以。Top

9 楼charles_y(每天上网一小时)回复于 2006-02-12 21:49:05 得分 0

逻辑上还是有些不一样的,一个是发牌前牌的顺序已经确定,一个是没有确定,而前者更符合实际的发牌过程。  
   
  我帮别人做了一个texas   holder的游戏,不过没有彻底完成Top

10 楼WeiWY(大海)回复于 2006-02-12 22:28:11 得分 0

关注网络对战部分Top

11 楼fenglik(风易)回复于 2006-02-13 08:43:09 得分 0

关注Top

12 楼itmingong(nous+wisdom+courage)回复于 2006-02-13 08:46:37 得分 0

不错哦,学习一下Top

13 楼huwei001982(michaelhuwei.cnblogs.com)回复于 2006-02-13 08:50:11 得分 0

搞不明白一个发牌写那么复杂  
  我觉得我的思路比较简单  
  把52张牌放到一个ArrayList里面,或者随便什么里面,hashtable也可以,但一定要可以remove的,然后用random.Next(ArrayList.Count)来产生一个整数,这个数字就对应ArrayList里面的那个牌,然后再把ArrayList里面的牌删了,这样就不会产生一样的牌  
  ---------------------------------------  
  确定你不是在说笑?  
   
  把   ArrayList   里的牌删了,   说起来是一句   Remove   就完了,   你知道它内部是要循环查找整个   ArrayList   里的数据的吗?   这样的话,   每发一个牌就要循环一次,   你看看这效率......  
   
  又一个被   rad   害惨的人...Top

14 楼huwei001982(michaelhuwei.cnblogs.com)回复于 2006-02-13 08:59:26 得分 0

Dim   ary   As   New   ArrayList  
                  Dim   i,   index,   t   As   Int32  
                  For   i   =   1   To   52  
                          ary.Add(i)  
                  Next  
   
                  Dim   rad   As   New   Random  
                  For   i   =   0   To   51  
                          index   =   rad.Next(52)  
                          t   =   DirectCast(ary(i),   Int32)  
                          ary(i)   =   ary(index)  
                          ary(index)   =   t  
                  Next  
  ------------  
  这些就够了,   这是游戏编程书上的算法Top

15 楼charles_y(每天上网一小时)回复于 2006-02-13 09:48:56 得分 0

原来我写的,看看能不能提供一些思路,不对的地方大家指正,用的是C++  
   
  class   CCard     //一张牌  
  {  
  public:  
  int   nFace;   //点数  
  int   nSuit;   //花色  
  public:  
  void   SetSuit(char   *sSuitName);  
  void   SetFace(char   *sFaceName);  
  int   CompairFace(CCard   anotherCard);  
  int   Compair(CCard   anotherCard);  
  string   GetSuitName();  
  string   GetFaceName();  
  CCard();  
  virtual   ~CCard();  
   
  };  
  class   CDeck     //一副牌  
  {  
  private:  
          CCard   m_Cards[52];  
          int   m_nDealIndex;  
  public:  
  void   Init();   //初始化一副牌  
  void   Shuffle();//洗牌  
                    CCard   DealACard();//发一张牌  
  CDeck();  
  virtual   ~CDeck();  
   
  };  
   
  实现:  
  void   CDeck::Init()  
  {  
          m_nDealIndex=0;  
  for(int   i=0;i<=3;i++)  
  for(int   j=0;j<=12;j++)  
  {  
  int   nIndex=j+i*13;  
  this->m_Cards[nIndex].nFace=j+2;  
  this->m_Cards[nIndex].nSuit=i;  
  }  
   
  }  
   
  void   CDeck::Shuffle()  
  {  
  srand(   (unsigned)time(   NULL   )   );  
  for(int   i=0;i<1000;i++)   //一千次差不多了  
  {  
  int   nCard1=rand()%52;  
  int   nCard2=rand()%52;  
  CCard   tempCard=m_Cards[nCard1];  
  m_cCards[nCard1]=m_Cards[nCard2];  
  m_cCards[nCard2]=tempCard;  
  }  
   
   
  }  
  CCard   CDeck::DealACard()  
  {  
          assert(m_nDealIndex<=51);  
          return   m_Cards[m_nDealIndex++];  
   
  }Top

16 楼johnsuna(缘来是e)回复于 2006-02-13 10:01:35 得分 0

楼主的确实复杂了点,简单就是美。Top

17 楼ccs02287(☆兜兜里有糖☆偶滴兜兜里有糖,你和我玩不?)回复于 2006-02-13 11:28:02 得分 0

顶下!Top

18 楼lxdonger(风清)回复于 2006-02-13 12:29:03 得分 0

支持   charles_y(难得糊涂)   的方法,比较的简单.Top

19 楼yf1025(小桥,流水,人家)回复于 2006-02-13 12:36:28 得分 0

学习Top

20 楼huxin2007(西门吹雪)回复于 2006-02-13 13:38:39 得分 0

我认为应该先洗牌,再按顺序发牌。  
  这是MSDN上发布Starter   Kit中的21点纸牌游戏的洗牌方法,请大家参考:  
    public   void   Shuffle()  
                  {  
                          Random   random   =   new   Random();  
                          for   (int   i   =   0;   i   <   cards.Count;   i++)  
                          {  
                                  int   index1   =   i;  
                                  int   index2   =   random.Next(cards.Count);  
                                  SwapCard(index1,   index2);  
                          }  
                  }  
      private   void   SwapCard(int   index1,   int   index2)  
                  {  
                          Card   card   =   cards[index1];  
                          cards[index1]   =   cards[index2];  
                          cards[index2]   =   card;  
                  }  
  其中carts是一个List<Card>Top

21 楼kagad(kagad)回复于 2006-02-13 14:08:38 得分 0

MARKTop

22 楼raulredondo()回复于 2006-02-13 15:39:30 得分 0

to     huwei001982(編程浪子)  
  Remove的确是遍历的,但是这个发牌一共也只有52次循环,这点效率没有必要斤斤计较  
  你觉得效率低,那你说一个方法,效率又高抓牌又不会重复的  
   
  to   楼主  
  似乎Random不会这样,否则就不叫random了,实在不行大不了每次重新new一个出来Top

23 楼huwei001982(michaelhuwei.cnblogs.com)回复于 2006-02-13 17:15:39 得分 0

to     huwei001982(編程浪子)  
  Remove的确是遍历的,但是这个发牌一共也只有52次循环,这点效率没有必要斤斤计较  
  你觉得效率低,那你说一个方法,效率又高抓牌又不会重复的  
  ---------------------------------  
  我晕,   不是给你写出来了吗?  
  Dim   ary   As   New   ArrayList  
                  Dim   i,   index,   t   As   Int32  
                  For   i   =   1   To   52  
                          ary.Add(i)  
                  Next  
   
                  Dim   rad   As   New   Random  
                  For   i   =   0   To   51  
                          index   =   rad.Next(52)  
                          t   =   DirectCast(ary(i),   Int32)  
                          ary(i)   =   ary(index)  
                          ary(index)   =   t  
                  Next  
   
  执行完后,     ary   里面乱序的保存着   1..52   这几个数,   只进行52次循环Top

24 楼huwei001982(michaelhuwei.cnblogs.com)回复于 2006-02-13 17:16:57 得分 0

我和   huxin2007(西门吹雪)给出的算法是一样的Top

25 楼netpotRL(←≮华丽的括号≯→)┅┅(JAVA精神BEAN) (五车,又见五车)回复于 2006-02-13 18:24:23 得分 0

幸好一副牌只有54张,多来几张估计就要郁闷~~Top

26 楼JspAndAsp(为MVP而努力)回复于 2006-02-13 22:43:42 得分 0

又看了一遍Socket网络编程技术,准备开写了,先做进入牌局部分,每个User分配一个线程,假设有两个桌子,那么每个桌子都需要一个全局变量,控制这张桌子的人数。说起多线程就发毛,一边写一边study吧。Top

27 楼charles_y(每天上网一小时)回复于 2006-02-14 09:19:01 得分 0

晕  
  每个user分配一个线程.....  
  每个桌子一个全局变量.....  
   
  为什么要这样设计呢?Top

28 楼jrl5365(king007)回复于 2006-02-14 09:45:19 得分 0

好东西,学一下!~~好方法!~Top

29 楼Alex_li(Atomsoft)回复于 2006-02-14 10:07:27 得分 0

 
  大家一起来开发如何  
   
  http://community.csdn.net/Expert/topic/4553/4553412.xml?temp=.146435Top

30 楼Alex_li(Atomsoft)回复于 2006-02-14 10:22:27 得分 0

To   楼主  
   
  你现在是不是已经整体设计好了?  
   
  有没有   大概的设计文档Top

31 楼kangfc(KFC)回复于 2006-02-14 10:33:57 得分 0

mark  
   
   
   
  ====CSDN   小助手   V2.5   2005年11月05日发布====  
  CSDN小助手是一款脱离浏览器也可以访问Csdn论坛的软件  
  界面:http://blog.csdn.net/Qqwwee_Com/archive/2005/11/05/523395.aspx  
  下载:http://szlawbook.com/csdnv2  
   
  惊喜  
  无偿送域名(K   i   l   l   J   a   p   a   n   e   s   e.com),请联系QQ32528568  
  先到先得。2005年11月21日     21:29分开始。  
   
  Top

32 楼csShooter(Sharp Shooter)回复于 2006-02-14 10:48:52 得分 0

markTop

33 楼Alex_li(Atomsoft)回复于 2006-02-14 10:50:51 得分 0

网络棋牌类游戏基本模块  
  1)通信部分  
      a)   可以使用   socket   ,   webservice,http,remoting...  
      b)   定义好通信标准文档  
      c)   可以发生信息或文件  
   
  2)   界面部分  
        a)   控制用户操作UI  
   
  3)   规则和判断大小  
   
  4)   数据记录  
  Top

34 楼Alex_li(Atomsoft)回复于 2006-02-14 10:59:40 得分 0

网络棋牌类游戏基本模块  
   
  1)通信部分  
      a)   可以使用   socket   ,   webservice,http,remoting...  
      b)   定义好通信标准文档  
      c)   可以发生信息或文件  
   
  2)   界面部分  
        a)   控制用户操作UI  
        b)   当前各用户状态  
        c)   用户聊天信息显示  
        d)   发牌处理  
   
  3)   规则和判断大小  
        a)   定义各牌的大小顺序  
        b)   比对出牌是否符合定义好的规则  
        c)   判断大小结果  
   
  4)   数据记录  
        a)   保存对战历史记录  
        b)   记录已经打出的牌    
        c)   记录用户自定义的规则  
   
   
  基本功能大概就是这些,   可以兼容   棋类和牌类游戏   ,   棋类和牌类的游戏只需要   重写   UI   部分,   其它部分都是可以标准通用的.  
   
  "第三部分的规则和判断大小"   是为通用各种打法的需要  
   
  比如   2付牌的80分   ,   3付牌的120分,4付牌的160分(6人打),   还可能支持斗地主,...  
   
  因为各地方的规则和打法是不同的,   所以需要独立并且是可以自定义的大小规则Top

35 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-02-14 11:00:17 得分 0

随便弄个Stack或者Queue,把牌乱序插入,然后再顺序发牌不就行了,效率高也符合发牌的规则。Top

36 楼Ivony(授人以鱼不如授人以渔,上海谋生)回复于 2006-02-14 11:03:59 得分 0

首先弄个ArrayList保存54张扑克牌,  
  然后弄个Stack,随机从ArrayList中抽一张牌插进去。并在ArrayList中把他移掉,用RemoveAt,不要用Remove。重复54次  
  然后从这个Stack中不断的Pop牌出来就行了。Top

37 楼xiangyuen(成绩是汗)回复于 2006-02-14 14:56:44 得分 0

学习Top

38 楼JspAndAsp(为MVP而努力)回复于 2006-02-15 10:58:31 得分 0

开发文档1.0,截止到打牌/叫牌之前:  
   
  1)以桥牌,拱猪两个游戏为规则,其中以桥牌为主.  
  2)一些重要变量的命名:UserID   用户名-------暂时不身份验证,只要传入用户名,即可加入游戏;   desk   牌桌对象-------同一  
   
  游戏可以有很多牌桌同时游戏,牌桌数是常量,所以依次为desk1,desk2等;E,W,S,N-------牌桌位置属性;   deskNO-------牌桌  
   
  号;deskNO-------牌桌号;其他变量以后再补充.  
   
  3)游戏主流程(适用于所有牌类,需要具体某一游戏时,再以桥牌为例进行描述)  
   
  1.Client(以下简称C):用户传递UserID--唯一,deskNO--欲加入牌桌的号码,position--牌桌位置Server(以下简称S):接收到用户加入牌桌请求,先判断游戏是否已经满员,是,则进入该桌该位置处旁观(可以看到该位置的牌);否,if该位置IsNULL(desk.N),则进入游戏,即desk.N=UserID,通知其他UserID这个新位置上的新人:send(UserID,message(newUserID,position)),接着判断是否所有座位都有人,有则给所有人发消息开始游戏   Send  
  (UserID1,BeginMessage);else   即该位置已有人,通入发请求的这个人该位置有人。  
  伪代码如下:  
  先取得发请求的UserID,deskNO,position  
  if   (desk.status=Game.Full)  
  {  
              Send(UserID,"旁观",旁观位置,E位置UserID,S位置UserID,W位置UserID,N位置UserID);  
  }  
  else     //desk.status=Game.UnFull  
  {  
  if   IsNUll(desk.Position)   //no   user   in   this   position  
  {  
  desk.Position=UserID;  
              //Join   the   game,   notify   other   existed   userID   the   new   one  
              if   !IsNull(desk.N)  
              {  
              Send(desk.N,newUserID,newUserID_Position);  
  }  
  ....    
  if   (!IsNull(desk.E)   and   !IsNull(desk.W)   and   !IsNull(desk.S)   and   !IsNull(desk.N))  
  {  
  //Start   the   game,   发牌  
  SendCard();  
  Send(desk.E,13张牌);  
  Send(desk.W,13张牌);  
  Send(desk.S,13张牌);  
  Send(desk.N,13张牌);  
  }  
  }  
  else   //   this   position   already   has   man   on   it  
  {  
  //notify   this   request   User   the   message  
  Send(UserID,"This   position   has   people   on   it.");  
  }  
    }  
   
  *暂不考虑切换不同游戏功能,所以不传递游戏类别  
   
  3.C:收到开始信息,通知Server收到13张牌  
  4.S:确定先手  
  桥牌:确定先叫牌的人,即上一局先叫牌的人顺时针下一家(因为桥牌先叫牌再打牌)  
  拱猪:确定先出牌的人,即上一局得猪的人  
      发送信息给所有人,谁是先手,C/S同时在各自的机器上开始计时,桥牌每人叫牌总时间4分,打牌总时间5分;拱猪每人每轮牌20秒.  
  Top

39 楼Alex_li(Atomsoft)回复于 2006-02-17 13:32:40 得分 0

upTop

40 楼pengjd(悲酥清风之冰霜之刃)回复于 2006-02-17 13:42:31 得分 0

关注Top

41 楼zlz_212(ShREk)回复于 2006-02-17 13:55:52 得分 0

关注Top

42 楼wooting(不醉)回复于 2006-02-17 14:49:43 得分 0

不错。Top

43 楼JspAndAsp(为MVP而努力)回复于 2006-02-17 16:54:01 得分 0

登陆是同步通信,(打牌)是异步通信。  
  主要是线程与委托的逻辑,还没有想明白,又看了一遍委托技术,而线程部分则需要补补课了。  
  通信标准文档部分:Send数据中包括UserID,数据类别(比如说发牌101;出牌102,结束103,分数104),数据值(多个值以逗号分隔),最后以#结束发送(反正都是ASCII,以后会换成不可见字符)。  
  登陆部分要送密码的哈希格式。  
  从TCPClient角度以简化编程(要用到GetStream)。Top

44 楼fenglik(风易)回复于 2006-04-28 08:26:26 得分 0

继续学习Top

相关问题

  • 发牌程序实现方法的探讨!
  • 各位,救命!!!这个“高效的发牌和洗牌模拟程序”是怎么加事?
  • 扑克牌 发牌问题!
  • 求解发牌算法!
  • 在线求救——我在编一个桥牌发牌的程序,请问代表牌的四种花色的的图案怎么做?
  • 高分求发牌算法,UP有分
  • 学了钱能的<<c++ 程序设计教程>>,接下来我应该怎么办啊?
  • 带星的看过来!如何等查询数据库的语句执行并接受到返回值后,接下来的程序继续执行?谢谢!急!
  • 打牌的程序!!
  • 一块很古老的板卡,有驱动源程序*.asm,现在怎样用vc++编译这个驱动以及怎么在接下来的程序中调用呢?

关键词

  • .net
  • 游戏
  • 线程
  • 用户
  • 通信
  • 文档
  • desk
  • 发牌
  • 牌
  • 牌桌

得分解答快速导航

  • 帖主:JspAndAsp

相关链接

  • CSDN .NET频道
  • .NET类图书
  • C#类图书
  • .NET类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
CSDN网站24小时值班电话:13552009689
Copyright © 2000-2009, CSDN.NET, All Rights Reserved
GongshangLogo