前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于ArrayList实现的简单的 <洗牌算法>

基于ArrayList实现的简单的 <洗牌算法>

作者头像
AUGENSTERN_
发布2024-04-09 20:41:01
1130
发布2024-04-09 20:41:01
举报
文章被收录于专栏:畅游IT畅游IT

1. 前言:

相信大家都打过扑克牌吧,每当亲朋好友相聚一堂的时候,总少不了这一个娱乐环节,斗地主,跑得快等玩法层出不穷,同时在手机上也出现了不少的扑克牌娱乐的软件;

在我们准备打牌的时候,我们会先拿出一副牌,进行简单的洗牌之后,每人再依次摸牌

当我们在线下或线上进行扑克牌活动时,不知道大家有没有想过,我们该如何用编程来实现洗牌发牌的这一过程呢???

这就是接下来我要讲解的洗牌算法

(ps: 以下的扑克牌大小用1 ~ 13代替,并且没有大小王,所以一共只有52张牌!!!)

2 洗牌算法:

2.1 扑克牌类的创建:

首先,要想打牌,我们得要有扑克牌,再想办法用多张扑克牌凑齐一整副扑克牌,那我们现在开始来创建扑克牌类:

一张扑克牌,有最主要的两个部分组成,一个是花色,一个是牌的大小;

不妨我们创建一个Card类,成员为rank 和suit:

在这里,我还重写了toString方法,方便之后的扑克牌的打印;

代码语言:javascript
复制
public class Card {

    int rank;   //扑克牌的面值大小

    String suit;   //扑克牌的花色

    //重写toString方法,方便之后的扑克牌的打印
    @Override
    public String toString() {
        return "[ " + suit + rank + " ]";
    }
}

以上就是扑克牌的创建;

2.2 一整副扑克牌的创建:

我们现在有了扑克牌的类,就该来创建一整副扑克牌了:

我们不妨写一个CardDemo类,来表示一整副扑克牌;

代码语言:javascript
复制
public class CardDemo {

    //SUIT用来存放扑克牌的花色
    public static final String[] SUIT = { "♥", "♠", "♦", "♣" };

}

现在这个CardDemo仅仅类似于一个扑克牌的盒子,我现在要往这个盒子里面放入扑克牌;

那我们就需要在这个CardDemo中写一个方法,我命名为buyDeck,代码如下:

代码语言:javascript
复制
//buyDeck表示买一副扑克牌,也就是创建一整副扑克牌
    public static List<Card> buyDeck() {
        //创建一个牌堆,叫deck,用来存放扑克牌
        List<Card> deck = new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {           //一共四种花色
            for (int j = 0; j < 13; j++) {      //扑克牌的大小从 0 ~ 13
                Card card = new Card();         //实例化单张扑克牌对象
                card.rank = j + 1;              //对每张扑克牌的大小进行赋值
                card.suit = SUIT[i];            //对每张扑克牌的花色进行赋值
                deck.add(card);                 //将扑克牌存入牌堆中
            }
        }
        return deck;                            //返回扑克牌的牌堆
    }

以上就是扑克牌堆的创建了;

2.3 对扑克牌进行洗牌操作:

要想对扑克牌进行洗牌操作,首先我们就要有一个如何去洗牌的思路,在这里,我的思路是:

我们不妨将牌堆顶部的牌认为是牌堆的最后一张牌,将原本有顺序的牌堆顶部的牌与所有牌中的任意一张进行交换

那我们首先写一个交换方法,命名为swap,顺便对其进行封装:

代码语言:javascript
复制
private static void swap(List<Card> deck, int i, int j) {
        Card tmp = deck.get(i);         //令tmp = 牌堆中的下标为i的牌
        deck.set(i, deck.get(j));       //交换下标为i的牌和下标为j的牌
        deck.set(j, tmp);
    }

有了交换的方法,那我们开始写洗牌的方法,命名为shuffle:

代码语言:javascript
复制
public static void shuffle(List<Card> deck) {
        Random random = new Random();                   //生成一个随机数
        for (int i = deck.size() - 1; i > 0; i--) {     //对每一张牌都进行一次交换
            int r = random.nextInt(52);          //让r = 0 ~ 52中的任意一个随机数
            swap(deck, i, r);                           //交换下标为r的牌和下标为i的牌
        }
    }

写到这里,我们的洗牌算法算是基本上完成了,接下来我们要对该算法进行简单的测试:

3. 测试:

测试的过程比较简单,我就不做过多的讲解了,接下来我会将测试的代码放在下面:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;

import java.util.Comparator;

public class My_Comparator implements Comparator<Card> {
    @Override
    public int compare(Card o1, Card o2) {              //实现一个比较器,用来比较扑克牌的大小
        return o1.rank - o2.rank;                       //此处是从小到大排序
    }
}


public class Main {
    public static void main(String[] args) {
        List<Card> deck = CardDemo.buyDeck();           //实例化一个牌堆并对其赋值
        System.out.println("初始牌堆:");
        System.out.println(deck);                       //打印初始有序的牌堆
        CardDemo.shuffle(deck);                         //对牌堆进行洗牌
        System.out.println("洗牌后的牌堆:");
        System.out.println(deck);                       //打印洗牌后的无序的牌堆

        List<List<Card>> hands = new ArrayList<>();     //实例化一个总牌库,包括三个人的所有手牌
        hands.add(new ArrayList<>());                   //实例化三个人的牌库
        hands.add(new ArrayList<>());
        hands.add(new ArrayList<>());

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
                hands.get(j).add(deck.removeLast());    //三个人每人一次发一张牌,一共发五次,每人五张牌
            }
        }
        System.out.println("剩余牌堆:");
        System.out.println(deck);                       //打印剩余的牌堆
        hands.get(0).sort(new My_Comparator());         //对三个人的手牌进行排序
        hands.get(1).sort(new My_Comparator());
        hands.get(2).sort(new My_Comparator());
        System.out.println("玩家一的手牌:");
        System.out.println(hands.get(0));               //分别打印三个人的手牌
        System.out.println("玩家二的手牌:");
        System.out.println(hands.get(1));
        System.out.println("玩家三的手牌:");
        System.out.println(hands.get(2));
    }
}

4. 源码分享:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Comparator;

public class My_Comparator implements Comparator<Card> {
    @Override
    public int compare(Card o1, Card o2) {
        return o1.rank - o2.rank;
    }
}


public class Card {

    int rank;   //扑克牌的面值大小

    String suit;   //扑克牌的花色

    //重写toString方法,方便之后的扑克牌的打印
    @Override
    public String toString() {
        return "[" + suit + rank + "]";
    }
}


public class CardDemo {

    //SUIT用来存放扑克牌的花色
    public static final String[] SUIT = { "♥", "♠", "♦", "♣" };

    //buyDeck表示买一副扑克牌,也就是创建一整副扑克牌
    public static List<Card> buyDeck() {
        //创建一个牌堆,叫deck,用来存放扑克牌
        List<Card> deck = new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {           //一共四种花色
            for (int j = 0; j < 13; j++) {      //扑克牌的大小从 0 ~ 13
                Card card = new Card();         //实例化单张扑克牌对象
                card.rank = j + 1;              //对每张扑克牌的大小进行赋值
                card.suit = SUIT[i];            //对每张扑克牌的花色进行赋值
                deck.add(card);                 //将扑克牌存入牌堆中
            }
        }
        return deck;                            //返回扑克牌的牌堆
    }

    private static void swap(List<Card> deck, int i, int j) {
        Card tmp = deck.get(i);         //令tmp = 牌堆中的下标为i的牌
        deck.set(i, deck.get(j));       //交换下标为i的牌和下标为j的牌
        deck.set(j, tmp);
    }

    public static void shuffle(List<Card> deck) {
        Random random = new Random();                   //生成一个随机数
        for (int i = deck.size() - 1; i > 0; i--) {     //对每一张牌都进行一次交换
            int r = random.nextInt(52);          //让r = 0 ~ 52中的任意一个随机数
            swap(deck, i, r);                           //交换下标为r的牌和下标为i的牌
        }
    }
}

public class Main {
    public static void main(String[] args) {
        List<Card> deck = CardDemo.buyDeck();           //实例化一个牌堆并对其赋值
        System.out.println("初始牌堆:");
        System.out.println(deck);                       //打印初始有序的牌堆
        CardDemo.shuffle(deck);                         //对牌堆进行洗牌
        System.out.println("洗牌后的牌堆:");
        System.out.println(deck);                       //打印洗牌后的无序的牌堆

        List<List<Card>> hands = new ArrayList<>();     //实例化一个总牌库,包括三个人的所有手牌
        hands.add(new ArrayList<>());                   //实例化三个人的牌库
        hands.add(new ArrayList<>());
        hands.add(new ArrayList<>());

        for (int i = 0; i < 5; i++) {
            for (int j = 0; j < 3; j++) {
                hands.get(j).add(deck.removeLast());    //三个人每人一次发一张牌,一共发五次,每人五张牌
            }
        }
        System.out.println("剩余牌堆:");
        System.out.println(deck);                       //打印剩余的牌堆
        hands.get(0).sort(new My_Comparator());         //对三个人的手牌进行排序
        hands.get(1).sort(new My_Comparator());
        hands.get(2).sort(new My_Comparator());
        System.out.println("玩家一的手牌:");
        System.out.println(hands.get(0));               //分别打印三个人的手牌
        System.out.println("玩家二的手牌:");
        System.out.println(hands.get(1));
        System.out.println("玩家三的手牌:");
        System.out.println(hands.get(2));
    }
}

以上就是该洗牌算法的全部内容了,希望对大家有所帮助!!!

制作不易,三连支持QAQ 谢谢!!!!! 如果有什么疑问或者错误,欢迎大家在评论区指出,我会尽快回复,谢谢大家观看!!! 命运只负责洗牌,出牌的永远都是自己!!!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言:
  • 2 洗牌算法:
    • 2.1 扑克牌类的创建:
      • 2.2 一整副扑克牌的创建:
        • 2.3 对扑克牌进行洗牌操作:
        • 3. 测试:
        • 4. 源码分享:
        相关产品与服务
        腾讯云服务器利旧
        云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档