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

Posted 不能再留遗憾了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用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();
    

洗牌

洗牌的操作原理是随机两两扑克牌互换,既然是随机的,我们就需要用到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);
    

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

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

发牌

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

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

模拟斗地主洗牌发牌-JAVA


1.1案例介绍

模拟斗地主洗牌发牌-JAVA_java

按照斗地主的规则,完成洗牌发牌的动作。

具体规则:

1.组装54张扑克牌

2.将54张牌顺序打乱

3.三个玩家参与游戏,三人交替摸牌,,每人17张牌,最后三张留作底牌。

4.查看三人各自手中的牌(按照牌的大小排序)、底牌

手中扑克牌从大到小的摆放顺序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3

1.2案例需求分析

准备牌:

            完成数字与纸牌的映射关系:

            使用双列Map(HashMap)集合,完成一个数字与字符串纸牌的对应关系(相当于一个字典)。

洗牌:

            通过数字完成洗牌发牌

发牌:

         将每个人以及底牌设计为ArrayList<String>,将最后3张牌直接存放于牌底,剩余牌通过对3取模依次发牌。

         存放的过程中要求数字大小与斗地主规则的大小对应。

         将代表不同纸牌的数字分配给不同的玩家与底牌。

看牌:

        通过Map集合找到对应字符展示。

        通过查询纸牌与数字对应关系,由数字转成纸牌字符串再进行展示。

1.3实现代码步骤

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
/*
* 斗地主洗牌发牌顺序
*/
public class Poker
public static void main(String[] args)
//准备花色
ArrayList<String> color=new ArrayList<String>();
color.add("♠");
color.add("♥");
color.add("♦");
color.add("♣");
//准备数字
ArrayList<String> number=new ArrayList<String>();
Collections.addAll(number, "3","4","5","6","7","8","9","10","J","Q","K","A","2");
//定义一个map集合,用来将数字与每一张牌进行对应
HashMap<Integer, String> map=new HashMap<Integer,String>();

int index =0;
//加入大小王
map.put(index++, "小?");
map.put(index++,"大?");

for (String thisNumber:number)
for (String thisColor:color)
map.put(index++,thisColor+thisNumber);



//一副牌54张的牌ArrayList里边为0-53的数的新牌
ArrayList<Integer> cards=new ArrayList<Integer>();

for (int i =0;i<=53;i++)
cards.add(i);


//洗牌
Collections.shuffle(cards);

//创建三个玩家和底牌
ArrayList<Integer> iPlayer=new ArrayList<Integer>();
ArrayList<Integer> iPlayer2=new ArrayList<Integer>();
ArrayList<Integer> iPlayer3=new ArrayList<Integer>();
ArrayList<Integer> itCards=new ArrayList<Integer>();

//遍历这副洗好的牌,遍历过程中,将牌发到三个玩家和底牌中
for (int i=0;i<cards.size();i++)
if (i>=51)
itCards.add(cards.get(i));
else
if(i%3==0)
iPlayer.add(cards.get(i));
else if(i%3==1)
iPlayer2.add(cards.get(i));
else
iPlayer3.add(cards.get(i));




//对每个人手中的牌排序
Collections.sort(iPlayer);
Collections.sort(iPlayer2);
Collections.sort(iPlayer3);

//对应数字形式的每个人手中的牌,定义字符串形式的牌
ArrayList<String> sPlayer=new ArrayList<String>();
ArrayList<String> sPlayer2=new ArrayList<String>();
ArrayList<String> sPlayer3=new ArrayList<String>();
ArrayList<String> sCards=new ArrayList<String>();

for (Integer key:iPlayer)
sPlayer.add(map.get(key));


for (Integer key:iPlayer2)
sPlayer2.add(map.get(key));

for (Integer key:iPlayer3)
sPlayer3.add(map.get(key));

for (Integer key:itCards)
sCards.add(map.get(key));

//看牌
System.out.println(sPlayer);
System.out.println(sPlayer2);
System.out.println(sPlayer3);
System.out.println(sCards);


 

以上是关于用Java实现简易的洗牌和发牌功能的主要内容,如果未能解决你的问题,请参考以下文章

java语言实现简单的洗牌,发牌

通过Java实现斗地主

Java模拟斗地主发牌和洗牌

java 18 - 12 模拟斗地主洗牌发牌,并对发的牌进行排序

java集合--模拟斗地主发牌洗牌

关于java洗牌发牌小程序