前些天我實現了發紅包案例:Java實現微信、QQ等羣主發紅包實例(普通紅包)
今天繼續來實現生活中一些有趣的案例:鬥地主
分析:
首先,我們來梳理一下規則:
- 準備牌階段:鬥地主一般用一副牌,有54張,其中有大王小王各1張,其他52張牌,分別是4個花色,每種花色13張。四種花色分別爲♥ ♦ ♠ ♣,定義一個集合來存儲它們;而每一種花色中的13張牌爲:(由大到小)2 A K Q J 10 9 8 7 6 5 4 3,也定義一個集合來存儲它們。遍歷這兩個集合,可以組裝成爲52張牌,例如♣7 ♥A
- 洗牌階段:使用集合工具類Collections方法,其中static void shuffle(List<?> list)使用指定的隨機數對指定列表進行置換,會隨機的打亂集合中的元素的順序
- 發牌階段:要求每一位玩家擁有17張牌,剩餘三張作爲底牌,一人一張輪流發牌:集合的索引(0-53)%3,定義4個集合,來存儲3個玩家的牌和場上的底牌。索引%3,有三個值(0,1,2),0%3=0,1%3=1,2%3=2,3%3=0,當索引>=51時,改爲發底牌
- 看牌階段:直接打印集合,遍歷存儲玩家和底牌的集合
實現:
public class Poker {
public static void main(String[] args) {
// 創建牌盒集合來存儲牌面
ArrayList<String> pokerBox = new ArrayList<String>();
// 創建花色集合
ArrayList<String> colors = new ArrayList<String>();
// 創建數字集合
ArrayList<String> numbers = new ArrayList<String>();
// 給花色集合加入花色
colors.add("♥");
colors.add("♦");
colors.add("♠");
colors.add("♣");
// 由小到大加入牌的點數
for(int i = 2;i <= 10;i++){
numbers.add(i+"");
}
numbers.add("J");
numbers.add("Q");
numbers.add("K");
numbers.add("A");
// 拿出每一個花色然後跟每一個點數進行結合,然後存儲到牌盒中
for (String color : colors) {
// color每一個花色
// 遍歷數字集合
for(String number : numbers){
// 結合
String card = color+number;
// 存儲到牌盒中
pokerBox.add(card);
}
}
// 添加大王小王
pokerBox.add("小王");
pokerBox.add("大王");
// 洗牌將牌盒中牌的索引打亂
Collections.shuffle(pokerBox);
// 創建三個玩家集合,創建一個底牌集合
ArrayList<String> player1 = new ArrayList<String>();
ArrayList<String> player2 = new ArrayList<String>();
ArrayList<String> player3 = new ArrayList<String>();
ArrayList<String> dipai = new ArrayList<String>();
// 遍歷牌盒
for(int i = 0;i < pokerBox.size();i++){
// 獲取牌面
String card = pokerBox.get(i);
// 分別按照索引存儲分配牌
if(i>=51){
dipai.add(card);
} else if(i%3==0){
player1.add(card);
}else if(i%3==1){
player2.add(card);
}else{
player3.add(card);
}
}
// 輸出結果
System.out.println("玩家1:"+player1);
System.out.println("玩家2:"+player2);
System.out.println("玩家3:"+player3);
System.out.println("底牌:"+dipai);
}
}
結果展示:
改進方案:
鬥地主的玩家的牌並不是按照順序來排列的,看牌的時候十分難受。
將存牌的時候加入Map集合,形成鍵值對,使得牌的索引和組裝好的牌形成配對,從牌的大小來存放,然後使用Collections中的方法soft(List)來打亂索引順序,最後發牌,看牌使用查表方法,遍歷玩家和底牌集合,獲取到Map集合的key,通過key找到value值。
實現:
public class Doudizhu{
public static void main(String[] args) {
// 創建一個Map集合,存儲牌的索引和組裝好的牌
HashMap<Integer,String> poker = new HashMap<>();
// 創建一個list集合,存儲牌的索引
ArrayList<Integer> pokerIndex = new ArrayList<>();
// 定義兩個集合,存儲牌的花色和序號
List<String> colors = List.of("♠","♣","♦","♥");
List<String> numbers = List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");
// 把大王小王存到集合中
int index = 0;
poker.put(index,"大王");
pokerIndex.add(index);
index++;
poker.put(index,"小王");
pokerIndex.add(index);
index++;
// 循環嵌套兩個集合,組裝這52張牌,存儲到集合中去
for (String number : numbers){
for (String color : colors){
poker.put(index,color+number);
pokerIndex.add(index);
index++;
}
}
// 輸出查看結果
System.out.println(poker);
System.out.println(pokerIndex);
// 洗牌階段
Collections.shuffle(pokerIndex);
// 發牌階段
ArrayList<Integer> player01 = new ArrayList<>();
ArrayList<Integer> player02 = new ArrayList<>();
ArrayList<Integer> player03 = new ArrayList<>();
ArrayList<Integer> dipai = new ArrayList<>();
// 遍歷存儲牌索引的list集合,獲取每一個牌的索引
for (int i = 0; i < pokerIndex.size(); i++) {
Integer in = pokerIndex.get(i);
// 先判斷底牌
if(i >= 51){
dipai.add(in);
}else if(i % 3 == 0){
player01.add(in);
}else if(i % 3 == 1){
player02.add(in);
}else if(i % 3 == 2){
player03.add(in);
}
}
// 排序:使用Collections中的方法sort(List)
Collections.sort(player01);
Collections.sort(player02);
Collections.sort(player03);
Collections.sort(dipai);
// 調用看牌的方法
lookPoker("玩家1" , poker , player01);
lookPoker("玩家2" , poker , player02);
lookPoker("玩家3" , poker , player03);
lookPoker("底牌" , poker , dipai);
}
public static void lookPoker(String name,HashMap<Integer,String> poker,ArrayList<Integer> list){
// 輸出玩家的名稱
System.out.print(name + ": ");
// 遍歷玩家或底牌集合,獲取牌的索引
for(Integer key : list){
// 使用牌的索引,去Map集合中,找到對應的牌
String value = poker.get(key);
System.out.print(value + " ");
}
System.out.println();
}
}
結果展示:
兩次打印輸出的內容不一樣,但結果都能按照從大到小的順序輸出,使查看效果和現實中的鬥地主一樣!
感謝您的閱讀,不足之處歡迎指正!