黑马程序员技术交流社区
标题: 每日一题之——扑克牌游戏的随机发牌 [打印本页]
作者: hello_world! 时间: 2012-11-2 10:57
标题: 每日一题之——扑克牌游戏的随机发牌
编写程序为一副扑克牌(除去大小王)随机发牌,要求输入玩家人数和每个玩家发牌的张数,程序在一副扑克牌中随机为每个玩家发牌,最后把发好的每一手牌输出出来。程序主要需要实现如下方法:
public static int[][] dispatch(intplayers,int cards);
方法参数说明:
players:玩家人数,即发几手牌。
cards:每手牌的张数。
方法返回值说明:
返回int类型的二维数组,表示发给每个玩家的每一手牌,该数组的行数就是玩家个数,列数就是一手牌的张数。
对扑克牌的抽象:(1)我们可以用一个3位十进制整数来代表一张扑克牌,其中,百位代表牌的花色,如下编码:
十位和个位代表牌的点数,如下编码:
例如:211代表红桃J,408代表方块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 |