大家伙平时都玩惯了纸质版的扑克牌,那你有没有想过去用代码去玩转扑克。
首先,一副扑克牌去掉大小王由52张牌组成,而每张牌都有花色和它对应的数值
在这里将会进行以下几个步骤:
-买牌:我们将会买一副牌,也就是52张牌,每张牌都会有对应的数值和其花色
-洗牌:也就是刚刚买到一副牌,要对其进行打乱操作
-发牌:为了简单,这里将会有三个人,每个人会发五张牌
1.我们知道每张牌都有其对应的花色和数值,那么我们需要定义一个类来定义其属性
class Card{
public String suit;//花色,花色有【"♥","♠","♣","♦"】
public int rank;//牌的数值,【1-13】
//并提供其构造方法
public Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
2.买牌操作
2.1花色与数值的关系
2.2代码实现
//牌52:1 2 3 4 5 6 7 8 9 10 11 12 13
//花色:"♥","♠","♣","♦"
public class TestDemo4 {
public static final String[] suits = {"♥","♠","♣","♦"};//定义牌的花色,因为花色是不变额
public static List<Card> buyCard(){
List<Card> list = new ArrayList<>();//存放牌,买的牌存放在list
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= 13; j++) {
String suit = suits[i];//0->♥,1->♠,2->♣,3->♦
int rank = j;//1-13
Card card = new Card(suit,rank);
list.add(card);//将买的牌放在list当中
}
}
return list;
}
效果1,如果出现了这种情况,是因为你没有重写toString方法
效果2,加上我们重写的toString
之后,我们就可以看到,我们的牌已经买回来了
3.买回来了之后当然不能直接使用,那么每个人手上的牌都是一样的了,使用进行洗牌操作,那么是怎么洗的呢?
3.1如果进行洗牌
简单说明:我们现在一共有52张牌,现在是放在数组里面的,也就是最后一张牌的下标为51,那么我们从最后一张牌也就是51号下标开始,产生在0到51张牌(不包括地51张牌)下标的随机数,然后再将地51张牌和产生随机数的下标的那张牌进行交换,如图
3.2洗牌代码实现(注:注意每一步里面都有备注)
//洗牌
public static void shuffleCard(List<Card> list){ //买回来的牌存放在list当中,就直接传入list
Random random = new Random();
/*
注意:这里的i=list.size-1,最后一张牌开始遍历的,
虽然有52张牌,然是在数组中它的下标是51,这是一个容易犯错的地方
*/
for (int i = list.size()-1; i > 0 ; i--) {
int index = random.nextInt(i);//产生随机数[0,51)
swap(list,index,i);
}
}
我们来看看效果
很明显可以看出牌的顺序已经发生了变化,而且是没有规律的,那说明我们洗牌成功
3.3这里要特别注意洗牌中的交换操作——swap()操作
/**
*这里有一个犯错的点,我们以前在发生两个数值交换的时候总是定义一个临时变量
* 如交换整型的a和b {int x = a,a = b,b = x};
* 而在这里是面向对象,是方法,使用我们应该调用方法来实现交换操作
* 也就是使用list中的set方法,
*/
private static void swap(List<Card> list,int index,int i){
Card tmp = list.get(index);//先保存index下标所对应的值
list.set(index,list.get(i));//然后使用set方法将index位置的值修改为i下标的值
list.set(i,tmp);//然后将i下标的值修改为保存在index位置的值也即tmp
}
4.已经完成买完牌和洗牌操作,那我们就来发牌
方法说明:现在有三个人,每个人将会得到五张牌(当然具体几张根据需要决定,这里只是简单说明),三个人将会按照顺序一次从牌堆顶揭牌,直至每个人手上揭够五张
具体实现:我们现在将洗好的牌放在list当中,那第一个就是从0
号位置揭牌,然后我们将0号位置的牌删除,那么剩下的牌的堆顶元素的下别又变成了0号下标,那么下一个人也将会从0号下标揭牌,一次类推,每个人都是从0号下标拿牌,具体看代码
如图所示
揭牌代码
/**
* 揭牌操作
* hands1 hands2 hands3 分别代表三个人,然后每个人揭的牌将会放入他们里面
* 我们将三个人揭的牌放在lists中
*/
List<List<Card>> lists = new ArrayList<>();
List<Card> hands1 = new ArrayList<>();
List<Card> hands2 = new ArrayList<>();
List<Card> hands3 = new ArrayList<>();
lists.add(hands1);
lists.add(hands2);
lists.add(hands3);
for (int i = 0; i < 5; i++) { //每个人揭五张牌
for (int j = 0; j < 3; j++) { //一共有三个人
lists.get(j).add(ret.remove(0));
}
}
System.out.println("===========================");
System.out.println("第一个人揭的牌");
System.out.println(lists.get(0));
System.out.println("第二个人揭的牌");
System.out.println(lists.get(1));
System.out.println("第三个人揭的牌");
System.out.println(lists.get(2));
System.out.println("剩下的牌"+"\n"+ret);
效果
完整代码
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class Card{
public String suit;//花色,花色有【"♥","♠","♣","♦"】
public int rank;//牌的数值,【1-13】
//并提供其构造方法
public Card(String suit, int rank) {
this.suit = suit;
this.rank = rank;
}
@Override
public String toString() {
return String.format("%s %d",suit,rank);
}
}
//牌52:1 2 3 4 5 6 7 8 9 10 11 12 13
//花色:"♥","♠","♣","♦"
public class TestDemo4 {
public static final String[] suits = {"♥","♠","♣","♦"};//定义牌的花色,因为花色是不变额
public static List<Card> buyCard(){
List<Card> list = new ArrayList<>();//存放牌,买的牌存放在list
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= 13; j++) {
String suit = suits[i];//0->♥,1->♠,2->♣,3->♦
int rank = j;//1-13
Card card = new Card(suit,rank);
list.add(card);//将买的牌放在list当中
}
}
return list;
}
/**
*这里有一个犯错的点,我们以前在发生两个数值交换的时候总是定义一个临时变量
* 如交换整型的a和b {int x = a,a = b,b = x};
* 而在这里是面向对象,是方法,使用我们应该调用方法来实现交换操作
* 也就是使用list中的set方法,
*/
private static void swap(List<Card> list,int index,int i){
Card tmp = list.get(index);//先保存index下标所对应的值
list.set(index,list.get(i));//然后使用set方法将index位置的值修改为i下标的值
list.set(i,tmp);//然后将i下标的值修改为保存在index位置的值也即tmp
}
//洗牌
public static void shuffleCard(List<Card> list){ //买回来的牌存放在list当中,就直接传入list
Random random = new Random();
/*
注意:这里的i=list.size-1,最后一张牌开始遍历的,
虽然有52张牌,然是在数组中它的下标是51,这是一个容易犯错的地方
*/
for (int i = list.size()-1; i > 0 ; i--) {
int index = random.nextInt(i);//产生随机数[0,51)
swap(list,index,i);
}
}
public static void main(String[] args) {
List<Card> ret = buyCard();
System.out.println("这是买回来的牌"+"\n"+ret);
shuffleCard(ret);
System.out.println("洗完之后的牌"+"\n"+ret);
/**
* 揭牌操作
* hands1 hands2 hands3 分别代表三个人,然后每个人揭的牌将会放入他们里面
* 我们将三个人揭的牌放在lists中
*/
List<List<Card>> lists = new ArrayList<>();
List<Card> hands1 = new ArrayList<>();
List<Card> hands2 = new ArrayList<>();
List<Card> hands3 = new ArrayList<>();
lists.add(hands1);
lists.add(hands2);
lists.add(hands3);
for (int i = 0; i < 5; i++) { //每个人揭五张牌
for (int j = 0; j < 3; j++) { //一共有三个人
lists.get(j).add(ret.remove(0));
}
}
System.out.println("===========================");
System.out.println("第一个人揭的牌");
System.out.println(lists.get(0));
System.out.println("第二个人揭的牌");
System.out.println(lists.get(1));
System.out.println("第三个人揭的牌");
System.out.println(lists.get(2));
System.out.println("剩下的牌"+"\n"+ret);
}
}