Java实现斗地主实例

论坛 期权论坛 脚本     
已经匿名di用户   2022-7-2 21:58   3000   0

前些天我实现了发红包案例:Java实现微信、QQ等群主发红包实例(普通红包)

Java实现微信、QQ等群主发红包实例(拼手气红包)

今天继续来实现生活中一些有趣的案例:斗地主


分析:

首先,我们来梳理一下规则:

  1. 准备牌阶段:斗地主一般用一副牌,有54张,其中有大王小王各1张,其他52张牌,分别是4个花色,每种花色13张。四种花色分别为 ,定义一个集合来存储它们;而每一种花色中的13张牌为:(由大到小)2 A K Q J 10 9 8 7 6 5 4 3,也定义一个集合来存储它们。遍历这两个集合,可以组装成为52张牌,例如7 A
  2. 洗牌阶段:使用集合工具类Collections方法,其中static void shuffle(List<?> list)使用指定的随机数对指定列表进行置换,会随机的打乱集合中的元素的顺序
  3. 发牌阶段:要求每一位玩家拥有17张牌,剩余三张作为底牌,一人一张轮流发牌:集合的索引(0-53)%3,定义4个集合,来存储3个玩家的牌和场上的底牌。索引%3,有三个值(0,1,2)0%3=01%3=12%3=23%3=0,当索引>=51时,改为发底牌
  4. 看牌阶段:直接打印集合,遍历存储玩家和底牌的集合


实现:

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();
    }
}

结果展示:

两次打印输出的内容不一样,但结果都能按照从大到小的顺序输出,使查看效果和现实中的斗地主一样!

感谢您的阅读,不足之处欢迎指正!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:81
帖子:4969
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP