Map&Collections&Poker

本文深入探讨Java中Map与Collection接口的区别与应用,包括HashMap、TreeMap等Map实现类的特性,以及List和Set作为Collection子接口的使用场景。详细解析了Map与Collection的常见操作,如添加、删除、遍历等,同时提供了丰富的代码示例,帮助读者掌握Java集合框架的核心概念。

文章目录

Map

描述:

键映射到值的对象, 地图不能包含重复的键; 每个键可以映射到最多一个值。
这个接口取代了Dictionary类,它是一个完全抽象的类而不是接口。

  • Map&Collection区别

    • Map 存储的是键值对形式的元素,键唯一,值可以重复。
    • Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。
  • Map接口功能

    • 添加功能

      V put(K key,V value):添加元素。
      	若存在则返回更新之前的value值,不存在返回NULL,且属于可选择返回:可以返回,也可以不返回。
      
      /*for example*/
      Map<String, String> map = new HashMap<String, String>();
      System.out.println(map.put("Tom", "2"));	//NULL
      System.out.println(map.put("Tom", "3"));	//2
      
    • 删除功能

      void clear():移除所有的键值对元素.
      V remove(Object key):根据键删除键值对元素,并把值返回.
      System.out.println("remove:" + map.remove("Tom));	//3
      
    • 判断功能

      boolean containsKey(Object key):判断集合是否包含指定的键.
      boolean containsValue(Object value):判断集合是否包含指定的值.
      boolean isEmpty():判断集合是否为空.
      
    • 获取功能

      Set<Map.Entry<K,V>> entrySet():返回键值对.
      	/*for example*/
      	Set<Map.Entry<String, String>> set = map.entrySet();
      
      V get(Object key):根据键获取值.
      	/*for example*/
      	System.out.println("get:" + map.get("Tom"));	//显示3.
      
      Set<K> keySet():获取集合中所有键的集合.
      	/*for example*/
      	Set<String> set = map.keySet();
      
      Collection<V> values():获取集合中所有值的集合.
      	/*for example*/
      	Collection<String> con = map.values();
      
      /*conclusion*/
      Map<String, String> map = new HashMap<String, String>();
      Set<Map.Entry<String, String>> set = map.entrySet();		
      		for (Map.Entry<String, String> Aa : set) {			
      			String key = Aa.getKey();
      			String value = Aa.getValue();
      			System.out.println(key + "---" + value);
      		}
      		
      
    • 长度功能

      int size():返回集合中的键值对的对数.
      		/*for example*/
      		System.out.println("size:"+map.size());
      
  • Map集合的遍历

    • 键->值.

      /*for example*/
      Map<String, String> map = new HashMap<String, String>();
      		Set<String> set = map.keySet();
      		
      		for (String key : set) {			
      			String value = map.get(key);
      			System.out.println(key + "---" + value);
      		}
      
    • 键值对->找键和值

      Map<String, String> map = new HashMap<String, String>();		
      Set<Map.Entry<String, String>> set = map.entrySet();
      
      		/*遍历键值对*/
      		for (Map.Entry<String, String> me : set) {			
      			String key = me.getKey();
      			String value = me.getValue();
      			System.out.println(key + "---" + value);
      		}
      
  • HashMap集合

    • HashMap<String,String>

      		HashMap<String, String> hm = new HashMap<String, String>();
      		
      		-键值对添加区域-	//hm.put("key","value")
      
      		/*遍历*/
      		Set<String> set = hm.keySet();
      		for (String key : set) {
      			String value = hm.get(key);
      			System.out.println(key + "---" + value);
      		}
      
    • HashMap<Integer,String>

      HashMap<Integer, String> hm = new HashMap<Integer, String>();
      
      	-键值对添加区域-	//hm.put(key,"value")
      
      	// 遍历
      	Set<Integer> set = hm.keySet();
      	for (Integer key : set) {
      		String value = hm.get(key);
      		System.out.println(key + "---" + value);
      	}
      
    • HashMap<String,Student>

      HashMap<String, Student> hm = new HashMap<String, Student>();
      
      	-键值对添加区域-	
      		//hm.put("key",value) value=objecet对象,如student.
      
      	// 遍历
      	Set<String> set = hm.keySet();
      	for (String key : set) {			
      		Student value = hm.get(key);
      		System.out.println(key + "---" + value.getName() + "---"
      				+ value.getAge());
      }
      
    • HashMap<Student,String>

      HashMap<Student, String> hm = new HashMap<Student, String>();
      
      		-键值对添加区域-	
      				//hm.put(value,"key") value=objecet对象,如student.	
      
      		// 遍历
      		Set<Student> set = hm.keySet();
      		for (Student key : set) {
      			String value = hm.get(key);
      			System.out.println(key.getName() + "---" + key.getAge() + "---"
      					+ value);
      	}
      
  • TreeMap集合

    • TreeMap<String,String>

      TreeMap<String, String> tm = new TreeMap<String, String>();
      		
      		-键值对添加区域-	
      						//hm.put("key","value") 
      
      		// 遍历集合
      		Set<String> set = tm.keySet();
      		for (String key : set) {
      			String value = tm.get(key);
      			System.out.println(key + "---" + value);
      		}
      
    • TreeMap<Student,String>

      /*for example*/
      
      /*自动生成学生类*/
      public class Student {
      	private String name;
      	private int age;
      
      	public Student() {
      		super();
      	}
      
      	public Student(String name, int age) {
      		super();
      		this.name = name;
      		this.age = age;
      	}
      
      	public String getName() {
      		return name;
      	}
      
      	public void setName(String name) {
      		this.name = name;
      	}
      
      	public int getAge() {
      		return age;
      	}
      
      	public void setAge(int age) {
      		this.age = age;
      	}
      }
      
      /*测试主类*/
      import java.util.Comparator;
      import java.util.Set;
      import java.util.TreeMap;
      
      /*TreeMap<Student,String>*/
      
      public class TreeMapMain {
      	public static void main(String[] args) {
      
      		//匿名抽象借口重写
      		TreeMap<Student, String> tm = new TreeMap<Student, String>(
      				new Comparator<Student>() {					
      					@Override
      					public int compare(Student s1, Student s2) {
      						//第一个变量-第二个=升序排列.
      						// 优先级年龄
      						int num = s1.getAge() - s2.getAge();
      						// 优先级名字
      						int num2 = num == 0 ? s1.getName().compareTo(
      								s2.getName()) : num;
      						return num2;
      					}
      				});
      		
      		Student s1 = new Student("Aa", 30);
      		Student s2 = new Student("Bb", 35);
      		Student s3 = new Student("Cc", 33);
      		Student s4 = new Student("Dd", 32);
      		Student s5 = new Student("Ee", 33);
      		
      		tm.put(s1, "01");
      		tm.put(s2, "02");
      		tm.put(s3, "03");
      		tm.put(s4, "04");
      		tm.put(s5, "05");
      
      		// 遍历
      		Set<Student> set = tm.keySet();
      		for (Student key : set) {
      			String value = tm.get(key);
      			System.out.println(key.getName() + "---" + key.getAge() + "---"
      					+ value);
      		}
      	}
      }
      
      
      
  • 多层嵌套

    • hashMap&hashMap

      /*for example*/
      //注意导包:Ctrl+Shift+O
      
      package TestAa;
      
      import java.util.HashMap;
      import java.util.Set;
      
      public class HashMapHashMap {
      	public static void main(String[] args) {
      
      		HashMap<String, HashMap<String, Integer>> bigMap = new HashMap<String, HashMap<String, Integer>>();
      
      		// 子图一
      		HashMap<String, Integer> oneMap = new HashMap<String, Integer>();
      		oneMap.put("Tom", 5);
      		oneMap.put("Jack", 2);
      		bigMap.put("one", oneMap);
      
      		// 子图二
      		HashMap<String, Integer> twoMap = new HashMap<String, Integer>();
      		twoMap.put("John", 3);
      		twoMap.put("Suqi", 4);
      		bigMap.put("two", twoMap);
      
      		// 遍历集合
      		Set<String> bigMapSet = bigMap.keySet();
      		for (String bigMapKey : bigMapSet) {
      			System.out.println(bigMapKey);
      
      			HashMap<String, Integer> bigMapValue = bigMap.get(bigMapKey);
      			Set<String> sonMapSet = bigMapValue.keySet();
      			for (String sonValue : sonMapSet) {
      				Integer value = bigMapValue.get(sonValue);
      				System.out.println("\t" + sonValue + "---" + value);
      			}
      		}
      	}
      }
      
      
    • 统计字符串字母频数

      public class TreeMap{
      	public static void main(String[] args) {
      		
      		Scanner sc = new Scanner(System.in);
      		System.out.println("请输入一个字符串:");
      		String line = sc.nextLine();
      		
      		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();		
      		char[] chs = line.toCharArray();
      		
      		for(char ch : chs){			
      			Integer i =  tm.get(ch);			
      			if(i == null){
      				tm.put(ch, 1);
      			}else {				
      				i++;
      				tm.put(ch,i);
      			}
      		}
      				
      		StringBuilder sb=  new StringBuilder();	
      		
      		Set<Character> set = tm.keySet();
      		for(Character key : set){
      			Integer value = tm.get(key);
      			sb.append(key).append("(").append(value).append(")");
      		}		
      		String result = sb.toString();
      		System.out.println("result:"+result);
      	}
      }
      
  • 忽略以下.

    • HashMap嵌套ArrayList
    • ArrayList嵌套HashMap
    • 多层嵌套

Collections

描述:注意与collection的区别,是针对集合进行操作的工具类.

  • Collection&Collections差异
    • Collection 是单列集合的顶层接口,有两个子接口List和Set.
    • Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等.
  • 常用函数
    • public static void sort(List list)

      List<Integer> list = new ArrayList<>();
      list.add(value);			//value为Integer数据类型.
      Collections.sort(list);
      
    • public static int binarySearch(List<?> list,T key)

      /*二分查找法,返回Index,未找到为-[(List.size)+1]*/
      System.out.println("binarySearch:" + Collections.binarySearch(list, 60));
      
    • public static T max(Collection<?> coll)

      /*for example,获取最大值.*/
      System.out.println("max:" + Collections.max(list));
      
    • public static void reverse(List<?> list)

      Collections.reverse(list);	//List反转
      System.out.println("list:" + list);
      
    • public static void shuffle(List<?> list)

      Collections.shuffle(list);	//List随机打乱.
      System.out.println("list:" + list);
      
  • 代码实例:
    • ArrayList对象排序

      public class CollectionsDemo {
      	public static void main(String[] args) {
      		
      		List<Student> list = new ArrayList<Student>();
      		- 添加对象数据区域-
      		- 		
      		// Collections.sort(list);
      		// 比较器排序,如果同时有自然排序和比较器排序,以比较器排序为主
      		Collections.sort(list, new Comparator<Student>() {
      			@Override
      			public int compare(Student s1, Student s2) {
      				int num = s2.getAge() - s1.getAge();
      				int num2 = num == 0 ? s1.getName().compareTo(s2.getName())
      						: num;
      				return num2;
      			}
      		});
      		
      		for (Student s : list) {
      			System.out.println(s.getName() + "---" + s.getAge());
      		}
      	}
      }
      
    • 斗地主洗牌&发牌&排序-(来源于网上.)

      package cn.itcast_04;
      
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.HashMap;
      import java.util.TreeSet;
      
      /*
       * 思路:
       * 		A:创建一个HashMap集合
       * 		B:创建一个ArrayList集合
       * 		C:创建花色数组和点数数组
       * 		D:从0开始往HashMap里面存储编号,并存储对应的牌
       *        同时往ArrayList里面存储编号即可。
       *      E:洗牌(洗的是编号)
       *      F:发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)
       *      G:看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
       */
      public class PokerDemo {
      	public static void main(String[] args) {
      		// 创建一个HashMap集合
      		HashMap<Integer, String> hm = new HashMap<Integer, String>();
      
      		// 创建一个ArrayList集合
      		ArrayList<Integer> array = new ArrayList<Integer>();
      
      		// 创建花色数组和点数数组
      		// 定义一个花色数组
      		String[] colors = { "♠", "♥", "♣", "♦" };
      		// 定义一个点数数组
      		String[] numbers = { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q",
      				"K", "A", "2", };
      
      		// 从0开始往HashMap里面存储编号,并存储对应的牌,同时往ArrayList里面存储编号即可。
      		int index = 0;
      
      		for (String number : numbers) {
      			for (String color : colors) {
      				String poker = color.concat(number);
      				hm.put(index, poker);
      				array.add(index);
      				index++;
      			}
      		}
      		hm.put(index, "小王");
      		array.add(index);
      		index++;
      		hm.put(index, "大王");
      		array.add(index);
      
      		// 洗牌(洗的是编号)
      		Collections.shuffle(array);
      
      		// 发牌(发的也是编号,为了保证编号是排序的,就创建TreeSet集合接收)
      		TreeSet<Integer> fengQingYang = new TreeSet<Integer>();
      		TreeSet<Integer> linQingXia = new TreeSet<Integer>();
      		TreeSet<Integer> liuYi = new TreeSet<Integer>();
      		TreeSet<Integer> diPai = new TreeSet<Integer>();
      
      		for (int x = 0; x < array.size(); x++) {
      			if (x >= array.size() - 3) {
      				diPai.add(array.get(x));
      			} else if (x % 3 == 0) {
      				fengQingYang.add(array.get(x));
      			} else if (x % 3 == 1) {
      				linQingXia.add(array.get(x));
      			} else if (x % 3 == 2) {
      				liuYi.add(array.get(x));
      			}
      		}
      
      		// 看牌(遍历TreeSet集合,获取编号,到HashMap集合找对应的牌)
      		lookPoker("风清扬", fengQingYang, hm);
      		lookPoker("林青霞", linQingXia, hm);
      		lookPoker("刘意", liuYi, hm);
      		lookPoker("底牌", diPai, hm);
      	}
      
      	// 写看牌的功能
      	public static void lookPoker(String name, TreeSet<Integer> ts,
      			HashMap<Integer, String> hm) {
      		System.out.print(name + "的牌是:");
      		for (Integer key : ts) {
      			String value = hm.get(key);
      			System.out.print(value + " ");
      		}
      		System.out.println();
      	}
      }
      
      
      
package com.ninidong.game; /* Common类提供了一系列与斗地主游戏中扑克牌操作相关的静态方法, 涵盖了牌型判断、牌的移动、排序、 重新摆放以及出牌合法性检查等多方面功能, 辅助游戏逻辑的实现, 这些方法可以被游戏中其他相关类方便地调用 */ import com.ninidong.domain.Poker; import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.concurrent.Callable; public class Common { //1.牌型判断 public static PokerType jugdeType(ArrayList<Poker> list) { int len=list.size(); //处理单张,对子,三张,炸弹等简单牌型 if(len<=4) { //判断是否为相同点数的牌 if(list.size()>0&&Common.getValue(list.get(0))==Common.getValue(list.get(len-1))) { switch (len) { case 1:return PokerType.c1;//单张 case 2:return PokerType.c2;//对子 case 3:return PokerType.c3;//三张 case 4:return PokerType.c4;//炸弹 } } //处理王炸 if(len==2&&Common.getColor(list.get(1))==5) { return PokerType.c2; } //处理三带一 if(len==4&&((Common.getValue(list.get(0))==Common.getValue(list.get(len-2)))||Common.getValue(list.get(1))==Common.getValue(list.get(len-1)))) return PokerType.c31; } //处理5张及以上的复杂牌型 if(len>=5) { //1.初始化牌型统计工具 PokerIndex pokerIndex=new PokerIndex(); ArrayList<ArrayList<Integer>> indexList=pokerIndex.indexList; for (int i = 0; i < 4; i++) { indexList.add(new ArrayList<>()); } //2.统计牌面点数出现的此次 Common.getMax(pokerIndex,list);//调用getMax方法 //3.根据不同规则判断具体牌型(顺子,连对) //判断顺子(c123) if((Common.getColor(list.get(0))!=5)//保证不是大小王 &&(indexList.get(0).size()==len)//出现 1 次的点数” 数量等于总牌数 &&(Common.getValue(list.get(0))-Common.getValue(list.get(len-1))==len-1))//最大值 - 最小值 = n-1 return PokerType.c123; //判断连对(c112233) if(indexList.get(1).size()==len/2&&//条件1:对子数量=总牌数/2(每对2张) len%2==0&&//条件2:总牌数为偶数 len/2>=3&&//条件3:至少3对 (Common.getValue(list.get(0))-Common.getValue(list.get(len-1))==(len/2-1))) //条件4:对子点数连续 return PokerType.c112233; //判断飞机 if(len%3==0//总牌数是3的倍数 &&indexList.get(2).size()==len/3//出现3次的点数数量=总牌数/3(全是3张牌) &&len/3>=2&&//至少三组 (indexList.get(2).get(0)-indexList.get(2).get(indexList.get(2).size()-1)==(len/3-1))) return PokerType.c111222; //判断飞机带单牌 if(len%4==0&&//总牌数是4的倍数 indexList.get(2).size()==len/4&&//三张组的数量=总牌数/4(组数) indexList.get(0).size()==len/4&&//单牌数量=组数 (indexList.get(2).get(0)-indexList.get(2).get(indexList.get(2).size()-1)==(len/4-1))) //飞机本身点数连续 { return PokerType.c11122234; } //判断飞机加对子 if(len%5==0&& indexList.get(2).size()==len/5&& indexList.get(1).size()==len/5&& (indexList.get(2).get(0)-indexList.get(2).get(indexList.get(2).size()-1)==(len/5-1))) { return PokerType.c1112223344; } ///判断c32 if(len==5&&//总牌数=5 indexList.get(2).size()==1//有1组3张牌 &&indexList.get(1).size()==1)//有1对牌 { return PokerType.c32; } //判断4带2 if(len==6&&//总牌数=6 indexList.get(3).size()==1//有一组4张炸弹 &&(indexList.get(0).size()==2||indexList.get(1).size()==1)) //附属牌是2单张(2个1次出现)or1对(1个2次出现) { return PokerType.c411; } //判断4带2对 if(len==8&& indexList.get(3).size()==1 &&indexList.get(1).size()==2) { return PokerType.c422; } //4.符合规则返回对应牌型 return PokerType.c0; } return PokerType.c0;//不符合任何规定的牌型 } //移动牌 public static void move(Poker poker,Point from,Point to) { //开始位置和目标位子不一样的话 if(to.x!=from.x) { //计算移动轨迹的斜率和截距 double k=(1.0)*(to.y-from.y)/(to.x-from.x); double b=to.y-to.x*k; //如果起点x小于终点x(向右移动),步数为+20 //否则,步长为-20 //确定移动方向 int flag=(from.x<to.x)?20:-20; //分步移动实现动画 for(int i=from.x;Math.abs(i-to.x)>20;i+=flag) { double y=k*i+b;//计算当前x对应的y坐标 poker.setLocation(i,(int) y); try{ Thread.sleep(5);//控制动画速度 }catch(InterruptedException e) { e.printStackTrace(); } } } } //出牌合法性校验 public static int checkCards(ArrayList<Poker> c,ArrayList<ArrayList<Poker>> current,GameFrame m) { //确定上一轮出牌 ArrayList<Poker> currentlist; if (m.time[0].getText().equals("不要")) currentlist = current.get(2); else { currentlist = current.get(0); } //获取双方牌型 PokerType cType = Common.jugdeType(c); PokerType cType2 = Common.jugdeType(currentlist); //基本校验 if (cType != PokerType.c4 && c.size() != currentlist.size()) { return 0; } if (cType != PokerType.c4 && cType != cType2) { return 0; } //炸弹规则:炸弹可以压任何非炸弹牌 if (cType == PokerType.c4) { if (c.size() == 2) { return 1; } if (cType2 != PokerType.c4) { return 1; } } //单张/对子/三张/炸弹的大小比较 if (cType == PokerType.c1 || cType == PokerType.c2 || cType == PokerType.c3 || cType == PokerType.c4) { return (Common.getValue(c.get(0)) > Common.getValue(currentlist.get(0))) ? 1 : 0; } //顺子/连对/飞机等牌型的大小比较 if (cType == PokerType.c123 || cType == PokerType.c112233 || cType == PokerType.c111222) { return (Common.getValue(c.get(0))>Common.getValue(currentlist.get(0)))?1:0; } return 1; } //提取三张牌组合 //牌的排序机制 public static void order(ArrayList<Poker> list) { Collections.sort(list, new Comparator<Poker>() { @Override public int compare(Poker o1, Poker o2) { //解析花色和点数 int a1=Integer.parseInt(o1.getName().substring(0,1)); int a2=Integer.parseInt(o2.getName().substring(0,1)); int b1=Integer.parseInt(o1.getName().substring(0,1)); int b2=Integer.parseInt(o1.getName().substring(0,1)); //计算牌值 //大小王特殊处理 if(a1==5)b1+=100; if(a2==5)b2+=100; //A和2的特殊处理 if(b1==1) b1+=20; if(b2==1) b2+=20; if(b1==2) b1+=30; if(b2==2) b2+=30; //倒序排列 int flag=b2-b1; //牌值相同则花色排序 if(flag==0) { return a2-a1; }else { return flag; } } }); } /* 这段代码是一个用于构建扑克牌组合模型(Model)的方法, 其核心功能是根据指定的处理顺序, 从手牌中提取各种合法牌型并封装到Model对象中, 为游戏中的牌型分析、AI 决策或玩家操作提供数据支持 */ public static Model getModel(ArrayList<Poker> list,int[] orders) { //1.创建手牌的副本,避免修改原始集合 ArrayList list2=new ArrayList<>(list); //初始化一个空的Model对象,用于存储提取的牌型 Model model=new Model(); //3.按照orders数组指定的顺序,依次处理手牌并提取牌型 for (int i = 0; i < orders.length; i++) { showOrders(orders[i],list2,model); } //4.返回封装了各种牌型的Model对象 return model; } //用于计算扑克牌组合分数 public static int getScore(ArrayList<Poker> list) { //初始化分数计数器 int count=0; //遍历牌集合中的每一张牌 for (int i = 0,len= list.size();i<len; i++) { Poker poker=list.get(i); //判断是否为大小王 if(poker.getName().substring(0,1).equals("5")) { count+=5; } //判断是否为点数2的牌 if(poker.getName().substring(2).equals("2")) { count+=2; } } return count;//返回总分数 } //重新排列扑克牌布局 public static void rePosition(GameFrame m,ArrayList<Poker> list,int flag) { Point p=new Point();//用于存储牌的起始坐标 if(flag==0) { //左侧玩家的牌的起始位置 p.x=50;//固定坐标 p.y=(450/2)-(list.size()+1)*15/2;//计算y坐标 } if(flag==1) { //中间玩家的牌的起始位置 p.x=(800/2)-(list.size()+1)*21/2; p.y=450; } if(flag==2) { p.x=700; p.y=(450/2)-(list.size()+1)*15/2; } int len=list.size(); for (int i = 0; i < len; i++) { Poker poker=list.get(i); //调用move方法,实现牌从当前位置到目标位置的动画移动 Common.move(poker,poker.getLocation(),p); //设置牌在容器中的显示层级 m.container.setComponentZOrder(poker,0); //计算下一张牌的位置 if(flag==1) { p.x+=21; }else{ p.x+=15; } } } /* getMax方法是斗地主游戏中用于统计扑克牌手牌中 点数出现次数的核心工具方法, 其作用是将手牌中各种点数的出现频率进行分类统计, 为后续判断复杂牌型(如顺子、连对、飞机等)提供数据支持 */ public static void getMax(PokerIndex pokerIndex,ArrayList<Poker> list) { //1.初始化计数数组 int count[]=new int[14];//长度为14的数组,用于统计1-13点和大小王的出现次数 for(int i=0;i<14;i++) { count[i]=0;//初始化数组元素为0 } //2.统计每张牌的出现次数 for (int i = 0,len=list.size(); i <len ; i++) { if(Common.getColor(list.get(i))==5)//判断是否为大小王(花色为5) count[13]++; else { count[Common.getValue(list.get(i))-1]++; } } ArrayList<ArrayList<Integer>> indexList=pokerIndex.indexList; for (int i = 0; i < 14; i++) { switch(count[i]) { case 1://出现1次的次数 indexList.get(0).add(i+1);//存入indexList的第0个集合 break; case 2://出现2次的次数--对子 indexList.get(1).add(i+1);//存入indexList的第1个集合 break; case 3://出现3次的次数--三张 indexList.get(2).add(i+1);//存入indexList的第2个集合 break; case 4://出现4次的次数--炸弹 indexList.get(3).add(i+1);//存入indexList的第3个集合 break; } } } /* 它根据传入的整数参数i, 调用对应的牌型提取方法, 将手牌中符合条件的牌型提取出来并存储到Model对象中 */ public static void showOrders(int i,ArrayList<Poker> list,Model model) { switch(i) { case 1: //处理单张牌型 Common.getSingle(list,model);//提取单张牌 case 2: //处理对子相关的牌型 Common.getTwo(list,model); Common.getTwoTwo(list,model); break; case 3: //处理三张相关牌型 Common.getTree(list,model); Common.getPlane(list,model); case 4: //初始炸弹 Common.getBoomb(list,model); case 5: //处理顺子 Common.get123(list,model); break; } } /* 用于从手牌中提取所有单张牌型并存储到模型中的工具方法 */ //处理单张牌 private static void getSingle(ArrayList<Poker> list, Model model) { //1。创建一个临时集合,用于存储要从手牌中移除的牌 ArrayList<Poker> del=new ArrayList<>(); //2.遍历手牌中的每一张牌 for (int i = 0,len= list.size(); i <len ; i++) { //将当前牌的名称添加到model的a1集合中 model.a1.add(list.get(1).getName()); //将当前牌加入待删除集合中 del.add(list.get(i)); } //3.从手牌中移除所以已经提取的单张牌 list.removeAll(del); } //处理顺子 public static void get123(ArrayList<Poker> list,Model model) { ArrayList<Poker> del=new ArrayList<>(); //1.边界条件判断,如果牌集合不为空,且首张牌小于7or末张牌值大于10,则直接返回 if(list.size()>0&&(Common.getValue(list.get(0))<7||Common.getValue(list.get(list.size()-1))>10)) { return; } //2.牌数量小于5张,无法构成顺子,直接返回 if(list.size()<5) { return; } ArrayList<Poker> list2=new ArrayList<>(); ArrayList<Poker> temp=new ArrayList<>(); ArrayList<Integer> integers=new ArrayList<>(); //3.对手牌去重处理,将不同牌值的牌放进temp集合 for(Poker poker:list2) { if(integers.indexOf(Common.getValue(poker))<0) { integers.add(Common.getValue(poker)); temp.add(poker); } } //4.对去重后的牌集合temp按牌值进行排序 Common.order(temp); //5.遍历排序后的牌集合,查找顺子 for (int i=0,len=temp.size();i<len;i++) { int k=i; for(int j=i;j<len;j++) { //判断当前牌与后续牌是否满足顺子条件 if(Common.getValue(temp.get(i))-Common.getValue(temp.get(j))==j-i) { k=j; } } //如果找到长度大于等于4的顺子 if(k-i>=4) { String s=" "; //构建顺子的字符串表示,格式如“牌1,牌2,牌3...” for(int j=i;j<k;j++) { s +=temp.get(i).getName()+","; del.add(temp.get(j)); } s+=temp.get(k).getName(); del.add(temp.get(k)); //将顺子字符串添加到model的123集合中 model.a123.add(s); i=k; } } } //处理连对牌型 public static void getTwoTwo(ArrayList<Poker> list,Model model) { ArrayList<String> del=new ArrayList<>(); //获取Model对象中已经有的对子集合 ArrayList<String> l=model.a2; //如果对子数量小于3,无法构成连对马,直接返回 if(l.size()<3) { return; } Integer s[]=new Integer[l.size()]; //1.解析已经有的对子集合中的牌值,存储到数组s中 for (int i = 0,len=l.size(); i < len; i++) { String[] name=l.get(i).split(","); s[i]=Integer.parseInt(name[0].substring(2,name[0].length())); } //2.遍历对子牌值数组,查找连对 for (int i = 0,len=l.size(); i < len; i++) { int k=i; for (int j = i; j < len; j++) { //判断当前对子与后续是个满足连对条件 if(s[i]-s[j]==j-i) k=j; } //如果找到长度大于等于2的连对 if(k-i>=2) { String ss=" "; //构建连对的字符串表示,格式如“对子1,对子2,...” for (int j = i; j < k; j++) { ss+=l.get(j)+","; del.add(l.get(j)); } ss +=l.get(k); //将连对的字符串添加到model的a112233集合中 model.a112233.add(ss); del.add(l.get(k)); i=k; } } //3.从原有的对子集合中移除已经提取为连对的对子信息 l.removeAll(del); } //将给定的扑克牌集合中的所有牌设置为不可见状态 public static void hideCards(ArrayList<Poker> list) { for (int i = 0,len=list.size(); i < len; i++) { list.get(i).setVisible(false); } } //查找飞机牌型 public static void getPlane(ArrayList<Poker> list,Model model) { ArrayList<String> del=new ArrayList<>(); //获取Model对象中已有的三种牌组合集合 ArrayList<String> l=model.a3; //如果三张牌组合数量小于2,无法构成飞机,直接返回 if(l.size()<2) { return; } Integer s[]=new Integer[l.size()]; //1.解析三张牌组合集合中的牌值,存储到数组s中 for (int i = 0,len=l.size(); i <len ; i++) { String[] name=l.get(i).split(","); s[i]=Integer.parseInt(name[0].substring(2,name[0].length())); } //2.遍历三张牌组合牌值数组,查找飞机牌型 for (int i = 0,len=l.size(); i < len; i++) { int k=i; for (int j = i; j < len; j++) { //判断当前三张牌组合与后续三张牌组合是否满足飞机条件 if (s[i] - s[j] == j - i) k = j; } //如果找到满足条件的飞机 if(k!=i) { String ss=" "; for (int j = i; j < k; j++) { ss +=l.get(j)+","; del.add(l.get(j)); } ss +=l.get(k); //将飞机字符串添加到model的a111222集合中 model.a111222.add(ss); i=k; } } //3.从原有的三张牌组合集合中移除已提取为飞机的组合信息 l.removeAll(del); } //查找炸弹牌型 public static void getBoomb(ArrayList<Poker> list,Model model) { ArrayList<Poker> del=new ArrayList<>(); //如果牌集合为空,直接返回,无法提取炸弹 if(list.size()<1) return; //1.处理大小王构成的炸弹情况 if(list.size()>=2&&Common.getColor(list.get(0))==5&&Common.getColor(list.get(1))==5) { model.a4.add(list.get(0).getName()+","+list.get(1).getName()); del.add(list.get(0)); del.add(list.get(1)); } //2.处理单张大小王情况 if(Common.getColor(list.get(0))==5&&Common.getColor(list.get(1))!=5) { del.add(list.get(0)); model.a1.add(list.get(0).getName()); } list.removeAll(del); //3.遍历牌的集合,查找普通炸弹 for (int i = 0,len=list.size(); i < len; i++) { if(i+3<len&&Common.getValue(list.get(i))==Common.getValue(list.get(i+3))) { String s=list.get(i).getName()+","; s+=list.get(i+1).getName()+","; s+=list.get(i+2).getName()+","; s+=list.get(i+3).getName(); model.a4.add(s); for (int j = i; j <=i+3; j++) del.add(list.get(j)); i=i+3; } } //4.从牌集合中移除已经提取为炸弹的牌 list.removeAll(del); } //拿到牌之后重新排序 public static ArrayList getOrder2(List<Poker> list) { ArrayList<Poker> list2 = new ArrayList<>(list); ArrayList<Poker> list3 = new ArrayList<>(); int len = list2.size(); int a[] = new int[20]; for (int i = 0; i < 20; i++) a[i] = 0; for (int i = 0; i < len; i++) { a[Common.getValue(list2.get(i))]++; } int max = 0; for (int i = 0; i < 20; i++) { max = 0; for (int j = 19; j >= 0; j--) { if (a[j] > a[max]) max = j; } for (int k = 0; k < len; k++) { if (Common.getValue(list2.get(k)) == max) { list3.add(list2.get(k)); } } list2.remove(list3); a[max] = 0; } return list3; } //从手牌中提取三张相同点数的牌组合 public static void getTree(ArrayList<Poker> list,Model model) { ArrayList<Poker> del=new ArrayList<>(); //遍历牌集合,查找三张相同点数的牌组合 for (int i = 0,len=list.size();i<len; i++) { if(i+2<len&&Common.getValue(list.get(i))==Common.getValue(list.get(i+2))) { String s=list.get(i).getName()+","; s+=list.get(i+1).getName()+","; s+=list.get(i+2).getName(); model.a3.add(s); for (int j = i; j <=i+2 ; j++) { del.add(list.get(j)); i=i+2; } } } //从牌集合中移除已提取为三张牌组合的牌 list.removeAll(del); } //用于从手牌中提取对子牌 public static void getTwo(ArrayList<Poker> list,Model model) { ArrayList<Poker> del=new ArrayList<>(); //遍历牌集合,查找两种相同点数的牌组合(对子) for (int i = 0,len=list.size(); i < len; i++) { if(i+1<len&&Common.getValue(list.get(i))==Common.getValue(list.get(i+1))) { String s=list.get(i).getName()+","; s+=list.get(i+1).getName(); model.a2.add(s); for (int j = i; j <=i+1; j++) { del.add(list.get(j)); i=i+1; } } } //从牌集合中移除已经提取为对子的牌 list.remove(del); } //计算牌的价值(用于比较大小) public static int getValue(Poker poker) { int i=Integer.parseInt(poker.getName().substring(2)); if(poker.getName().substring(2).equals("2")) { i+=13;//A } if(poker.getName().substring(2).equals("1")) { i+=13;//2 } if(Common.getColor(poker)==5) { i+=2; } return i; } /* 1:黑桃 2:红桃 3:梅花 4:方块 5:大小王(特殊花色) */ //判断花色 private static int getColor(Poker poker) { return Integer.parseInt(poker.getName().substring(0,1)); //格式规则:"花色-点数"(通过-分隔花色和点数) } } /*PokerIndex类是一个用于辅助统计和分析扑克牌点数 分布情况的数据结构类, 主要作用是 在判断复杂牌型(如顺子、连对、飞机等)时, 提供牌面点数出现次数的统计信息 */ class PokerIndex{ //嵌套集合:外层集合表示"出现次数“的分类,内层集合存储对应点数 ArrayList<ArrayList<Integer>> indexList=new ArrayList<>(); } 改进这段代码
最新发布
09-30
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值