【Java】斗地主 —— 排序方式一:利用序号进行排序

一、思路分析

排序的过程中,最让人头疼的是:最小的数字 2 反而是最大的,因此我们不好找出它的规律。那怎么办呢?

image-20240429113557682

牌没有规律,但是数字是有规律的。因此我们可以将牌按照指定的规则先进行手动的排列,然后再跟 1 / 2 / 3 ... 这样的数字一一对应。对应完后,我们就可以认为:数字越大,所对应的牌也就越大。

因此我们需要使用 Map集合 将这种对应关系存起来。

那么问题就来了:在 Map集合 集合中,是底下的需要作为 ,还是上面的牌作为 呢?

image-20240429113838891

其实谁作为键有一个规则,在下面的代码中,我们以谁为主导,谁就作为键。

在刚刚我们说了,我们需要将牌先跟序号对应起来,对应起来的目的:牌的规则我们不好把握,但是下面序号的规则就很好把握。

那么在下面的代码中,我们实际上操作的都是序号,因此我们需要将序号当做

与此同时,我们还会创建一个单列集合,用来单独存储牌的序号,这样准备牌的动作我们才算是准备好了。

接下来还有洗牌,所谓洗牌其实洗的就是序号。

发牌发的也是序号,前三个序号作为底牌,后面所有的序号再依次发给三个玩家。

发完后会发现,序号是没有顺序的,我们还需要将序号进行排序。

image-20240429123817449

完事后,在看牌的时候,我们就可以拿着序号到一开始的 Map集合 中找对应的牌就行了。

image-20240429123829498

此时牌就有序了。这种排序思想是利用了编程圈中的:对应思想 —— 如果原始数据的规律非常复杂,我们可以先手动排序让每一个数据唯一的序号产生对应关系。

这里的序号就是数字,规律非常简单,后续的所有操作,我们以序号为准。

当真正需要操作原始数据的时候,再通过序号找到原始数据即可。


二、准备牌

基础代码

public class App {
    public static void main(String[] args) {
        //从程序的主入口开启斗地主游戏
        new PokerGame();
    }
}

public class PokerGame {
    static {
        String[] color = {"♦", "♣", "♥", "♠"};
        String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};
    }
}

接下来的目的:将序号跟牌产生对应关系。

public class PokerGame {
    //牌盒 Map
    //此时我们只要把牌跟序号产生对应关系就可以了,不需要按照序号进行排序,所以只要HashMap就可以了
    //由于在静态代码块中需要用到这个集合,因此集合前面需要加上static
    static HashMap<Integer, String> hm = new HashMap<>();
    static ArrayList<Integer> list = new ArrayList<>();

    static {
        String[] color = {"♦", "♣", "♥", "♠"};
        String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

        //序号
        int serialNumber = 1;
        
        for (String c : color) {
            //依次表示每一个数字
            for (String n : number) {
                //依次表示每一个花色
                hm.put(serialNumber, c + n);
                list.add(serialNumber);
                serialNumber++;
            }
        }

        hm.put(serialNumber, "小王");
        list.add(serialNumber);
        serialNumber++;
        hm.put(serialNumber, "大王");
        list.add(serialNumber);
    }
}

如果跟之前一样,外层循环是花色,内存循环是数字,那么打印结果如下。

思考一下这里面的规律,例如玩家1被分到的序号是:1 2 3 4 5 14,通过这个序号,去查到对应的牌,真的就有序了吗?

{1=3, 2=4, 3=5, 4=6, 5=7, 6=8, 7=9, 8=10, 9=J, 10=Q, 11=K, 12=A, 13=2, 
 14=3, 15=4, 16=5, 17=6, 18=7, 19=8, 20=9, 21=10, 22=J, 23=Q, 24=K, 25=A, 26=2, 
 27=3, 28=4, 29=5, 30=6, 31=7, 32=8, 33=9, 34=10, 35=J, 36=Q, 37=K, 38=A, 39=2, 
 40=3, 41=4, 42=5, 43=6, 44=7, 45=8, 46=9, 47=10, 48=J, 49=Q, 50=K, 51=A, 52=2, 
 53=小王, 54=大王}

可以发现并不是,因此这种规则其实是不对的。

解决办法:只需要将循环的内外层对调一下就行了

//细节
for (String c : color) {
    //依次表示每一个数字
    for (String n : number) {
        //依次表示每一个花色
        hm.put(serialNumber, c + n);
        System.out.println(c + n);
        list.add(serialNumber);
        serialNumber++;
    }
}

