用Java实现简易的洗牌和发牌功能

简介: 在日常生活中,想必大家都玩过或者听过斗地主吧,斗地主大致分为三个过程:洗牌,发牌,玩家按照规则将手中的牌给打完,谁最先打完,谁就获胜。这听起来挺简单的,但是影响你胜利的因素有很多:洗牌,玩家的水平。在赌场中很多人就是在洗牌跟发牌的过程中作弊的,那么我们可不可以用代码来实现洗牌跟发牌的功能来实现相对公平呢?

在日常生活中,想必大家都玩过或者听过斗地主吧,斗地主大致分为三个过程:洗牌,发牌,玩家按照规则将手中的牌给打完,谁最先打完,谁就获胜。这听起来挺简单的,但是影响你胜利的因素有很多:洗牌,玩家的水平。在赌场中很多人就是在洗牌跟发牌的过程中作弊的,那么我们可不可以用代码来实现洗牌跟发牌的功能来实现相对公平呢?


代码思路

要想发牌跟洗牌我们首先需要有扑克牌,每张不同的牌对应不同的花色跟数字,这里就需要我们抽象出一副扑克牌对象,然后进行洗牌,洗牌我们就随机打乱扑克牌的顺序,然后就是发牌,每个人平均分发相同数量的扑克牌。


代码实现

我们在这里创建一个Poker的包用来包装我们跟扑克牌相关的类。在Poker包中创建三个Java文件:Poker文件用来产生扑克牌,包含花色跟点数;Game文件用来实现创建一套扑克牌、洗牌和发牌的功能;而Test文件则是我们用来测试的。


Poker的Java文件抽象出一张扑克牌

package poker;
public class Poker {
//扑克牌的点数
    private int rank;
//扑克牌的花色
    private String suit;
//创建构造方法
    public Poker(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
//以下这些方法我们今天暂时用不上
    public int getRank() {
        return rank;
    }
    public void setRank(int rank) {
        this.rank = rank;
    }
    public String getSuit() {
        return suit;
    }
//重写toString方法
    @Override
    public String toString() {
        return "{ "+rank+" "+suit+"}";
    }
}

Game的Java文件实现洗牌跟发牌功能


创建存放花色的字符串数组的成员变量


这些花色不能被更改,并且仅在当前类中可以使用,所以我们直接用

private static final修饰保证安全性。

private static final String[] suit = {"♥","♣","♦","♠"};

创建一副扑克牌

扑克牌我们用数组来存放

public List<Poker> buyPoker() {
        List<Poker> pokers = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <=13 ; j++) {
                Poker poker = new Poker(j,suit[i]);
                pokers.add(poker);
            }
        }
        return pokers;
    }

用Test来看是否创建成功,我们在写代码的时候要养成边写边测试的习惯,这样能及时发现错误。

public class Test {
    public static void main(String[] args) {
        Game game = new Game();
        List<Poker> poker = game.buyPoker();
    }
}

image.png


洗牌

洗牌的操作原理是随机两两扑克牌互换,既然是随机的,我们就需要用到Random来产生随机数,我们从数组的后面开始与前面随机位置对应的数互换,因为这样我们容易产生随机数。

  public void shuffle(List<Poker> poker) {
        for (int i = poker.size()-1; i > 0 ; i--) {
            Random random = new Random();
            int index = random.nextInt(i);
            swap(poker,i,index);
        }
    }
//创建私有方法来实现交换
  private void swap(List<Poker> pokers,int i,int j) {
        Poker tmp = pokers.get(i);
        pokers.set(i,pokers.get(j));
        pokers.set(j,tmp);
    }

同样,我们进行一下测试。

image.png

我们可以看到:我们的洗牌功能已经实现了,每次生成的扑克牌的顺序都是不一样的。


发牌

这里我们创建一个二维数组,分别存放三个玩家所分得的手牌。

public List<List<Poker>> game(List<Poker> pokers) {
        List<List<Poker>> hand = new ArrayList<>();
        List<Poker> hand1 = new ArrayList<>();
        List<Poker> hand2 = new ArrayList<>();
        List<Poker> hand3 = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);
        for (int i = 0; i < 3; i++) {
        //我们这里测试每人分发五张
            for (int j = 0; j < 5; j++) {
//我们默认每次从下标为0的位置分发,并且分发一次就移除这个下表为0的扑克牌,
//移除之后,它后面的数字也会自动补齐到0位置
                Poker tmp = pokers.remove(0);
                hand.get(i).add(tmp);
            }
        }
        return hand;
    }

