首先定义一张牌类,其中包含数值(A、2、3、4、5、6、7、8、9、10、J、Q、K)和花色(♦、♣、♥、♠)两种私有属性。为了方便结果打印,这里选择重写toString()方法。formart表示格式化(关于toString()方法的相关操作详情请见:http://t.csdn.cn/nqoeh)
// 表示一张牌
public class Card {
private final int rank; // 值是 1 到 13,代表 A -> K
private final String suit; // 花色 ♥、♣、♦、♠
public Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
// 重写其 toString 方法
@Override
public String toString() {
// String.format 返回一个 格式化(format)后的字符串(String)
// 格式化字符串的使用和 System.out.printf 的方式一样
return String.format("扑克[%s %s]", this.suit, rankStr());
}
private String rankStr() {
if (rank == 1) {
return "A";
} else if (rank >= 2 && rank <= 10) {
return String.valueOf(rank);
} else if (rank == 11) {
return "J";
} else if (rank == 12) {
return "Q";
} else {
return "K";
}
}
//检验代码正确与否,可以删去
public static void main(String[] args) {
Card card = new Card("♥", 11);
System.out.println(card); // card.toString()
}
}
运用ArrayList定义一副牌,其中元素是一张牌即Card类:List<Card> 一副牌 = new ArrayList<>();而这个顺序表内目前是空的需要我们利用for循环的方式添加不同花色不同数值的52 张牌。
对于洗牌操作可以使用Java编译器中自带的shuffle()方法。
进行发牌的操作,要求最后每名玩家 5 张牌,所以一共需要发 5 轮牌,每次使用add()方法给每位玩家添加牌,并使用remove()方法移除一副牌中已经被派发的牌。最后可以使用addAll()方法回收所有牌,并使用clear()方法清空玩家手中的牌。
编译器中shuffle()源码是,感兴趣的可以自行了解,这里不做详情讲解。
public static void shuffle(List<?> list) {
Random rnd = r;
if (rnd == null)
r = rnd = new Random(); // harmless race.
shuffle(list, rnd);
}
private static Random r;
/**
* Randomly permute the specified list using the specified source of
* randomness. All permutations occur with equal likelihood
* assuming that the source of randomness is fair.<p>
*
* This implementation traverses the list backwards, from the last element
* up to the second, repeatedly swapping a randomly selected element into
* the "current position". Elements are randomly selected from the
* portion of the list that runs from the first element to the current
* position, inclusive.<p>
*
* This method runs in linear time. If the specified list does not
* implement the {@link RandomAccess} interface and is large, this
* implementation dumps the specified list into an array before shuffling
* it, and dumps the shuffled array back into the list. This avoids the
* quadratic behavior that would result from shuffling a "sequential
* access" list in place.
*
* @param list the list to be shuffled.
* @param rnd the source of randomness to use to shuffle the list.
* @throws UnsupportedOperationException if the specified list or its
* list-iterator does not support the <tt>set</tt> operation.
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static void shuffle(List<?> list, Random rnd) {
int size = list.size();
if (size < SHUFFLE_THRESHOLD || list instanceof RandomAccess) {
for (int i=size; i>1; i--)
swap(list, i-1, rnd.nextInt(i));
} else {
Object arr[] = list.toArray();
// Shuffle array
for (int i=size; i>1; i--)
swap(arr, i-1, rnd.nextInt(i));
// Dump array back into list
// instead of using a raw type here, it's possible to capture
// the wildcard but it will require a call to a supplementary
// private method
ListIterator it = list.listIterator();
for (int i=0; i<arr.length; i++) {
it.next();
it.set(arr[i]);
}
}
}
洗牌、发牌、收牌操作 :
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 定义一副牌,元素是 Card 对象
List<Card> 一副牌 = new ArrayList<>();
// 这副牌现在的空的(empty)
// 初始化这副牌,一共 52 张
String[] 所有的花色 = { "♥", "♠", "♦", "♣" };
// 遍历所有的花色
for (String suit : 所有的花色) { // 循环 4 次
// 遍历 A -> K
for (int rank = 1; rank <= 13; rank++) { // 循环 13 次
// 定义一张牌
Card card = new Card(suit, rank); // 执行 4 * 13 = 52 次
// 把牌添加到 这副牌中
一副牌.add(card);
}
}
// 打印
System.out.println(一副牌); // 一副牌.toString()
// 进行洗牌(shuffle)操作,直接使用官方定义的方法
// Collections 和 Collection
// 类似
// Arrays 和 Array 的关系
// Collections 提供了很多方便操作 Collection 的工具方法(静态的)
// Arrays 提供了很多方便操作 数组(Array)的工具方法(静态的)
Collections.shuffle(一副牌);
// 打印,洗牌后
System.out.println(一副牌); // 一副牌.toString() 牌堆
// 进行发牌的操作
// 定义四名玩家,类型都是 List<Card>
List<Card> playerA = new ArrayList<>(); // 空(empty)的
List<Card> playerB = new ArrayList<>(); // 空(empty)的
List<Card> playerC = new ArrayList<>(); // 空(empty)的
List<Card> playerD = new ArrayList<>(); // 空(empty)的
System.out.println("发牌后,牌堆的牌数:" + 一副牌.size());
// 进行发牌的操作,要求最后每名玩家 5 张牌,所以,一共需要发 5 轮牌
for (int i = 0; i < 5; i++) {
// 按照 A -> B -> C -> D 的顺序发牌
// 发牌:从 牌堆顶部(可以是 顺序表的 头部,也可以是顺序表的尾部,只要保持全程保持一致即可)
// 我们这里规定,顺序表的头部就是牌堆顶部(实际上尾部更好,自己思考为什么)
// 从 顺序表头部取出一张牌 -> 顺序表的头删操作
Card card = 一副牌.remove(0); // 删除 [0] 下标的牌,就是头删
// 发给对应的玩家 A
playerA.add(card); // 这里头插、尾插都可以
// 发牌给 B
card = 一副牌.remove(0);
playerB.add(card);
// C
card = 一副牌.remove(0);
playerC.add(card);
// D
card = 一副牌.remove(0);
playerD.add(card);
}
System.out.println("发牌前,牌堆的牌数:" + 一副牌.size());
// 分别打印每个人手中的牌
System.out.println(playerA);
System.out.println(playerB);
System.out.println(playerC);
System.out.println(playerD);
// 大家下来可以自行扩展
//在一切结束后,把每名玩家手中的牌拿回牌堆,然后重新洗牌
//使用addAll方法
一副牌.addAll(playerA);
playerA.clear();
一副牌.addAll(playerA);
playerB.clear();
一副牌.addAll(playerA);
playerC.clear();
一副牌.addAll(playerA);
playerD.clear();
Collections.shuffle(一副牌);
System.out.println(playerA);
System.out.println(playerB);
System.out.println(playerC);
System.out.println(playerD);
System.out.println(一副牌);
}
}