Java实现斗地主洗牌发牌功能(不打牌噢)

设计思路

  1. 初始化54张牌
  2. 洗牌
  3. 发牌
  4. 给玩家手牌排序
  5. 展示玩家手牌及3张底牌

实现思路

  • 首先是54张牌要选择一种数据结构存放,这里选择List和Map集合都可以,我这里选择的是Map

    1. 要区分4种花色,则将四种花色存入String数组中,方便后续遍历生成牌池
    2. 因为每种花色的13张牌的顺序并不是严格的按照数字大小排序,所以每张牌的序号需要计算后存起来,与牌面对应,即典型的key-value形式,这是我选择使用Map的原因之一,主要原因还是刚学完Map,想熟练一下(若使用List存放牌池也完全OK,可以使用下标代替key使用)
    3. 考虑到方便后续对牌面进行排序,所以Map中的key存放54张牌排序后的序号,即:大小相同的牌,序号是连续的,比如:大王、小王、红桃2、黑桃2、方块2、梅花2,对应的序号应该是:54,53,52,51,50,49
  • 其次是要有三个玩家,结合面向对象编程思想,需要创建一个玩家类,记录三个玩家的姓名和手牌list

    1. 轮流给3个玩家发牌时,根据对3取余是否为0,对3取余是否为1,对3取余是否为2来判断给哪个玩家发牌,即给哪个玩家的手牌list中添加元素
    2. 因为最后要对玩家手牌排序,所以玩家手牌的list中存放的应该是牌面对应的排序大小,而不是牌面值,即map的key值
    3. Collections工具类中已经提供了对List集合的升序排列,再结合该类的reverse方法,即可实现对手牌list的降序排列

代码实现

玩家类

import java.util.List;

/**
 * @program: 
 * @description: 扑克牌玩家
 * @author: Jack
 * @create: 2020-11-09 21:41
 **/
public class Player {
    private String name;
    private List<Integer> ownPokers;

    public Player() {
    }

    public Player(String name, List<Integer> ownPokers) {
        this.name = name;
        this.ownPokers = ownPokers;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Integer> getOwnPokers() {
        return ownPokers;
    }

    public void setOwnPokers(List<Integer> ownPokers) {
        this.ownPokers = ownPokers;
    }

    @Override
    public String toString() {
        return "玩家[" + name + "]拥有手牌的keys:" + ownPokers;
    }
}

功能实现主类

import java.util.*;

/**
 * @program: 
 * @description:
 * @author: Jack
 * @create: 2020-11-10 14:41
 **/
public class PlayCards {
    public static Map<Integer,String> mapPoker = new HashMap<>();
    private static Player p1 = new Player("廉颇", new ArrayList<>()); //玩家一
    private static Player p2 = new Player("赵云", new ArrayList<>()); //玩家二
    private static Player p3 = new Player("安琪拉", new ArrayList<>()); //玩家三
    private static List<Integer> lastPoker = new ArrayList<>(); //3张底牌
    private static List<Integer> messyList = new ArrayList(); //为实现随机,先声明一个包含1-54,但是随机存放的的list

    public static void main(String[] args) {
        //1、初始化牌库
        initPoker();
        //2、洗牌
        shufflePoker();
        //3、发牌
        givePoker();
        //4、手牌排序
        orderPoker(p1);
        orderPoker(p2);
        orderPoker(p3);
        //5、手牌及底牌打印
        printPlayerPoker(p1);
        printPlayerPoker(p2);
        printPlayerPoker(p3);
        printLastPoker();
    }

    /**
     * 初始化牌库
     */
    public static void initPoker(){
        String[] colors = {"♣","♠","♦","♥"};  //声明4种花色
        String smallJoker = "☪"; //小王
        String bigJoker = "●";  //大王
        mapPoker.put(53, smallJoker); 
        mapPoker.put(54, bigJoker);
        //将52张普通牌初始化到牌池中
        for (int i = 1; i < 14; i++) { //每种花色13张牌,所以遍历13次
            for (int j = 0; j < colors.length; j++) { //4种花色,遍历4次
                //处理顺序特殊的牌面
                if(i == 2){  
                    mapPoker.put(13*4 - j, colors[j] + i);  //因为2是大小王之后的最大牌面,所以序号从小王的序号的下一个数值开始依次递减
                } else if(i == 1) {
                    mapPoker.put(12*4 - j, colors[j] + i); //1是在2之后最大牌面,所以序号从2的最小序号的下一个数值(值等价于12*4-j)开始依次递减
                } else{
                    //将11-12-13转换为英文符号J-Q-K
                    String face = (i == 11) ? "J" : (i == 12) ? "Q" : (i == 13) ? "K" : String.valueOf(i);
                    mapPoker.put((i-2)*4 - j, colors[j] + face); 
                }
            }
        }
        
    }

    /**
     * 洗牌
     */
    public static void shufflePoker(){
        p1.getOwnPokers().clear();
        p2.getOwnPokers().clear();
        p3.getOwnPokers().clear();
        for (int i = 1; i <= 54 ; i++) {
            messyList.add(i);
        }
        Collections.shuffle(messyList); //打乱元素值1-54的位置
    }

    /**
     * 发牌
     */
    public static void givePoker(){
        for (int i = 0; i < 54; i++) { //发牌54次,并且轮流给三个玩家发牌
            if(i > 50){ //最後三张底牌不发
                lastPoker.add(messyList.get(i));
                continue;
            }
            //给p3发牌
            if(i%3 == 0){
                p3.getOwnPokers().add(messyList.get(i));//经过上方的洗牌操作,messyList.get(i)的值不再是有规律的1-54,而是1-54内随机的一个数值,
                //此时将该随机值保存到玩家手牌list中当作该玩家此轮手牌的key,后续打印手牌时再根据这个随机的key取出的牌面也就是随机的了
            }
            //给p2发牌
            else if(i%3 == 1){
                p2.getOwnPokers().add(messyList.get(i));//同上
            }
            //给p1发牌
            else{
                p1.getOwnPokers().add(messyList.get(i));//同上
            }
        }
    }

    /**
     * 打印玩家手牌
     */
    public static void printPlayerPoker(Player player){
        System.out.print("\n玩家" + player.getName() + "手牌:");
        for(Integer key : player.getOwnPokers()){
            System.out.print(mapPoker.get(key) + " ");
        }
    }

    /**
     * 打印底牌
     */
    public static void printLastPoker(){
        System.out.print("\n剩余三张底牌:");
        for(Integer key:lastPoker){
            System.out.print(mapPoker.get(key) + " ");
        }
    }

    /**
     * 手牌排序
     * @param
     */
    public static void orderPoker(Player p){
        Collections.sort(p.getOwnPokers());
        Collections.reverse(p.getOwnPokers());
    }
}

说明:使用List存放牌池相对比Map更简单一些,List的下标可以直接用来当作排序的key使用,按照同样的逻辑将54张牌添加到牌池list中,发牌时根据下标取牌即可







文章内容输出来源:拉勾教育_大数据开发高新训练营第3期第一阶段模块三作业5

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迟到_啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值