整体功能实现


Poker.java

public class Poker {
    private int rank;
    private String suit;
    public Poker(int rank, String suit) {
        this.rank = rank;
        this.suit = suit;
    }
    public int getRank() {
        return rank;
    }
    public void setRank(int rank) {
        this.rank = rank;
    }
    public String getSuit() {
        return suit;
    }
    @Override
    public String toString() {
        return "{ "+rank+" "+suit+"}";
    }
}

Game.java

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Game {
    private static final String[] suit = {"♥","♣","♦","♠"};
    public List<Poker> buyPoker() {
        List<Poker> pokers = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <=13 ; j++) {
                Poker poker = new Poker(j,suit[i]);
                pokers.add(poker);
            }
        }
        return pokers;
    }
    //洗牌
    public void shuffle(List<Poker> poker) {
        for (int i = poker.size()-1; i > 0 ; i--) {
            Random random = new Random();
            int index = random.nextInt(i);
            swap(poker,i,index);
        }
    }
    private void swap(List<Poker> pokers,int i,int j) {
        Poker tmp = pokers.get(i);
        pokers.set(i,pokers.get(j));
        pokers.set(j,tmp);
    }
    public List<List<Poker>> game(List<Poker> pokers) {
        List<List<Poker>> hand = new ArrayList<>();
        List<Poker> hand1 = new ArrayList<>();
        List<Poker> hand2 = new ArrayList<>();
        List<Poker> hand3 = new ArrayList<>();
        hand.add(hand1);
        hand.add(hand2);
        hand.add(hand3);
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 5; j++) {
                Poker tmp = pokers.remove(0);
                hand.get(i).add(tmp);
            }
        }
        return hand;
    }
}

Test.java

public class Test {
    public static void main(String[] args) {
        Game game = new Game();
        List<Poker> poker = game.buyPoker();
        System.out.println(poker);
        game.shuffle(poker);
        System.out.println(poker);
        List<List<Poker>> hand = game.game(poker);
        for (int i = 0; i < hand.size(); i++) {
            System.out.println("第"+(i+1)+"个人的牌"+hand.get(i));
        }
        System.out.println("剩下的牌");
        System.out.println(poker);
    }
}

40.png

相关文章
|
18天前
|
安全 Java 测试技术
🎉Java零基础:全面解析枚举的强大功能
【10月更文挑战第19天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
101 60
|
6天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
14 2
|
4月前
|
Java 索引
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
|
29天前
|
Java 程序员
在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。
【10月更文挑战第13天】在Java编程中,关键字不仅是简单的词汇,更是赋予代码强大功能的“魔法咒语”。本文介绍了Java关键字的基本概念及其重要性,并通过定义类和对象、控制流程、访问修饰符等示例,展示了关键字的实际应用。掌握这些关键字,是成为优秀Java程序员的基础。
23 3
|
28天前
|
Java 数据安全/隐私保护
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
|
1月前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
58 2
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
|
1月前
|
机器学习/深度学习 算法 Java
通过 Java Vector API 利用 SIMD 的强大功能
通过 Java Vector API 利用 SIMD 的强大功能
40 10
|
1月前
|
Oracle 安全 Java
Java 22 为开发人员带来了重大增强功能
Java 22 为开发人员带来了重大增强功能
37 9
|
1月前
|
Java
让星星⭐月亮告诉你,jdk1.8 Java函数式编程示例:Lambda函数/方法引用/4种内建函数式接口(功能性-/消费型/供给型/断言型)
本示例展示了Java中函数式接口的使用,包括自定义和内置的函数式接口。通过方法引用,实现对字符串操作如转换大写、数值转换等,并演示了Function、Consumer、Supplier及Predicate四种主要内置函数式接口的应用。
25 1
|
3月前
|
Java 开发者
Java多线程教程:使用ReentrantLock实现高级锁功能
Java多线程教程:使用ReentrantLock实现高级锁功能
42 1