相信大家都打过扑克牌吧,每当亲朋好友相聚一堂的时候,总少不了这一个娱乐环节,斗地主,跑得快等玩法层出不穷,同时在手机上也出现了不少的扑克牌娱乐的软件;
在我们准备打牌的时候,我们会先拿出一副牌,进行简单的洗牌之后,每人再依次摸牌
当我们在线下或线上进行扑克牌活动时,不知道大家有没有想过,我们该如何用编程来实现洗牌发牌的这一过程呢???
这就是接下来我要讲解的洗牌算法;
(ps: 以下的扑克牌大小用1 ~ 13代替,并且没有大小王,所以一共只有52张牌!!!)
首先,要想打牌,我们得要有扑克牌,再想办法用多张扑克牌凑齐一整副扑克牌,那我们现在开始来创建扑克牌类:
一张扑克牌,有最主要的两个部分组成,一个是花色,一个是牌的大小;
不妨我们创建一个Card类,成员为rank 和suit:
在这里,我还重写了toString方法,方便之后的扑克牌的打印;
public class Card {
int rank; //扑克牌的面值大小
String suit; //扑克牌的花色
//重写toString方法,方便之后的扑克牌的打印
@Override
public String toString() {
return "[ " + suit + rank + " ]";
}
}
以上就是扑克牌的创建;
我们现在有了扑克牌的类,就该来创建一整副扑克牌了:
我们不妨写一个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; //返回扑克牌的牌堆
}
以上就是扑克牌堆的创建了;
要想对扑克牌进行洗牌操作,首先我们就要有一个如何去洗牌的思路,在这里,我的思路是:
我们不妨将牌堆顶部的牌认为是牌堆的最后一张牌,将原本有顺序的牌堆顶部的牌与所有牌中的任意一张进行交换
那我们首先写一个交换方法,命名为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的牌
}
}
写到这里,我们的洗牌算法算是基本上完成了,接下来我们要对该算法进行简单的测试:
测试的过程比较简单,我就不做过多的讲解了,接下来我会将测试的代码放在下面:
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));
}
}
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谢谢!!!!! 如果有什么疑问或者错误,欢迎大家在评论区指出,我会尽快回复,谢谢大家观看!!! 命运只负责洗牌,出牌的永远都是自己!!!