隨機數在撲克牌洗牌和抽卡中的應用
阿新 • • 發佈:2021-10-28
Random模組可生成偽隨機數,隨機數的使用情況分為兩種:放回抽樣和不放回抽樣。最簡單的擲骰子可用new Random().nextInt(點數)實現,這裡我們討論其他的使用場景。
撲克牌洗牌
這是典型的不放回抽樣。
import java.util.Random; public class Shuffle { public static void main(String[] args) { Shuffle sf = new Shuffle(); int[] cards = new int[54]; //4*13+2 String[] colors = {"紅桃","方塊","黑桃","梅花"}; char[] special = {'J','Q','K'}; for(int i=0;i<54;i++) cards[i]=i; //初始化 Random rand = new Random(); int pos=53; //標記切牌位置 System.out.println("開始發牌:"); for(int i=0;i<54;i++) { int r = rand.nextInt(pos+1),n = cards[r]; if(n==52) System.out.print("小王"+"\t"); else if(n==53) System.out.print("大王"+"\t"); else { if(n%13>9) System.out.print(colors[n/13]+special[n%13-10]+"\t"); else if(n%13==0) System.out.print(colors[n/13]+"A\t"); else System.out.print(colors[n/13]+(n%13+1)+"\t"); } sf.swap(cards,r,pos);pos--; //關鍵步驟,交換 if((i+1)%4==0) System.out.println(); } } public void swap(int[] cards,int r,int pos) { int temp = cards[r]; cards[r] = cards[pos]; cards[pos] = temp; } }
執行結果
開始發牌:
方塊9 方塊Q 黑桃10 小王
黑桃2 黑桃8 黑桃4 黑桃Q
梅花Q 紅桃7 梅花K 紅桃9
梅花A 黑桃J 梅花J 方塊K
梅花8 黑桃5 紅桃2 紅桃5
方塊2 方塊10 紅桃3 大王
方塊3 紅桃8 方塊5 紅桃4
紅桃K 紅桃6 方塊A 梅花4
黑桃6 方塊6 梅花6 紅桃10
方塊J 梅花3 方塊7 黑桃K
梅花7 紅桃J 紅桃Q 黑桃A
黑桃3 梅花10 黑桃7 方塊8
黑桃9 梅花2 梅花9 方塊4
梅花5 紅桃A
隨機抽卡(抽獎)
遊戲中的抽卡是放回抽樣,但是概率不等,重點是卡池引數的設定。一般會設定一個保底機制,60抽必出SSR。
import java.util.Random; import java.util.Scanner; public class Shuffle { //設計一個概率不等的隨機抽卡 private int cur=0,max=60; @SuppressWarnings("resource") public void draw() { Scanner sc = new Scanner(System.in); Random rand = new Random(); String[] list = {"SSR-A","SSR-B","SSR-C","SR-A","SR-B","SR-C","SR-D","SR-E", "SR-F","SR-G","R-A","R-B","R-C","R-D","R-E","R-F","R-G","R-H", "R-I","R-J"}; int[] record = new int[3],count = new int[list.length]; System.out.print("輸入抽卡次數:"); int cont=sc.nextInt(),sss=3,ss=7,s=10,sum=list.length; //抽卡次數和卡池引數,應滿足sss+ss+s=sum for(int i=0;i<cont;i++) { int num = rand.nextInt(sum); if(num < sss+ss) { if(rand.nextInt(10)<6) { if(num < sss) num = rand.nextInt(9)<2?num:sss+rand.nextInt(ss); } else num = sss+ss+rand.nextInt(s); } cur++; if(num < sss) cur=0; else if(cur == max) { num = rand.nextInt(sss); //max抽必中ssr cur=0; } count[num]++; if(num<sss) { record[0]++; //System.out.println("SSR "+list[num]); }else if(num<sss+ss) { record[1]++; //System.out.println("SR "+list[num]); }else { record[2]++; //System.out.println("R "+list[num]); } } for(int i=0;i<count.length;i++) System.out.println(list[i]+" : "+count[i]); System.out.printf("ssr: %.2f%%\n",record[0]*100.0/(float)cont); System.out.printf("sr: %.2f%%\n",record[1]*100.0/(float)cont); System.out.printf("r: %.2f%%\n",record[2]*100.0/(float)cont); } public static void main(String[] args) { Shuffle sf = new Shuffle(); sf.draw(); } }
執行結果
輸入抽卡次數:100
SSR-A : 0
SSR-B : 4
SSR-C : 1
SR-A : 2
SR-B : 3
SR-C : 4
SR-D : 5
SR-E : 5
SR-F : 4
SR-G : 5
R-A : 5
R-B : 7
R-C : 8
R-D : 4
R-E : 5
R-F : 10
R-G : 6
R-H : 9
R-I : 7
R-J : 6
ssr: 5.00%
sr: 28.00%
r: 67.00%
可以線上執行程式碼檢視執行效果:線上編譯