Java洗牌

如何得到一副洗过的牌的集合呢,如果用JAVA实现,最方便的就是调用Collections的方法[b]shuffle[/b]来进行洗牌。一个很简单的随机产生纸牌的思路如下:

根据纸牌的张数(length),上千次产生0~ length-1的随机数,然后产生随机数对应位置的纸牌与第一张纸牌进行交换,经过上千次的交换,足以达到使纸牌乱序的效果。

该小程序能够产生一副或者多幅随即牌。

具体的程序如下.

package cards.util;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
* <code>CardsUtil</code>是一个随机产生纸牌的工具类
* <p>
* 1. 利用Collections的方法shuffle来进行洗牌 2. 根据纸牌的长度(length),上千次产生0~ length-1的随机数,
* 然后产生随机数的纸牌与第一张纸牌进行交换,经过上千次的交换 足以达到使纸牌乱序的效果。
* </p>
*
* @author Eric
* @version 1.0
*
*/
public final class CardsUtil {

/**
* @param includeJoker
* 是否需要包括大小王
* @return
*/
private static List<Card> initCards(boolean includeJoker) {
List<Card> cardList = new ArrayList<Card>();
for (int i = 1; i <= 13; i++) {
cardList.add(new Card(i, CardType.SPADES));
cardList.add(new Card(i, CardType.HEARTS));
cardList.add(new Card(i, CardType.DIAMONDS));
cardList.add(new Card(i, CardType.CLUBS));
}
if (includeJoker) {
cardList.add(new Card(0, CardType.LITTLE_JOKER));
cardList.add(new Card(0, CardType.BIG_JOKER));
}
return cardList;
}

/**
*
* @param number
* 牌的数量(2副,3副.....)
* @param includeJoker
* 是否需要包括大小王
* @return
*/
private static List<Card> initCards(int number, boolean includeJoker) {
List<Card> cardList = new ArrayList<Card>();
for (int i = 0; i < number; i++) {
cardList.addAll(initCards(includeJoker));
}
return cardList;
}

/**
* 调用Collections的shuffle方法来达到乱序的效果
*
* @param list
* @return
*/
public static List<Card> shuffleByCollections(List<Card> list) {
Collections.shuffle(list);
return list;
}

/**
* 根据纸牌的长度(length),上千次产生0~ length-1的随机数, 然后产生随机数的纸牌与第一张纸牌进行交换,经过上千次的交换
* 足以达到使纸牌乱序的效果。 (此方法适用于一副牌的时候)
*
* @param list
* @param includeJoker
* @return
*/
public static List<Card> shuffle(List<Card> list, boolean includeJoker) {
int seed = includeJoker ? 54 : 52;
Random random = new Random();
int randomNumber = 0;
for (int i = 0; i < 1000; i++) {
randomNumber = random.nextInt(seed);
swapCard(list, randomNumber);
}
return list;
}

private static List<Card> swapCard(List<Card> list, int randomNumber) {
Card temp = list.get(0);
list.set(0, list.get(randomNumber));
list.set(randomNumber, temp);
return list;
}

/**
* 根据纸牌的长度(length),上千次产生0~ length-1的随机数, 然后产生随机数的纸牌与第一张纸牌进行交换,经过上千次的交换
* 足以达到使纸牌乱序的效果。 (此方法适用于一副牌或者多幅牌的时候)
*
* @param list
* @param number
* @param includeJoker
* @return
*/
private static List<Card> shuffle(List<Card> list, int number,
boolean includeJoker) {
int seed = includeJoker ? 54 * number : 52 * number;
Random random = new Random();
int randomNumber = 0;
for (int i = 0; i < 1000 * number; i++) {
randomNumber = random.nextInt(seed);
swapCard(list, randomNumber);
}
return list;
}

/**
* 获取一副牌,洗牌后的结果
*
* @param includeJoker
* @return
*/
public static List<Card> retrieveShuffledCards(boolean includeJoker) {
return shuffle(initCards(includeJoker), includeJoker);
}

/**
* 获取一副牌或者多副牌,洗牌后的结果
*
* @param number
* @param includeJoker
* @return
*/
public static List<Card> retrieveShuffledCards(int number,
boolean includeJoker) {
return shuffle(initCards(number, includeJoker), number, includeJoker);
}

/**
* 调用Collectios 的shuffle方法, 获取一副牌,洗牌后的结果
*
* @param includeJoker
* @return
*/
public static List<Card> retrieveShuffledCardsByCollections(
boolean includeJoker) {
List<Card> cardList = initCards(includeJoker);
Collections.shuffle(cardList);
return cardList;
}

/**
* 调用Collectios 的shuffle方法, 获取一副牌或者多副牌,洗牌后的结果
*
* @param number
* @param includeJoker
* @return
*/
public static List<Card> retrieveShuffledCardsByCollections(int number,
boolean includeJoker) {
List<Card> cardList = initCards(number, includeJoker);
Collections.shuffle(cardList);
return cardList;
}

}



