按照鬥地主的規則,完成洗牌發牌的動作。
具體規則
- 組裝54張撲克牌將
- 54張牌順序打亂
- 三個玩家參與遊戲,三人交替摸牌,每人17張牌,最後三張留作底牌。
- 查看三人各自手中的牌(按照牌的大小排序)、底牌
規則:手中撲克牌從大到小的擺放順序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3
需求分析
- 準備牌:
完成數字與紙牌的映射關係:
使用雙列Map(HashMap)集合,完成一個數字與字符串紙牌的對應關係(相當於一個字典)。
- 洗牌:
通過數字完成洗牌發牌
- 發牌:
將每個人以及底牌設計爲ArrayList,將最後3張牌直接存放於底牌,剩餘牌通過對3取模依次發牌。
存放的過程中要求數字大小與鬥地主規則的大小對應。
將代表不同紙牌的數字分配給不同的玩家與底牌。
- 看牌:
通過Map集合找到對應字符展示。
通過查詢紙牌與數字的對應關係,由數字轉成紙牌字符串再進行展示。
普通版:手牌無序
package cn.luis;
import java.util.*;
/**
* @ClassName Dou
* @Description TODO 鬥地主綜合案例:準備牌、洗牌、看牌
* @Author L
* @Date 2020.06.13 10:01
* @Version 1.0
* @Remark :初級版本,牌的順序混亂
**/
public class Dou {
public static void main(String[] args) {
// 準備好的牌:poker
ArrayList<String> poker = readyPai();
// 洗好的牌:poker
ArrayList<String> poker2 = xiPai(poker);
// 發牌
Map<String, ArrayList<String>> map = faPai(poker2);
// 看牌
showPai(map);
}
/**
* 準備牌
*/
public static ArrayList<String> readyPai(){
ArrayList<String> poker = new ArrayList<>();
// 定義兩個數組,存儲牌的花色和牌的序號
String[] colors = {"♠","♥","♣","♦"};
String[] nums = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
// 先把大王和小王存儲到撲克牌集合中
poker.add("大王");
poker.add("小王");
// 循環嵌套遍歷兩個數組,組裝52張撲克牌
for (String color : colors) { // colors.for 先循環顏色的運行快
for (String num : nums) {
// 把組裝好的牌存儲到poker集合中
poker.add(color + num);
}
}
// 查看組裝是否成功
// System.out.println(poker);
return poker;
}
/**
* 洗牌
* @param poker
*/
public static ArrayList<String> xiPai(ArrayList<String> poker){
// 使用Collections工具類的方法將集合元素順序打亂
Collections.shuffle(poker);
return poker;
}
/**
* 發牌
* @param poker
* @return
*/
public static Map<String,ArrayList<String>> faPai(ArrayList<String> poker){
// 定義四個集合,存儲玩家的牌和底牌
ArrayList<String> player01 = new ArrayList<>();
ArrayList<String> player02 = new ArrayList<>();
ArrayList<String> player03 = new ArrayList<>();
ArrayList<String> diPai = new ArrayList<>();
// 用來存儲上面四個集合
Map<String,ArrayList<String>> map = new LinkedHashMap<>();
/*
遍歷poker集合,獲取每一張牌
爲三位玩家輪流發牌:使用poker集合的 (索引 % 3)
剩餘三張給底牌
注意:
先判斷底牌:索引 >= 51,否則就發沒了
*/
for (int i = 0; i < poker.size(); i++) {
// 獲取每一張牌
String p = poker.get(i);
// 輪流發牌
if (i >= 51) {
// 給底牌發牌
diPai.add(p);
} else if (i % 3 == 0) {
// 給玩家一發牌
player01.add(p);
} else if (i % 3 == 1) {
// 給玩家一發牌
player02.add(p);
} else if (i % 3 == 2) {
// 給玩家一發牌
player03.add(p);
}
}
// 將存儲牌的集合裝入map集合
map.put("player01",player02);
map.put("player02",player02);
map.put("player03",player03);
map.put("diPai",diPai);
return map;
}
/**
* 看牌
* @param map
*/
public static void showPai(Map<String,ArrayList<String>> map){
Set<String> set = map.keySet();
// 遍歷鍵找值方式
System.out.println("======迭代器======");
Iterator<String> it = set.iterator();
while (it.hasNext()){
String key = it.next();
ArrayList<String> list = map.get(key);
System.out.println(key+":"+list);
}
System.out.println("======增強for======");
for (String key : set) {
ArrayList<String> list = map.get(key);
System.out.println(key+":"+list);
}
System.out.println("======增強for======");
for (String key : map.keySet()) {
ArrayList<String> list = map.get(key);
System.out.println(key+":"+list);
}
// 遍歷鍵值對方式
Set<Map.Entry<String, ArrayList<String>>> set2 = map.entrySet();
System.out.println("======迭代器======");
Iterator<Map.Entry<String, ArrayList<String>>> it2 = set2.iterator();
while (it2.hasNext()){
Map.Entry<String, ArrayList<String>> entry = it2.next();
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
System.out.println(key+ "=" +value);
}
System.out.println("======增強for======");
for (Map.Entry<String, ArrayList<String>> entry : set2) {
String key = entry.getKey();
ArrayList<String> value = entry.getValue();
System.out.println(key+ "=" +value);
}
}
}
結果:
player01:[♥10, ♣4, ♠6, ♥K, ♣J, ♠K, ♥Q, ♠Q, ♦Q, ♠8, ♦2, ♦J, ♠3, ♥7, ♠9, 大王, ♠J]
player02:[♥10, ♣4, ♠6, ♥K, ♣J, ♠K, ♥Q, ♠Q, ♦Q, ♠8, ♦2, ♦J, ♠3, ♥7, ♠9, 大王, ♠J]
player03:[♣9, ♦5, ♣3, ♦A, ♣10, ♠2, ♣8, ♣A, ♠A, ♥A, ♣5, ♥6, ♥2, ♣2, ♠7, 小王, ♥8]
diPai:[♦10, ♣7, ♥5]
進階版:手牌有序,結構優化
package cn.luis;
import java.util.*;
/**
* @ClassName DouPro
* @Description TODO 鬥地主綜合案例:準備牌、洗牌、看牌
* @Author L
* @Date 2020.06.13 10:01
* @Version 2.0
* @Remark :高級版,對牌的順序進行完善
**/
public class DouPro {
public static void main(String[] args) {
Map<String, ArrayList<Integer>> pai = faPai("鋼鐵俠", "蜘蛛俠", "小飛俠", xiPai());
showPai(pai, readyPai());
}
/**
* 準備牌
*/
public static Map<Integer, String> readyPai() {
// 創建牌的花色和數字集合
List<String> colors = List.of("♠", "♥", "♣", "♦");
List<String> nums = List.of("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
// 存儲牌的集合
Map<Integer, String> poker = new HashMap<>();
// 組裝牌
poker.put(0, "大王");
poker.put(1, "小王");
int index = 2;
for (String num : nums) { // 比color在前循環更浪費時間
for (String color : colors) {
String s = color + num;
poker.put(index, s);
index++;
}
}
// System.out.println(poker);
return poker;
}
/**
* 洗牌
* 創建集合:存取牌的序號,方便發牌調用
*
* @return
*/
public static ArrayList<Integer> xiPai() {
// 存取牌的序號(和map集合的key相同)
ArrayList<Integer> pid = new ArrayList<>();
for (int i = 0; i < 54; i++) {
pid.add(i);
}
Collections.shuffle(pid);
//System.out.println(pid);
return pid;
}
/**
* 發牌
*
* @param name1
* @param name2
* @param name3
* @param list
* @return
*/
public static Map<String, ArrayList<Integer>> faPai(String name1, String name2, String name3, ArrayList<Integer> list) {
// 定義四個集合,存儲撲克牌集合的key
ArrayList<Integer> player01 = new ArrayList<>();
ArrayList<Integer> player02 = new ArrayList<>();
ArrayList<Integer> player03 = new ArrayList<>();
ArrayList<Integer> diPai = new ArrayList<>();
// 分發牌
// 遍歷list,用map.get方法獲取value
for (int i = 0; i < list.size(); i++) {
Integer id = list.get(i);
// 先判斷底牌
if (i >= 51) {
diPai.add(id);
} else if (i % 3 == 0) {
player01.add(id);
} else if (i % 3 == 1) {
player02.add(id);
} else if (i % 3 == 2) {
player03.add(id);
}
}
Map<String, ArrayList<Integer>> map = new LinkedHashMap<>();
map.put(name1, player01);
map.put(name2, player02);
map.put(name3, player03);
map.put("底牌", diPai);
return map;
}
/**
* 看牌
*
* @param p :發牌方法傳遞過來的
* @param poker :準備牌方法傳遞過來的
*/
public static void showPai(Map<String, ArrayList<Integer>> p, Map<Integer, String> poker) {
Set<String> set = p.keySet();
// 遍歷發牌集合
for (String name : set) {
System.out.print(name + ": ");
ArrayList<Integer> list = p.get(name);
// 排序(發牌集合中的ArrayList集合)
Collections.sort(list);
// 根據list集合的元素遍歷map集合中的value
for (int index = 0; index < list.size(); index++) {
Integer value = list.get(index);
String pai = poker.get(value);
System.out.print(pai + " ");
}
System.out.println();
}
}
}
結果:
鋼鐵俠: 小王 ♥2 ♦2 ♥A ♦A ♣K ♠Q ♥Q ♦Q ♥J ♥9 ♣9 ♠8 ♠7 ♦7 ♠6 ♠4
蜘蛛俠: 大王 ♠2 ♥K ♠J ♦J ♣10 ♣8 ♦8 ♣6 ♠5 ♣5 ♦5 ♣4 ♦4 ♠3 ♣3 ♦3
小飛俠: ♣2 ♠A ♣A ♠K ♦K ♣J ♠10 ♥10 ♦10 ♠9 ♦9 ♥8 ♥6 ♦6 ♥5 ♥4 ♥3
底牌: ♣Q ♥7 ♣7