如何用map的value值显示扑克牌的牌型,对子,三条,炸弹之类的

如何用map的value值显示扑克牌的牌型,对子,三条,炸弹之类的

Map mao=new HashMap();

Map map= new HashMap();
map,put("paixing1","duizi");
map,put("paixing2","santaio");
map,put("paixing3","zhadan");
String name=map.get("paixing1");
String name=map.get("paixing2");
String name=map.get("paixing3");

此前,在公司的项目开发中,我负责着手解决这样一个问题:在斗地主游戏中,根据玩家出的牌分析出这手牌的牌型。
大家知道,在斗地主游戏中,总计有十一种牌型:
火箭:即双王(大王和小王)。
炸弹:四张同数值牌(如四个7)。
单牌:单个牌(如红桃5)。
对牌:数值相同的两张牌(如梅花4+方块4)。
三张牌:数值相同的三张牌(如三个J)。
三带一:数值相同的三张牌 + 一张单牌或一对牌。例如: 333+6或444+99
单顺:五张或更多的连续单牌(如:45678或78910JQK)。不包括2点和双王。
双顺:三对或更多的连续对牌(如:334455、7788991010JJ)。不包括2点和双王。
三顺:二个或更多的连续三张牌(如:333444、555666777888)。不包括2点和双王。
飞机带翅膀:三顺+同数量的单牌(或同数量的对牌)。
如:444555+79 或333444555+7799JJ
四带二:四张牌+两手牌。(注意:四带二不是炸弹)。
如:5555+3+8或4444+55+77。
那么,如何由玩家出的牌分析出这手牌到底是哪一种牌型呢?
在我们试着用程序解决这个问题之前,先来回顾一下在现实的生活中是如何分辨一手牌的牌型的。在斗地主游戏中,确定不同牌型的一个重要依据是看这手牌中有多少张牌的数字是相同的。比如一手这样的牌:梅花2+方块3+红桃3+黑桃3,在我们的思维中,首先会计算有最多相同数字的那些牌的个数,也就是这里的三个3,在这里,3总计出现了3次。根据最多出现相同数字的情况,我们可以把一手牌先分成四种情况:
1、所有数字只出现一次
2、相同数字的牌出现两次
3、相同数字的牌出现三次
4、相同数字的牌出现四次
5、不可能出现的情况:相同数字的牌出现大于四次或小于1次。
其中,在以上的1、2、3、4中又可能分为多种情况,比如在1中,虽然相同数字最多只出现一次,但不能因此就断定它是单张,它也有可能是双王(这里假定大小王的数字不相同)或单顺;在2中,出现两次的情况下,又进一步分为:对子和双顺两种情况;在3中,出现三次的情况下,可能有以下牌型:单三张,三带一,三顺或飞机;在4中,出现4个相同数字牌的时候,可能有以下牌型:炸弹和四带二。
为了建立以上的这种分析模型,我们需要对出的牌进行排序和统计,找出最大的相同个数及相同的数字,再进一步分析它的特征直到最终确定当前牌的牌型。用于实现牌型分析伪过程如下:
注:cardlist为所出牌的列表,cardcount为所出牌的个数。二维数组cardArray[0..12,0..1]是用于分析的辅助数据结构。
1、对cardlist按牌的数字大小进行升序排序
2、对carlist中的每张牌顺序进行以下操作
 将cardlist中牌的数字记入cardarray的低维中,即首先记cardlist[0]的数字于cardarray[0,0]中,并将cardarray[0,1]置为1,然后顺序取出cardlist中的后继牌,判断后继牌是否等于cardarray当前位置的cardarray[X,0]值,如果等于,则在card[x,1]中加1,以求得相同牌的个数,如果不等于,则在新单元cardarray[X+1,0]中记入cardlist当前牌的数字,并把cardarray[x+1,1]置为1。如此循环,对cardlist中的每张牌都进行扫描后,cardarray数组中,低维存放的就是当前这手牌中出现的所有数字,而在其对应的高维中则存放这些数字出现的次数。由这个二维数组,我们便可以初步判定这手牌的牌型。
这是我在实际工作中所采用的牌型分析方法,此方法最初由我们的teamleader提出,后来我作了些小小改动,不知有没有作相同问题研究的朋友,如果有更好的方法可以判断,请不吝赐教。

这种牌型问题我觉得应该将所有可能的牌型都作为一个map集合,比如34567顺子,map集合就叫34567顺子,然后value为3,4,5,6,7
遍历手中卡牌的时候,只要分别调用map的contain()方法,用&&连接,判断是否同时包含所有value,则可以判断出卡牌为顺子34567
这种方法比较复杂 需要写很多的牌型可能性的map,然后一 一判断,最后输出复合的牌型
方法比较笨,但是应该可以实现楼主的要求。。。

