引言:
学习java这么久了,总归是要拿出一点有趣的东西哈,今天就给大家带来一个学集合当中有趣的一个,且知识点设计比较综合的一个例子,斗地主,当然基于目前的水平我们只解决一个发牌,看牌的简单操作,至于玩以后再说。
目录
一、题目要求
众所周知,我们的扑克有四种花色,搭配点数进行组合,最终得到了54张扑克,那么要想实现发牌看牌的看似简单的功能, 我们需要用到哪些知识点呢?其实无非就是集合的一些排序的特性和功能。那么接下来就随我一起去了解一下这道题把!
二、实现步骤
1:创建HashMap,键是编号,值是牌
2:创建ArrayList,存储编号
3:创建花色数组和点数数组
4:从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号
5:洗牌(洗的是编号),用Collections的shuffle()方法实现
6:发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)
7:定义方法看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
8:调用看牌方法
因为HashMap集合是键值对一对一的关系,而且不重复,那么我们就可以利用其存储我们的54张扑克,以及他的编号,编号我们还需要另存一份在List集合里面,方便我们去洗牌和发牌。
有了上面两步之后,我们应该把扑克变成我们自己能看懂的对吧,那么就用数组来组合拼接扑克的花色和点数,并且存储到Map集合当中,并将每一张牌存进去的同时,定义一个自增变量index来完成计数,将得到的数存储进List集合当中,我们后面的发牌看牌其实就是对List集合进行操作。示例代码如下:
// 1:创建HashMap,键是编号,值是牌
HashMap<Integer, String> hm = new HashMap<Integer, String>();
//2:创建ArrayList,存储编号
ArrayList<Integer> array = new ArrayList<Integer>();
//3:创建花色数组和点数数组
String[] colors = {"♣", "♦", "♠", "♥"};
String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//4:从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号
int index = 0;
//这个地方让数字numbers在前面是为了能够进行点数的排序,不可更改
for (String number : numbers) {
for (String color : colors) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
存储完扑克之后,因为我们List集合是存取有序的,就是你放进去的顺序是没有被打乱的,那在我们万扑克的时候,如果没有洗牌,那这牌打的就没有意思了对吧,因此我们要在发牌和看牌之前进行洗牌的动作:
//5:洗牌(洗的是编号),用Collections的shuffle()方法实现
Collections.shuffle(array);
这个地方用的是Collections这个帮助类中的shuffle()方法实现的,jdk自带,因此可以直接用它让我们的集合中的元素的顺序被打乱。
洗完牌我们就应该进行发牌动作,给每个玩家手里发牌,这里我们是用的是TreeSet集合去接收玩家手中的牌,并且其排序是按照List集合中所存的编号的顺序进行排序,那么这会大家应该要知道我们玩家手中拿到的牌其实还是数字,
其次就是我们发牌,怎么保障我们每个玩家拿到手上的牌都是规则之中的呢?很显然,我们三个玩家没人手上应该有17张牌,底牌有三张,至于谁当了地主拿了底牌我们目前不管,针对这个我们可以写一个循环,让我们的每个值都到达每个玩家手中,只需要对每个i作对3取余即可写出三个判断条件,让我们的i对应的添加的每个玩家手中,底牌自然就是最后三张牌,我们可以一开始,就将最后三张牌给底牌,代码如下:
//:发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)
//这里的集合代表的是三个玩家和底牌,玩家名称自定
TreeSet<Integer> lbSet = new TreeSet<Integer>();
TreeSet<Integer> zglSet = new TreeSet<Integer>();
TreeSet<Integer> zySet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for (int i = 0; i < array.size(); i++) {
int inx = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(inx);
} else if (i % 3 == 0) {
lbSet.add(inx);
} else if (i % 3 == 1) {
zglSet.add(inx);
} else if (i % 3 == 2) {
zySet.add(inx);
}
}
由于看牌有四个玩家,包括底牌,那么我们如果要看四次,显然非常麻烦,我们直接将看牌的动作写成一个方法,每个玩家分别调用即可。
如何实现看牌呢?没错,这时我们隐藏已久的大佬HashMap集合就派上用场了,我们的牌和序号已经存在集合当中蓄势待发了,就等我们玩家的TreeSet了,如何是实现呢?很简单,我们只需要将Set集合当中的元素作为我们Map集合当中的Key,那么就能找到Map集合的Value也就是我们要找的扑克牌,然后遍历输出即可,代码如下:
//定义方法看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
public static void lookPoker(String name, TreeSet<Integer> treeSet, HashMap<Integer, String> hashMap) {
System.out.print(name + "的牌是:");
for (int key : treeSet) {
String poker = hashMap.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}
最后我们在主方法调用方法来看看效果:
刘备的牌是:♦3 ♠3 ♥3 ♣4 ♦6 ♣9 ♦9 ♠9 ♦10 ♥10 ♠J ♥J ♦K ♠K ♣2 ♦2 小王
诸葛亮的牌是:♣3 ♦4 ♣5 ♦5 ♠5 ♥6 ♣7 ♠8 ♥9 ♦J ♦Q ♠Q ♥Q ♣K ♥K ♦A ♠A
周瑜的牌是:♠4 ♥4 ♣6 ♠6 ♦7 ♠7 ♥7 ♣8 ♦8 ♥8 ♣10 ♠10 ♣J ♣A ♥A ♠2 ♥2
底牌的牌是:♥5 ♣Q 大王
可以看到刘备的牌还是不错的啊,这把跟诸葛亮配合着周瑜能赢的可能性不大啊。
三、题目可能存在的问题
大家在做这道题的时候唯一可能出问题的地方就在于存牌的时候,我们花色数组和点数数组循环的时候,有的同学把花色放在外层循环,点数放在内层循环导致排不了序,例如这样:
for (String color : colors) {
for (String number : numbers) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
那么你的输出结果就会是这样:
刘备的牌是:♣6 ♣J ♣K ♦8 ♦K ♠4 ♠7 ♠8 ♠Q ♠K ♥6 ♥8 ♥9 ♥10 ♥J ♥Q 小王
诸葛亮的牌是:♣5 ♣10 ♣Q ♦9 ♦J ♠5 ♠6 ♠10 ♠J ♠A ♥3 ♥4 ♥5 ♥7 ♥K ♥A ♥2
周瑜的牌是:♣7 ♣8 ♣9 ♣A ♣2 ♦3 ♦4 ♦5 ♦6 ♦10 ♦Q ♦A ♦2 ♠3 ♠9 ♠2 大王
底牌的牌是:♣3 ♣4 ♦7
你会发先这样玩家完全看不了牌,这是因为我们在存牌的时候存的是数字,也是我们存进去的序号,对应着每个值在Map集合当中,如果你花色在外层循环就会导致你存进去的是红桃3,红桃3,红桃4.......红桃2,那么我们取出的时候就会导致我们的牌排不了序,他按照你存入的花色数组的顺序去排序了,所以一定要将点数数组的循环放在外层循环。
四、完整代码:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;
public class PokerDemo {
public static void main(String[] args) {
// 1:创建HashMap,键是编号,值是牌
HashMap<Integer, String> hm = new HashMap<Integer, String>();
//2:创建ArrayList,存储编号
ArrayList<Integer> array = new ArrayList<Integer>();
//3:创建花色数组和点数数组
String[] colors = {"♣", "♦", "♠", "♥"};
String[] numbers = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
//4:从0开始往HashMap里面存储编号,并存储对应的牌。同时往ArrayList里面存储编号
int index = 0;
//这个地方让数字numbers在前面是为了能够进行点数的排序,不可更改
for (String number : numbers) {
for (String color : colors) {
hm.put(index, color + number);
array.add(index);
index++;
}
}
hm.put(index, "小王");
array.add(index);
index++;
hm.put(index, "大王");
array.add(index);
//5:洗牌(洗的是编号),用Collections的shuffle()方法实现
Collections.shuffle(array);
//:发牌(发的也是编号,为了保证编号是排序的,创建TreeSet集合接收)
//这里的集合代表的是三个玩家和底牌,玩家名称自定
TreeSet<Integer> lbSet = new TreeSet<Integer>();
TreeSet<Integer> zglSet = new TreeSet<Integer>();
TreeSet<Integer> zySet = new TreeSet<Integer>();
TreeSet<Integer> dpSet = new TreeSet<Integer>();
for (int i = 0; i < array.size(); i++) {
int inx = array.get(i);
if (i >= array.size() - 3) {
dpSet.add(inx);
} else if (i % 3 == 0) {
lbSet.add(inx);
} else if (i % 3 == 1) {
zglSet.add(inx);
} else if (i % 3 == 2) {
zySet.add(inx);
}
}
//8:调用看牌方法
lookPoker("刘备", lbSet, hm);
lookPoker("诸葛亮", zglSet, hm);
lookPoker("周瑜", zySet, hm);
lookPoker("底牌", dpSet, hm);
}
//定义方法看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
public static void lookPoker(String name, TreeSet<Integer> treeSet, HashMap<Integer, String> hashMap) {
System.out.print(name + "的牌是:");
for (int key : treeSet) {
String poker = hashMap.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}
感谢大家的观看,如果能对你有所帮助,是我的荣幸,我们下期再见!