package cards.util;

import java.util.HashMap;
import java.util.Map;

public enum CardType {

SPADES("S", "黑桃"), HEARTS("H", "红桃"), DIAMONDS("D", "方块"), CLUBS("P", "梅花"), BIG_JOKER(
"BJ", "大王"), LITTLE_JOKER("LJ", "小王"), UNKNOWN("U", "UNKNOWN");

private static final Map<String, CardType> MAP = new HashMap<String, CardType>();
static {
for (CardType cardType : CardType.values()) {
MAP.put(cardType.getCardTypeCode(), cardType);
}
}

private String cardTypeCode = null;

private String cardTypeDescription = null;

public CardType getCardTypeByCode(String cardTypeCode) {
return MAP.containsKey(cardTypeCode) ? MAP.get(cardTypeCode) : UNKNOWN;
}

/**
* @return the cardTypeCode
*/
public String getCardTypeCode() {
return cardTypeCode;
}

/**
* @param cardTypeCode
* the cardTypeCode to set
*/
public void setCardTypeCode(String cardTypeCode) {
this.cardTypeCode = cardTypeCode;
}

/**
* @return the cardTypeDescription
*/
public String getCardTypeDescription() {
return cardTypeDescription;
}

/**
* @param cardTypeDescription
* the cardTypeDescription to set
*/
public void setCardTypeDescription(String cardTypeDescription) {
this.cardTypeDescription = cardTypeDescription;
}

/**
* @param cardTypeCode
* @param cardTypeDescription
*/
private CardType(String cardTypeCode, String cardTypeDescription) {
this.cardTypeCode = cardTypeCode;
this.cardTypeDescription = cardTypeDescription;
}

}


package cards.util;

import java.io.Serializable;

public class Card implements Serializable {

private static final long serialVersionUID = 4709869689433952388L;

// 纸牌的点数
private int points = 0;
// 纸牌类型
private CardType cardType = null;

public Card() {
}

/**
* @param points
* @param cardType
*/
public Card(int points, CardType cardType) {
this.points = points;
this.cardType = cardType;
}

/**
* @return the points
*/
public int getPoints() {
return points;
}

/**
* @param points
* the points to set
*/
public void setPoints(int points) {
this.points = points;
}

/**
* @return the cardType
*/
public CardType getCardType() {
return cardType;
}

/**
* @param cardType
* the cardType to set
*/
public void setCardType(CardType cardType) {
this.cardType = cardType;
}

}


package cards.util;

import java.util.List;

public class CardsTest {

public static void main(String[] args) {

boolean includeJoker = true;//true代表包括大小王,false则不包括
int number = 1;//number代表几幅牌,默认为一副牌
System.out.println("************** 一副牌(包括大小王)洗牌后的结果 (start)******************");
printCards(CardsUtil.retrieveShuffledCards(number, includeJoker));
System.out.println("************** 一副牌(包括大小王)洗牌后的结果 (end)******************");
System.out.println();
includeJoker = false;
System.out.println("************** 一副牌(不包括大小王)洗牌后的结果 (start)******************");
printCards(CardsUtil.retrieveShuffledCards(number, includeJoker));
System.out.println("************** 一副牌(不包括大小王)洗牌后的结果 (end)******************");
System.out.println();
includeJoker = true;
number=2;
System.out.println("************** 两副牌(包括大小王)洗牌后的结果 (start)******************");
printCards(CardsUtil.retrieveShuffledCards(number, includeJoker));
System.out.println("************** 两副牌(包括大小王)洗牌后的结果 (end)******************");
System.out.println();
includeJoker = false;
System.out.println("************** 两副牌(不包括大小王)洗牌后的结果 (start)******************");
printCards(CardsUtil.retrieveShuffledCards(number, includeJoker));
System.out.println("************** 两副牌(不包括大小王)洗牌后的结果 (end)******************");
System.out.println();

}

private static void printCards(List<Card> list) {
for (Card card : list) {
System.out.print(card.getCardType().getCardTypeDescription());
System.out.print(" ");
System.out.println(card.getPoints());
}
}

}


几个测试的结果如下:

************** 一副牌(包括大小王)洗牌后的结果 (start)******************
方块 12
梅花 9
红桃 1
梅花 1
红桃 6
黑桃 8
红桃 4
黑桃 6
方块 3
方块 1
黑桃 3
红桃 2
红桃 13
方块 8
梅花 3
红桃 7
方块 2
梅花 2
方块 11
梅花 4
方块 13
方块 7
梅花 11
红桃 8
红桃 5
方块 9
方块 10
红桃 3
方块 4
梅花 8
黑桃 4
黑桃 10
黑桃 9
梅花 6
黑桃 7
黑桃 2
方块 5
黑桃 11
红桃 12
红桃 11
大王 0
梅花 5
梅花 13
黑桃 13
梅花 7
梅花 10
梅花 12
红桃 9
黑桃 5
黑桃 1
红桃 10
方块 6
小王 0
黑桃 12
************** 一副牌(包括大小王)洗牌后的结果 (end)******************

