按照斗地主的规则,完成洗牌发牌的动作。
具体规则
- 组装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