三、洗牌

此时真正洗的应该是牌的序号

public PokerGame() {
    //洗牌
    Collections.shuffle(list);
}

四、发牌

发牌我们发的其实也是序号。

在之前我们使用的是 ArrayList,但是这里可以使用 TreeSet 进行改进,因为 TreeSet 是支持排序的。

当我们将序号加入到 TreeSet 后,就会按照默认的方式进行排序,Integer 中默认的排序方式就是从小到大排列。

public PokerGame() {
    //发牌
    TreeSet<Integer> lord = new TreeSet<>();
    TreeSet<Integer> player1 = new TreeSet<>();
    TreeSet<Integer> player2 = new TreeSet<>();
    TreeSet<Integer> player3 = new TreeSet<>();

    for (int i = 0; i < list.size(); i++) {
        //i :依次表示集合中的每一个索引
        //list.get(i)元素:牌的序号
        int serialNumber = list.get(i);

        if(i <= 2){
            lord.add(serialNumber);
            continue;
        }

        if(i % 3 == 0){
            player1.add(serialNumber);
        }else if(i % 3 == 1){
            player2.add(serialNumber);
        }else{
            player3.add(serialNumber);
        }
    }
}

五、看牌

//看牌
lookPoker("底牌",lord);
lookPoker("钢脑壳",player1);
lookPoker("大帅比",player2);
lookPoker("蛋筒",player3);

/*
    * 参数一:玩家的名字
    * 参数二:牌的序号
    * */
public void lookPoker(String name, TreeSet<Integer> ts){
    System.out.print(name + ": ");
    //遍历TreeSet集合得到每一个序号,再拿着序号到Map集合中去找真正的牌
    for (int serialNumber : ts) {
        String poker = hm.get(serialNumber);
        System.out.print(poker + " ");
    }
    System.out.println();
}
}

六、完整代码

package com.itheima.doudizhu2;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.TreeSet;

public class PokerGame {

    //牌盒 Map
    //此时我们只要把牌跟序号产生对应关系就可以了,不需要按照序号进行排序,所以只要HashMap就可以了
    static HashMap<Integer, String> hm = new HashMap<>();
    static ArrayList<Integer> list = new ArrayList<>();


    static {
        String[] color = {"♦", "♣", "♥", "♠"};
        String[] number = {"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A", "2"};

        //序号
        int serialNumber = 1;
        //细节
        for (String c : color) {
            //依次表示每一个数字
            for (String n : number) {
                //依次表示每一个花色
                hm.put(serialNumber, c + n);
                System.out.println(c + n);
                list.add(serialNumber);
                serialNumber++;
            }
        }

        hm.put(serialNumber, "小王");
        list.add(serialNumber);
        serialNumber++;
        hm.put(serialNumber, "大王");
        list.add(serialNumber);

        System.out.println(hm);
    }


    public PokerGame() {
        //洗牌
        Collections.shuffle(list);

        //发牌
        TreeSet<Integer> lord = new TreeSet<>();
        TreeSet<Integer> player1 = new TreeSet<>();
        TreeSet<Integer> player2 = new TreeSet<>();
        TreeSet<Integer> player3 = new TreeSet<>();

        for (int i = 0; i < list.size(); i++) {
            //i :依次表示集合中的每一个索引
            //list.get(i)元素:牌的序号
            int serialNumber = list.get(i);

            if(i <= 2){
                lord.add(serialNumber);
                continue;
            }

            if(i % 3 == 0){
                player1.add(serialNumber);
            }else if(i % 3 == 1){
                player2.add(serialNumber);
            }else{
                player3.add(serialNumber);
            }
        }


        //看牌
        lookPoker("底牌",lord);
        lookPoker("钢脑壳",player1);
        lookPoker("大帅比",player2);
        lookPoker("蛋筒",player3);
    }

    /*
    * 参数一:玩家的名字
    * 参数二:牌的序号
    * */
    public void lookPoker(String name, TreeSet<Integer> ts){
        System.out.print(name + ": ");
        //遍历TreeSet集合得到每一个序号,再拿着序号到Map集合中去找真正的牌
        for (int serialNumber : ts) {
            String poker = hm.get(serialNumber);
            System.out.print(poker + " ");
        }
        System.out.println();
    }
}
  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值