前些天我实现了发红包案例:Java实现微信、QQ等群主发红包实例(普通红包)
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();
}
}
结果展示:
两次打印输出的内容不一样,但结果都能按照从大到小的顺序输出,使查看效果和现实中的斗地主一样!
感谢您的阅读,不足之处欢迎指正!
|