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

 

🎉欢迎大家观看AUGENSTERN_dc的文章(o゜▽゜)o☆✨✨

🎉感谢各位读者在百忙之中抽出时间来垂阅我的文章,我会尽我所能向的大家分享我的知识和经验📖

🎉希望我们在一篇篇的文章中能够共同进步!!!

🌈个人主页:AUGENSTERN_dc

🔥个人专栏:C语言 | Java | 数据结构

⭐个人格言:

一重山有一重山的错落,我有我的平仄

一笔锋有一笔锋的着墨,我有我的舍得

目录

1. 前言:

2 洗牌算法:

2.1 扑克牌类的创建:

2.2 一整副扑克牌的创建:

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

3. 测试:

4. 源码分享:


1. 前言:

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

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

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

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

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

2 洗牌算法:

2.1 扑克牌类的创建:

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

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

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

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

public class Card {

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

    String suit;   //扑克牌的花色

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

以上就是扑克牌的创建;

2.2 一整副扑克牌的创建:

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

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

public class CardDemo {

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

}

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

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

//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,顺便对其进行封装:

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:

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. 测试:

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

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. 源码分享:

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

谢谢!!!!!

如果有什么疑问或者错误,欢迎大家在评论区指出,我会尽快回复,谢谢大家观看!!!

命运只负责洗牌,出牌的永远都是自己!!!

  • 13
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值