隨機數在撲克牌洗牌和抽卡中的應用


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%

 
可以在線運行代碼查看運行效果:在線編譯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM