黑马程序员技术交流社区

标题: 每日一题之——扑克牌游戏的随机发牌 [打印本页]

作者: hello_world!    时间: 2012-11-2 10:57
标题: 每日一题之——扑克牌游戏的随机发牌
编写程序为一副扑克牌(除去大小王)随机发牌,要求输入玩家人数和每个玩家发牌的张数,程序在一副扑克牌中随机为每个玩家发牌,最后把发好的每一手牌输出出来。程序主要需要实现如下方法:
public static int[][] dispatch(intplayers,int cards);
方法参数说明:
       players:玩家人数,即发几手牌。
        cards:每手牌的张数。
方法返回值说明:
     返回int类型的二维数组,表示发给每个玩家的每一手牌,该数组的行数就是玩家个数,列数就是一手牌的张数。

    对扑克牌的抽象:
(1)我们可以用一个3位十进制整数来代表一张扑克牌,其中,百位代表牌的花色,如下编码:
  
编码值
  
花色
1
黑桃
2
红桃
3
梅花
4
方块
十位和个位代表牌的点数,如下编码:
  
编码值
  
点数
02
2
03
3
04
4
05
5
06
6
07
7
08
8
09
9
10
10
11
J
12
Q
13
K
14
A
例如:211代表红桃J408代表方块8
2)如何确保在发牌时不会有重复的牌被发出。
随机发牌程序的实现原理:采用生成随机数的形式,生成牌的点数和花色,由点数和花色构成一张牌。将所有生成的牌存放在数组中,每当生成一张新的扑克牌时,依次将这张牌与数组中的每张牌去比较,若数组中已有这张牌,则重新生成下一张牌,若数组中没有这张牌,则将这张牌存放在数组中。

/**
          * 在一副扑克牌(除去大小王)中随机发牌,
          * 发给players个人,每个人发cards张牌。
          * @param players 人数。
          * @param cards 每手牌的张数。
          * @return 发好的牌,用二维int数组表示。
          */
         public static int[][] dispatch(int players,int cards){
                   if(players<=0 ||cards<=0){
                            System.out.println("无效的发牌参数:玩家人数和每手牌的张数必须大于零!");
                            return null;
                   }
                   if(players*cards>52){
                            System.out.println("无效的发牌参数:发牌总数大于扑克牌的张数!");
                            return null;
                   }
                   int[] allCards=new int[52];//用来存放所有54张牌的数组。
                   int k=0;
//               依次生成所有52张牌。
                   for(int i=1;i<=4;i++){
                            for(int j=2;j<=14;j++){
                                     allCards[k]=i*100+j;
                                     k++;
                            }
                   }
                   //先随机抽出要发的牌
                   int[] dispatchCards=new int[players*cards];
                   int num=0;
                   outer:while(num<dispatchCards.length){
                            int index=(int)(Math.random()*allCards.length);
                            for(int i=0;i<num;i++){
                                     if(dispatchCards==allCards[index]){
                                               continue outer;
                                     }
                            }
                            dispatchCards[num++]=allCards[index];
                   }//while end!
                   //然后将所有抽出的牌分发到二维数组中。
                   int[][] cs=new int[players][cards];
                   int index=0;
                   for(int i=0;i<cs[0].length;i++){
                            for(int j=0;j<cs.length;j++){
                                     cs[j]=dispatchCards[index++];
                            }
                   }
                  
                   return cs;
         }//dispatch end!


求更好的解法。。。


作者: 林晓泉    时间: 2012-11-2 12:06
楼主的想法不符合面向对象啊
首先确定这个扑克牌类的成员(这个类用单例模式写比较好)
变量:4个花色,10个点数
方法:构造函数()   生成一副牌54张,顺序无所谓,返回值应该是一个二维数组,a[54][3] ,54是牌的数量,一维数组中3个元素分别是花色,点数和位置标示符(用于确定这张牌的位置)
      洗牌();   这个方法没有参数,返回值是个二维数组,我的想法是将一个随机数赋给位置标示符,然后将位置标示符排序,就将原来牌的顺序打乱了
          发牌();  返回值是手牌类数组,这个方法的参数应该是人数,人数定的话发的牌数就是54/人数,然后按顺序发牌即可,调用手牌类的收进方法
既然是发牌,那应该还有一个类,就是手牌类
变量: 手牌数组
成员:  收进();  
             打出();
我的思路暂时到这,今晚回去试试写写看,希望对你有帮助




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2