这是我自己写的代码,之前刚回答过一个人的问题,printPai是我的方法,参数一,手里的牌,参数二:要找对子还是三个的,还是炸弹,参数3需要寻找的名字。可以根据你自己的需求进行改变代码逻辑,大体上就是这样的一回事

  @Test
    public void testFunction4(){
        /*数字*/
        String[] pai = new String[] { "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2" };
        /*花色*/
        String[] hs = new String[] { "♥", "♠", "♦", "♣" };
        HashMap<String,Integer> hj = new HashMap<>();
        HashMap<String,Integer> hy = new HashMap<>();
        HashMap<String,Integer> hb = new HashMap<>();
        List<String> a = new ArrayList<String>();
        for (int i = 0; i < pai.length; i++) {
            a.add(hs[0]+pai[i]);
            a.add(hs[1]+pai[i]);
            a.add(hs[2]+pai[i]);
            a.add(hs[3]+pai[i]);
        }
        a.add("大王");
        a.add("小王");

        Random rand = new Random();
        String temp = null;
        for (int k = 0; k < 100; k++) {
            int p = a.size();
            int l = rand.nextInt(p);
            int m = rand.nextInt(p);
            if (l == m) {
                continue;
            }
            {
                temp = a.get(l);
                a.set(l, a.get(m));
                a.set(m, temp);
            }
        }
// Collections.shuffle(a);

        List<String> j = new ArrayList<String>();
        List<String> y = new ArrayList<String>();
        List<String> b = new ArrayList<String>();
        List<String> d = new ArrayList<String>();
        for (int i = 0; i < a.size(); i++) {
            if (i >= a.size() - 3) {
                d.add(a.get(i));
            } else if (i % 3 == 0) {
                j.add(a.get(i));
            } else if (i % 3 == 1) {
                y.add(a.get(i));
            } else if (i % 3 == 2) {
                b.add(a.get(i));
            }
        }
        System.out.println(d);
        System.out.println("甲" + j.toString());
        /*获得有三个的*/
        printPai(j,3,null);
        System.out.println("乙" + y.toString());
        System.out.println("丙" + b.toString());
        for (String str : j) {
            if (hj.containsKey(str)) {
                hj.put(str, hj.get(str) + 1);
            } else {
                hj.put(str, 1);
            }
        }
        System.out.println("j" + hj);

        for (String str : y) {
            if (hy.containsKey(str)) {
                hy.put(str, hy.get(str) + 1);
            } else {

                hy.put(str, 1);
            }
        }
        System.out.println("y" + hy);

        for (String str : b) {
            if (hb.containsKey(str)) {
                hb.put(str, hb.get(str) + 1);
            } else {
                hb.put(str, 1);
            }
        }
        System.out.println("b" + hb);
    }

    public void printPai(List<String> pai, Integer count ,String name) {
        if (count == null) {
            /*去掉花色,输出手里面的排*/
            pai.forEach(p ->p=p.substring(1,2));
            System.out.println(pai.toString());
        }else if (name !=null && name !=""){
            /*name为大王的时候输出大王,按名字查找,忽略大小写,忽略花色*/
            pai.stream().filter(p -> p.substring(1,2).equalsIgnoreCase(name)).collect(toList());
            System.out.println(name+":"+ pai.size()+"个");
        } else if (count!=null && name ==null || name !=""  ){
            /*查找指定数量的pai,2对子,3三个,4炸等,忽略花色*/
            HashMap<String, Integer> paiCount = new HashMap<>();
            pai.forEach(p->{
                String p2 =  p.substring(1,2);
                if (paiCount.containsKey(p2)) {
                    paiCount.put(p2, paiCount.get(p2)+1);
                } else {
                    paiCount.put(p2, 1);
                }
            });
            /*输出指定个数的*/
            ArrayList<String> resultPai = new ArrayList<String>();
            paiCount.forEach((k,v)->{
                if (v.equals(count)) {
                    resultPai.add(k);
                }
            });
            System.out.println(count+"个的牌有:"+resultPai.toString());
        } else {
            /*如果count是2输出手里面的对子,3数据三个,4输出炸弹,配合name,如name=大王,输出手里面是否有大王*/
            /*由于不能使用int类型变量来自增统计个数,就使用集合来统计个数一样的*/
            ArrayList list = new ArrayList();
            pai.stream().forEach(p ->{
                if (p.substring(1, 2).equalsIgnoreCase(name)) {
                    list.add(p);
                }
            });
            System.out.println("是否有"+count+"个"+name+":"+ (list.size()>=count?"是":"否"));
        }
    }

给一个输出的结果:

[♦K, ♥4, ♥3]
甲[♣6, ♦6, ♦4, ♠5, ♣4, ♥2, ♦5, ♠Q, ♣K, ♠K, ♦3, ♥8, ♦Q, ♣10, ♠4, ♦7, ♣2]
3个的牌有:[4] --这个是我的方法输出的,查找三个的牌,具体炸弹属不属于三个的你自己定下,然后修改一点代码就好了
乙[♠3, ♦8, ♦A, ♥9, ♣8, ♣A, ♥K, ♥10, ♥6, ♦10, ♣9, ♠2, ♥J, ♣5, ♠8, ♣3, ♠A]
丙[大王, ♥7, ♥Q, ♠9, 小王, ♠7, ♣7, ♣J, ♣Q, ♠10, ♦2, ♠6, ♠J, ♥5, ♦9, ♥A, ♦J]
j{♥2=1, ♦3=1, ♦4=1, ♦5=1, ♣2=1, ♣K=1, ♠K=1, ♦Q=1, ♠4=1, ♠5=1, ♣10=1, ♦6=1, ♣4=1, ♠Q=1, ♦7=1, ♣6=1, ♥8=1}
y{♥J=1, ♥K=1, ♠A=1, ♥9=1, ♣8=1, ♣9=1, ♥10=1, ♣3=1, ♥6=1, ♦10=1, ♦8=1, ♠2=1, ♣5=1, ♠3=1, ♣A=1, ♠8=1, ♦A=1}
b{♦J=1, ♣J=1, ♥Q=1, ♦2=1, ♣Q=1, ♠J=1, 大王=1, ♠10=1, ♣7=1, ♠6=1, ♠7=1, ♥5=1, ♥7=1, 小王=1, ♦9=1, ♥A=1, ♠9=1}