************** 一副牌(不包括大小王)洗牌后的结果 (start)******************
方块 3
方块 4
红桃 1
红桃 6
方块 5
方块 7
方块 1
黑桃 3
方块 2
梅花 3
红桃 12
梅花 12
方块 12
黑桃 4
方块 11
黑桃 12
黑桃 8
红桃 8
梅花 7
红桃 10
方块 6
梅花 2
黑桃 6
红桃 11
黑桃 7
黑桃 2
梅花 1
梅花 13
红桃 9
梅花 5
黑桃 5
方块 9
方块 13
黑桃 11
方块 8
梅花 9
梅花 6
梅花 4
梅花 8
黑桃 1
红桃 13
黑桃 10
红桃 3
红桃 2
红桃 5
红桃 4
红桃 7
方块 10
黑桃 13
梅花 11
黑桃 9
梅花 10
************** 一副牌(不包括大小王)洗牌后的结果 (end)******************

************** 两副牌(包括大小王)洗牌后的结果 (start)******************
方块 5
梅花 6
梅花 12
红桃 6
方块 4
红桃 11
黑桃 8
梅花 6
梅花 5
红桃 6
红桃 7
红桃 2
梅花 11
梅花 4
梅花 10
梅花 1
黑桃 8
小王 0
方块 7
黑桃 9
红桃 4
方块 1
红桃 8
黑桃 10
红桃 1
梅花 7
梅花 13
方块 10
方块 10
红桃 3
方块 11
大王 0
方块 13
方块 6
方块 3
黑桃 3
方块 1
黑桃 7
方块 4
方块 2
黑桃 6
红桃 4
方块 9
红桃 13
梅花 10
方块 13
黑桃 10
黑桃 4
方块 7
大王 0
红桃 10
方块 8
梅花 9
梅花 2
方块 12
红桃 12
方块 6
黑桃 7
红桃 5
方块 12
黑桃 11
红桃 2
黑桃 3
黑桃 4
红桃 10
梅花 8
黑桃 6
小王 0
黑桃 12
黑桃 13
红桃 5
红桃 13
梅花 3
方块 5
方块 2
方块 3
黑桃 13
红桃 7
梅花 4
黑桃 2
梅花 3
方块 9
黑桃 1
梅花 13
黑桃 11
红桃 9
梅花 11
方块 8
梅花 7
梅花 5
方块 11
红桃 12
梅花 2
黑桃 2
梅花 1
黑桃 5
红桃 3
黑桃 5
红桃 11
黑桃 12
红桃 1
黑桃 1
梅花 8
黑桃 9
梅花 9
梅花 12
红桃 8
红桃 9
************** 两副牌(包括大小王)洗牌后的结果 (end)******************

************** 两副牌(不包括大小王)洗牌后的结果 (start)******************
梅花 10
红桃 6
梅花 13
红桃 12
方块 6
红桃 10
红桃 3
梅花 7
方块 13
红桃 9
黑桃 13
梅花 1
黑桃 3
黑桃 5
方块 12
梅花 12
红桃 12
梅花 6
方块 10
黑桃 1
红桃 8
黑桃 10
红桃 11
梅花 5
红桃 8
梅花 3
红桃 1
梅花 2
红桃 13
方块 8
梅花 4
梅花 12
方块 5
黑桃 4
梅花 5
红桃 7
红桃 3
黑桃 4
梅花 9
梅花 10
方块 12
黑桃 5
方块 9
梅花 6
梅花 3
黑桃 11
方块 8
红桃 2
方块 10
方块 1
梅花 11
黑桃 7
黑桃 8
红桃 4
方块 5
黑桃 12
梅花 2
黑桃 8
方块 2
红桃 5
红桃 13
方块 11
梅花 8
黑桃 3
红桃 7
黑桃 9
方块 2
黑桃 10
梅花 8
方块 9
梅花 11
红桃 6
黑桃 12
方块 13
红桃 2
方块 7
梅花 7
方块 7
黑桃 11
红桃 1
黑桃 2
黑桃 7
方块 11
梅花 9
黑桃 1
方块 3
黑桃 2
梅花 13
红桃 9
方块 4
方块 1
黑桃 13
红桃 11
梅花 4
红桃 4
方块 4
梅花 1
方块 3
黑桃 6
黑桃 9
红桃 5
红桃 10
黑桃 6
方块 6
************** 两副牌(不包括大小王)洗牌后的结果 (end)******************
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值