SCAU 发牌程序(java)
发牌程序
思路
- 用数字代表扑克牌,例如 0-黑桃A 12-黑桃K 13-红心A
- pokeNum-扑克牌副数 , playerNum-人数
- 先初始化一个 52*扑克牌副数 的一维数组cards来存放扑克牌,让数组每个元素的值等于它的下标index(现在我们拥有了一个存放了0~51的数组,每个数字对应一张扑克牌)。
- 然后洗牌,即将cards里面的元素打乱,这里使用学JavaScript的时候看到的一个随机排列数组的算法 Fisher-Yates shuffle。详述见下文。
- 最后分牌,只需要尽量平均地将已经打乱的数组分为 playerNum 组即可(即前几个数组元素代表的牌给第一个人,中间的给第二个人……)。
初始化 initCards()
public void initCards() {
for(int i = 0 ; i < 52 * pokeNum ; i++) {
cards[i] = i;
}
洗牌 cardShuffle()
Fisher-Yates shuffle
核心思想:逆向遍历数组,并将每个元素与其前面的随机的一个元素互换位置。
从后往前遍历数组元素,假设当前元素下标为i(0<i<扑克牌的总数-1)(因为扑克牌是从0开始表示的) ,则用Random对象随机生成一个(0~i)的数 j,然后将当前数组元素cards[i] 与下标为j的元素 cards[j] 交换。
public void cardShuffle() {
Random rand = new Random();
for(int i = 52 * pokeNum - 1 ; i >= 1 ; i--) {
//生成随机数
int index = rand.nextInt(i);
//交换
int temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
}
分牌 dealCards()
平均分配
参考:https://www.cnblogs.com/sinpo828/p/14264518.html
感觉很神奇:D
用数组存储每一种花色的牌
对于每一个人,初始化一个二维数组int [][] c,用来存放各种花色的牌的数字
通过 cards[i] % 52 / 13 得到花色type(取值为0、1、2、3)
将花色作为行的索引,用另一个数组存储该花色目前牌的数目j[type],存储相应的牌: c[type][ j[type]++ ]=cards[i]
输出
可以用type作为字符串数组的下标获取相应花色的字符串。
通过 cards[i] % 52 % 13 可以得到牌面的值,获取对应字符串方式同上。
/* 类中变量
private String huaSe[] = {"黑桃","红心","草花","方块"};
private String cardValue[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
*/
public void dealCards() {
for (int i = 0 ; i < playerNum ; i++)
{
int [][]c = new int [4][pokeNum*13];
int []j = new int [4];
int min = pokeNum * 52 * i / playerNum;
int max = (pokeNum * 52 * (i + 1)) / playerNum;
for (int k = min; k < max; k++) {
int type = cards[k] % 52 / 13;
c[type][j[type]++] = cards[k];
//System.out.println("c["+type+"]["+(j[type]-1)+"]="+c[type][j[type]-1]+" ");
}
System.out.println("第" + (i + 1) + "个人:");
for(int p = 0 ; p < 4 ; p++) {
System.out.print(huaSe[p] + ":");
for(int q = 0 ; q < j[p] ; q++) {
System.out.print(cardValue[(c[p][q] % 52) % 13] + " ");
}
System.out.println();
}
}
}
代码
/**
* @author CSDN-孜然の夏天
* @id 202025310407
* @date 2021年9月24日
*/
import java.util.Random;
import java.util.Scanner;
public class PokerGame{
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("输入扑克牌幅数:");
int pokeNum = input.nextInt();
System.out.print("输入人数:");
int playerNum = input.nextInt();
Cards c = new Cards(pokeNum,playerNum);
//初始化牌组
c.initCards();
//洗牌
c.cardShuffle();
//分牌
System.out.println("输出如下:");
c.dealCards();
}
}
class Cards{
private int []cards;
public int pokeNum;
public int playerNum;
private String huaSe[] = {"黑桃","红心","草花","方块"};
private String cardValue[] = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
public Cards(int pokeNum , int playerNum){
this.pokeNum = pokeNum;
this.playerNum = playerNum;
cards = new int[(52 * pokeNum) + 1];
}
public void initCards() {
for(int i = 0 ; i < 52 * pokeNum ; i++) {
cards[i] = i;
}
/*for(int i = 0;i<52*pokeNum;i++) {
System.out.println(i+":"+cards[i]+" 数字:"+(cards[i]%52)+" 牌面:"+cardValue[(cards[i]%52)%13]+" 花色:"+(cards[i]%52)/13);}
*/
}
public void cardShuffle() {
Random rand = new Random();
for(int i = 52 * pokeNum - 1 ; i >= 1 ; i--) {
int index = rand.nextInt(i);
int temp = cards[index];
cards[index] = cards[i];
cards[i] = temp;
}
/*for(int i = 0;i<52*pokeNum;i++) {
System.out.println(i+":"+cards[i]+" 数字:"+(cards[i]%52)+" 牌面:"+cardValue[(cards[i]%52)%13]+" 所属玩家:"+(i/perNum+1)+" 花色:"+(cards[i]%52)/13);}
*/
}
public void dealCards() {
for (int i = 0 ; i < playerNum ; i++)
{
int [][]c = new int [4][pokeNum*13];
int []j = new int [4];
int min = pokeNum * 52 * i / playerNum;
int max = (pokeNum * 52 * (i + 1)) / playerNum;
for (int k = min; k < max; k++) {
int type = cards[k] % 52 / 13;
c[type][j[type]++] = cards[k];
//System.out.println("c["+type+"]["+(j[type]-1)+"]="+c[type][j[type]-1]+" ");
}
System.out.println("第" + (i + 1) + "个人:");
for(int p = 0 ; p < 4 ; p++) {
System.out.print(huaSe[p] + ":");
for(int q = 0 ; q < j[p] ; q++) {
System.out.print(cardValue[(c[p][q] % 52) % 13] + " ");
}
System.out.println();
}
}
}
}