一、代码
package javaSeTasks07;
/**
作业:模拟斗地主洗牌发牌
(一)案例介绍:
按照斗地主的规则,完成洗牌发牌的动作。
具体规则:
1.组装54张扑克牌
2.将54张扑克牌的顺序打乱
3.三个玩家参与游戏,三人交替摸牌,没人17张牌,最后三张留作底牌。
4.查看三人各自手中的牌(按照牌的大小排序)、底牌
手中扑克牌从大到小的摆放顺序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3
(二)案例需求分析
1.准备牌
完成数字与牌的映射关系
使用双列Map(HashMap)集合,完成一个数字与字符串字牌的对应关系(相当于一个字典)。
2.洗牌
通过数字完成洗牌发牌
3.发牌
将每个人以及底牌设计为ArrayList,将最后3张牌直接存放于底牌,剩余牌通过对3取模依次发牌。
存放的过程中要求数字大小与斗地主规则的大小对应。
将代表不同字牌的数字分配给不同的玩家与底牌。
4.看牌
通过Map集合找打对应字符展示。
通过查询字牌与数字的对应关系,由数字转成纸牌字符串再进行展示。
*/
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public class Landlords {
public static void main(String[] args) {
// 准备牌
HashMap<Integer,String> pokerCards = getPokerCards();
// 洗牌
List<Integer> pokerCardsKeysList = shufflePokerCards(pokerCards);
// 发牌
ArrayList<ArrayList<Integer>> playerKeyList = dealPokerCards(pokerCardsKeysList);
// 看牌
showCards(playerKeyList,pokerCards);
}
// 准备牌:生成一幅扑克牌,返回一组包含数字与牌的映射关系的HashMap<Integer,String>Map对象
public static HashMap<Integer,String> getPokerCards() {
// 生成包含数字与牌的映射关系的HashMap<Integer,String> pokerCards,其中键为:1-54,键值分别代表54张扑克牌
HashMap<Integer,String> pokerCards = new HashMap<Integer,String>();
// 数字1的键映射扑克牌中的大王
pokerCards.put(1, "大王");
// 数字2的键映射扑克牌中的大王
pokerCards.put(2, "小王");
// 由suitKinds和 cardKinds来生成扑克牌除"大王"、"小王"外的其它全部牌
// suitKinds代表扑克牌中的四种花色:红桃、黑桃、梅花、方角
String suitKinds[] = {"♠","♥","♣","♦"};
// cardKinds代表扑克牌中除"大王"、"小王"外的其它牌面类型
String cardKinds[] = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
// 数字3-53的键分别映射扑克牌中除"大王"、"小王"外的其它52张(4*13)牌。键越小,牌越大,比如1键代表的“大王”为最大牌,54键代表“♦3”为最小牌
int i = 3;
for(int j = 0,len1 = cardKinds.length ; j<len1 ; j++) {
for(int k = 0,len2 = suitKinds.length ; k<len2 ; k++) {
// 往pokerCards中添加其它52个“数字与牌”的映射关系:键从3开始,键值由“花色和牌面”组成。
pokerCards.put(i++,suitKinds[k]+cardKinds[j]);
}
}
return pokerCards;
}
// 洗牌:返回洗牌后的包含pokerCards中的所有key值的List<Integer>类型的集合对象
public static List<Integer> shufflePokerCards(HashMap<Integer,String> pokerCards) {
// 获取pokerCards中的所有key值生成List<Integer>类型的pokerCardsKeysList,pokerCardsKeysList是洗牌的操作对象,以下几个用到的方法作用分别说明如下:
// pokerCards.keySet() :返回pokerCards中包含其所有key的 Set<Integer>集合
// new Integer[pokerCards.keySet().size()] :创建一个大小跟上面的Set<Integer>集合一样的整型数组
// pokerCards.keySet().toArray :将Set<Integer>集合转换成Integer[]数组
// public static <T> List<T> asList(T... a) :该方法返回一个受指定数组支持的固定大小的列表List<Integer>,参数为上面的Integer[]数组
List<Integer> pokerCardsKeysList = Arrays.asList(pokerCards.keySet().toArray(new Integer[pokerCards.keySet().size()]));
// 将获取到的包含pokerCards中所有键的sortList进行随机排列,即模拟斗地主的“洗牌”
Collections.shuffle(pokerCardsKeysList);
return pokerCardsKeysList;
}
// 发牌:生成底牌并分别给三位玩家发牌,返回一个包含底牌和三个玩家牌的ArrayList<ArrayList<Integer>>集合对象
public static ArrayList<ArrayList<Integer>> dealPokerCards(List<Integer> pokerCardsKeysList) {
// bottomCard:存放3张“底牌”的键
ArrayList<Integer> bottomCard = new ArrayList<Integer>();
// 将最后3张牌直接存放于底牌
bottomCard.add(pokerCardsKeysList.get(pokerCardsKeysList.size()-1));
bottomCard.add(pokerCardsKeysList.get(pokerCardsKeysList.size()-2));
bottomCard.add(pokerCardsKeysList.get(pokerCardsKeysList.size()-3));
// 创建playerKey1:用于存放“玩家1”所有牌的键
ArrayList<Integer> playerKey1 = new ArrayList<Integer>();
// 创建playerKey2:用于存放“玩家2”所有牌的键
ArrayList<Integer> playerKey2 = new ArrayList<Integer>();
// 创建playerKey3:用于存放“玩家3”所有牌的键
ArrayList<Integer> playerKey3 = new ArrayList<Integer>();
// 剩余牌通过对3取模依次发给玩家1、玩家2和玩家3
for(int i = 0,len = pokerCardsKeysList.size()-3 ; i < len ; i++) {
if(i % 3 == 0)
playerKey1.add(pokerCardsKeysList.get(i));
else if(i % 3 == 1)
playerKey2.add(pokerCardsKeysList.get(i));
else
playerKey3.add(pokerCardsKeysList.get(i));
}
// 调用Collections.sort(List<T> list)方法实现按照“数字大小与斗地主规则的大小”要求对玩家手中牌进行排序
Collections.sort(playerKey1);
Collections.sort(playerKey2);
Collections.sort(playerKey3);
Collections.sort(bottomCard);
// 创建存放底牌集合和三个玩家牌集合的集合
ArrayList<ArrayList<Integer>> playerKeyList = new ArrayList<ArrayList<Integer>>();
playerKeyList.add(playerKey1);
playerKeyList.add(playerKey2);
playerKeyList.add(playerKey3);
playerKeyList.add(bottomCard);
return playerKeyList;
}
// 看牌:分别在控制台打印"玩家1","玩家2","玩家3"的牌和"底牌"
public static void showCards(ArrayList<ArrayList<Integer>> playerKeyList,HashMap<Integer,String> pokerCards) {
// 定义持牌者
String[] playerKindName = {"玩家1","玩家2","玩家3","底牌"};
// playerKindNameIndex:用于访问上面数组获得持牌者名称
int playerKindNameIndex = 0;
// cardShow:用于存放从pokerCards中根据playerKey键获取到的扑克牌键值
ArrayList<String> cardShow = new ArrayList<String>();
// 先遍历playerKeyList集合获取pokerKey集合
for(ArrayList<Integer> playerKey : playerKeyList) {
// 再遍历pokerKey集合获取pokerKey键值
for(Integer pokerKey : playerKey) {
// 根据pokerKey键值获取扑克牌键值并添加到cardShow
cardShow.add(pokerCards.get(pokerKey));
}
// 逐一打印持牌者的牌
System.out.println(playerKindName[playerKindNameIndex++] + "\t" + cardShow);
// 每次打印完就清空当前已打印的cardShow,以存放下个持牌者的牌
cardShow.clear();
}
}
}
二、运行结果: