引言
最近学习java相关的知识,学习了传智老师讲的斗地主案例感觉还是有点意思,此处小猿决定学习该案例并做一些相关的笔记,废话不多讲,我们开始进入正题。
案例需求
现有player1,player1,player1三人需要完poker,我们操作是将54张牌发给这三人,在这过程中需要经历的是:
准备牌->洗牌->发牌->看牌四个过程,我们需要用集合的知识实现这个过程。
方案一
采用单列集合实现本案例
知识架构
arrayList继承了的集成体系如下所示:
而list接口和set接口都是来源于collection
案例的基本思路是采用ArrayList集合,一个大集合来储存所有poker,然后遍历poker一次添加到不同玩家所采的集合,当poker只剩三张的时候就做底牌,废话不多说,献上代码。
代码实现
public class DouDiZhuDemo {
public static void main(String[] args) {
Collection collection = readyPoker();
collection=shufflePoker(collection);
ArrayList<String> dipai=new ArrayList<>();
ArrayList<String> [] player=new ArrayList[4];
for (int i = 0; i < player.length; i++) {
player[i]=new ArrayList<>();
}
distributePoker(collection,dipai,player);
lookPoker(dipai,player);
}
//准备牌
public static Collection readyPoker(){
ArrayList<String> poker = new ArrayList<>();
// 静态定义数组
String [] number= {
"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//动态定义数组,复习一下动态定义数组的方法,可以参考一下和C/C++定义数组有什么区别
String [] color = new String[4];
color[0]="♠";
color[1]="♥";
color[2]="♣";
color[3]="♦";
for (int i = 0; i < number.length; i++) {
for (int i1 = 0; i1 < color.length; i1++) {
poker.add(number[i]+color[i1]);
}
}
poker.add("大王");
poker.add("小王");
System.out.println("开始准备poker");
System.out.println(poker);
return poker;
}
//洗牌
public static Collection shufflePoker(Collection poker){
Collections.shuffle((List<?>) poker);
return poker;
}
//发牌
public static void distributePoker(Collection poker,ArrayList dipai, ArrayList... player){
ArrayList<?> poker1 = (ArrayList<?>) poker;
String p=null;
for (int i = 0; i < poker1.size(); i++) {
p= (String) poker1.get(i);
if(i>50){
dipai.add(p);
}else {
for (int i1 = 0; i1 < player.length; i1++) {
if(i%player.length==i1){
player[i1].add(p);
break;
}
}
}
}
}
//看牌
public static void lookPoker(ArrayList dipai,ArrayList... player){
System.out.println("-------------------------");
System.out.println("dipai"+dipai);
System.out.println("-----------------------");
for (int i = 0; i < player.length; i++) {
System.out.println("player"+i+"pokeris:"+player[i]);
}
}
}
图中假定有四个人,小猿采用可变参的参数传递方式,这样做的好处是人数可变,具有较高的灵活性。
先看看结果:
上述案例有个缺点就是看牌的时候poker没有按照顺序排列,所以需要考虑用其他双列集合来实现该案例。
方案二
采用双列集合实现斗地主案例
知识架构
map是一个java中的顶层接口,改接口常见的继承体系如下图。
小猿要重点关注的是Map下的hashmap的应用,采用hashMap实现上述案例,废话不多说,献上代码
代码实现
public class DouDiZhuDemo {
public static void main(String[] args) {
Collection<Integer> pokerIndex=new ArrayList<>();
Map<Integer, String> poker= new HashMap<>();
readyPoker(pokerIndex,poker);
// System.out.println(pokerIndex);
// System.out.println(poker);
shufflePoker(pokerIndex);
System.out.println(pokerIndex);
// System.out.println(poker.size());
Map<String, List> disPoker = new HashMap<>();
disPoker.put("赵丽颖",new ArrayList());
disPoker.put("杨幂",new ArrayList());
disPoker.put("陈乔恩",new ArrayList());
disPoker.put("杨紫",new ArrayList());
disPoker.put("底牌",new ArrayList());
disPoker.put("张天爱",new ArrayList());
disPoker.put("甘露露",new ArrayList());
try {
disPoker=distributePoker(pokerIndex,disPoker,poker);
} catch (Exception e) {
e.printStackTrace();
}
lookPoker(disPoker);
}
//准备牌
public static void readyPoker(Collection<Integer> pokerIndex, Map<Integer, String> poker){
//定义洗好的poker索引
//定义poker
System.out.println("------------------准备poker-------------------------");
// 定义牌的数字
List<String> numbers = List.of("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
// String [] number= {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
//动态定义数组,复习一下动态定义数组的方法,可以参考一下和C/C++定义数组有什么区别
/*String [] color = new String[4];
color[0]="♠";
color[1]="♥";
color[2]="♣";
color[3]="♦";*/
//定义牌的花色
List<String> colors = List.of("♠", "♥", "♣", "♦");
int index=0;
pokerIndex.add(index);
poker.put(index,"大王");
index++;
pokerIndex.add(index);
poker.put(index,"小王");
index++;
for (String number : numbers) {
for (String color : colors) {
pokerIndex.add(index);
poker.put(index,number+color);
index++;
}
}
// System.out.println(pokerIndex);
System.out.println(poker);
//return poker;
}
//洗牌
public static void shufflePoker(Collection poker){
System.out.println("----------开始洗牌-----------");
Collections.shuffle((List<?>) poker);
//return poker;
}
//发牌
/*public static void distributePoker(Collection poker,ArrayList dipai, ArrayList... player){
ArrayList<?> poker1 = (ArrayList<?>) poker;
String p=null;
for (int i = 0; i < poker1.size(); i++) {
p= (String) poker1.get(i);
if(i>50){
dipai.add(p);
}else {
for (int i1 = 0; i1 < player.length; i1++) {
if(i%player.length==i1){
player[i1].add(p);
break;
}
}
}
}
}*/
public static Map distributePoker(Collection pokerIndex,Map<String,List> disPoker,Map<Integer,String> poker ) throws Exception {
System.out.println("-------------------------开始发牌----------------------------");
Map<String,List> newDisPoker = new HashMap<>();
for (int i = 0; i < pokerIndex.size(); i++) {
if(i>50){
if(disPoker.containsKey("底牌")){
List dipai = disPoker.get("底牌");
dipai.add(((List)pokerIndex).get(i));
}else {
throw new Exception("没有底牌");
}
}else {
int size = disPoker.size()-1;
int in=0;
for (String key :
disPoker.keySet()) {
if(key.equals("底牌")){
continue;
}
if(i%size==in){
disPoker.get(key).add(((List)pokerIndex).get(i));
break;
}
in++;
}
}
}
for (String name:disPoker.keySet()
) {
Collections.sort(disPoker.get(name), new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
}
//重新组装牌
for (String name:disPoker.keySet()
) {
List<String> tempList= new ArrayList<>();
for (Object o : disPoker.get(name)) {
tempList.add(o+":"+poker.get(o));
}
newDisPoker.put(name,tempList);
//tempList.clear();
}
//disPoker.clear();
return newDisPoker;
}
//看牌
/*public static void lookPoker(ArrayList dipai,ArrayList... player){
System.out.println("-------------------------");
System.out.println("dipai"+dipai);
System.out.println("-----------------------");
for (int i = 0; i < player.length; i++) {
System.out.println("player"+i+"pokeris:"+player[i]);
}
}*/
public static void lookPoker(Map<String,List> disPoker){
System.out.println("-------------------------------准备看牌----------------------------");
for (Map.Entry<String,List> entry :
disPoker.entrySet()) {
System.out.println(entry.getKey()+"::"+entry.getValue()+"共"+entry.getValue().size()+"::张牌");
}
System.out.println("---------------------------看牌结束-------------------------------");
}
}
此处值得一提的是List的of方法,该方法可以批量添加固定长度的元素,并且添加之后List的长度不在发生变化,即List.of(element…)适合固定长度的元素添加,并且采用该函数对jdk版本有要求,即推荐使用jdk9.0.4,上述代码执行结果为:
总结
通过演练斗地主案例,使得小猿复习了有关集合和图的相关知识,古人云:吾日三省吾身,小猿需要多多反省自己,多多努力。