1. 程式人生 > >學以致用——Java原始碼——任意次拋雙骰結果模擬程式(Dice Rolling, updated in 2018)

學以致用——Java原始碼——任意次拋雙骰結果模擬程式(Dice Rolling, updated in 2018)

本程式基於2年前的程式做了以下改進:

1. 2018年12月25日優化:使用陣列元素作為計數器 (而不是用switch...case或if...else進行逐個判斷)

2. 修改了概率計算的一個bug (顯示小數點位數為兩位,只需要格式化輸出即可)

程式碼如下:

package exercises.ch7Arrays;


//Java how to program, 10th/e, Exercise 7.17-Dice Rolling
/**(Dice Rolling) Write an application to simulate the rolling of two dice. The application
should use an object of class Random once to roll the first die and again to roll the second die. The
sum of the two values should then be calculated. Each die can show an integer value from 1 to 6, so
the sum of the values will vary from 2 to 12, with 7 being the most frequent sum, and 2 and 12 the
least frequent. Figure 7.28 shows the 36 possible combinations of the two dice. Your application
should roll the dice 36,000,000 times. Use a one-dimensional array to tally the number of times
each possible sum appears. Display the results in tabular format.*/
import java.util.Scanner;

public class RollingDice2018 {
	
public static int rollDice()
{
 int dice1=(int)(1+Math.random()*6);
 int dice2=(int)(1+Math.random()*6);
 return dice1+dice2;
 }

public static void main(String[] args){
	int size=0;
	Scanner input=new Scanner(System.in);
	
	do{

		System.out.print("請輸入拋雙骰的次數(輸入-1退出):");
		size=input.nextInt();
		if(size==-1){
			System.out.printf("已退出程式");
			break;
		}
			
		int rollingResult=0;
		int[] frequency=new int[13];
		double[] possibility=new double[13];
		double possibilityTotal=0.0;
		double percentTotal=0.0;
		int totalRolling=0;
		
		System.out.println("拋雙骰開始:");
		for (int i=0;i<size;i++){
		   rollingResult=rollDice();
		   ++frequency[rollingResult]; //2018年12月25日優化:使用陣列元素作為計數器
	   }
		System.out.println("拋雙骰結束:");
		
		for (int i=2;i<13;i++){
			possibility[i]=(double)frequency[i]/size;
		}
		
		System.out.printf("已模擬拋雙骰共%d次,統計結果如下:\n",size);
		System.out.println("拋雙骰點數合計\t丟擲次數\t\t所佔百分比:");
		for (int i=2;i<13;i++){
			//百分比取兩位小數推演過程:0.12545->1254.5+0.5=1255/10000=0.1255*100
			System.out.printf("%d\t\t%d\t\t%.2f%%%n",i,frequency[i],(double)(possibility[i]*10000)/100);
			//System.out.print("%"+"\n");
		}
		
		for(double p:possibility){
			possibilityTotal+=p;
			percentTotal+=(p*10000)/100;
		}
		
		for(int f:frequency)
			totalRolling+=f;
			
		System.out.printf("校驗值-丟擲次數合計:%d,概率合計:%.2f,百分比合計:%.2f\n\n\n",totalRolling,possibilityTotal,percentTotal);

	}while(size!=-1);
	
	input.close();
}
}

執行結果:

請輸入拋雙骰的次數(輸入-1退出):10

拋雙骰開始:

拋雙骰結束:

已模擬拋雙骰共10次,統計結果如下:

拋雙骰點數合計                 丟擲次數                              所佔百分比:

2                                              0                                              0.00%

3                                              0                                              0.00%

4                                              0                                              0.00%

5                                              2                                              20.00%

6                                              1                                              10.00%

7                                              1                                              10.00%

8                                              0                                              0.00%

9                                              1                                              10.00%

10                                           5                                              50.00%

11                                           0                                              0.00%

12                                           0                                              0.00%

校驗值-丟擲次數合計:10,概率合計:1.00,百分比合計:100.00

 

 

請輸入拋雙骰的次數(輸入-1退出):1000

拋雙骰開始:

拋雙骰結束:

已模擬拋雙骰共1000次,統計結果如下:

拋雙骰點數合計                 丟擲次數                              所佔百分比:

2                                              23                                           2.30%

3                                              68                                           6.80%

4                                              77                                           7.70%

5                                              106                                         10.60%

6                                              131                                         13.10%

7                                              177                                         17.70%

8                                              128                                         12.80%

9                                              116                                         11.60%

10                                           81                                           8.10%

11                                           71                                           7.10%

12                                           22                                           2.20%

校驗值-丟擲次數合計:1000,概率合計:1.00,百分比合計:100.00

 

 

請輸入拋雙骰的次數(輸入-1退出):10000

拋雙骰開始:

拋雙骰結束:

已模擬拋雙骰共10000次,統計結果如下:

拋雙骰點數合計                 丟擲次數                              所佔百分比:

2                                              263                                         2.63%

3                                              554                                         5.54%

4                                              804                                         8.04%

5                                              1191                                      11.91%

6                                              1399                                      13.99%

7                                              1647                                      16.47%

8                                              1329                                      13.29%

9                                              1128                                      11.28%

10                                           866                                         8.66%

11                                           548                                         5.48%

12                                           271                                         2.71%

校驗值-丟擲次數合計:10000,概率合計:1.00,百分比合計:100.00

 

 

請輸入拋雙骰的次數(輸入-1退出):1000000

拋雙骰開始:

拋雙骰結束:

已模擬拋雙骰共1000000次,統計結果如下:

拋雙骰點數合計                 丟擲次數                              所佔百分比:

2                                              27926                                    2.79%

3                                              55949                                    5.59%

4                                              83441                                    8.34%

5                                              111135                                 11.11%

6                                              138894                                 13.89%

7                                              165858                                 16.59%

8                                              139348                                 13.93%

9                                              110583                                 11.06%

10                                           83645                                    8.36%

11                                           55509                                    5.55%

12                                           27712                                    2.77%

校驗值-丟擲次數合計:1000000,概率合計:1.00,百分比合計:100.00

 

 

請輸入拋雙骰的次數(輸入-1退出):36000000

拋雙骰開始:
拋雙骰結束:
已模擬拋雙骰共36000000次,統計結果如下:
拋雙骰點數合計    丟擲次數        所佔百分比:
2        1000086        2.78%
3        1999219        5.55%
4        3000665        8.34%
5        3994492        11.10%
6        5003550        13.90%
7        6000844        16.67%
8        4996358        13.88%
9        4000238        11.11%
10        3002417        8.34%
11        2001085        5.56%
12        1001046        2.78%
校驗值-丟擲次數合計:36000000,概率合計:1.00,百分比合計:100.00

彩蛋:

這個程式可以用來演示大數定律(Law of Large Number),由程式執行結果來看,當丟擲1000000次後,模擬結果與理論概率高度吻合(這也等於是驗證了程式的準確性)。

參考文章:

1. 學以致用-擲雙骰兒(craps)遊戲的直方圖(概率分佈)資料分析,https://blog.csdn.net/hpdlzu80100/article/details/78920409

2. 經典問題-搖雙色模擬(次數自定義)(Dice Rolling),https://blog.csdn.net/hpdlzu80100/article/details/51852730