1, 1 | 2, 1 | 3, 1 | 4, 1 | 5, 1 | 6, 1 |
1, 2 | 2, 2 | 3, 2 | 4, 2 | 5, 5 | 6, 2 |
1, 3 | 2, 3 | 3, 3 | 4, 3 | 5, 3 | 6, 3 |
1, 4 | 2, 4 | 3, 4 | 4, 4 | 5, 4 | 6, 4 |
1, 5 | 2, 5 | 3, 5 | 4, 5 | 5, 5 | 6, 5 |
1, 6 | 2, 6 | 3, 6 | 4, 6 | 5, 6 | 6, 6 |
平手的情況有 6 種,贏的情況有 0 + 1 + 2 + 3 + 4 + 5 = 15 種,輸的情況也有 15 種,所有的情況有 36 種,因此理論上,平手的機率為 6 / 36 = 0.1667 ,輸與贏的機率相同都是 15 / 36 = 0.4167 。
我們在擲骰子遊戲已經建立了模擬擲骰子的亂數表,現在我們繼續來模擬遊戲的勝負吧!
首先,我們把記錄骰子點數的陣列擴展到 1000 個元素,這也是說我們會模擬 1000 次遊戲的勝負。當然,我們需要加入
#define SIZE 1000 |
這樣宣告陣列就可以直接用 SIZE 代入即可,若是需要更改模擬次數,調整 SIZE 的值就可以了。
另外,我們需要加入以下三個變數的宣告
int counter1 = 0; // 累計 points1 贏的次數 int counter2 = 0; // 累計 points2 贏的次數 int counter3 = 0; // 累計平手的次數 |
這三個變數分別記錄陣列 points1 贏的次數,陣列 points2 贏的次數,以及平手的次數。我們假設 points1 記錄電腦 A 擲出的點數, points2 為電腦 B 擲出的點數,所有的程式碼如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include <stdio.h> #include <stdlib.h> #include <time.h> #define SIZE 1000 int main( void ) { int points1[SIZE]; // 第一組骰子表格 int points2[SIZE]; // 第二組骰子表格 int temp; // 暫存變數 int i; // 迴圈用變數 int counter1 = 0; // 累計 points1 贏的次數 int counter2 = 0; // 累計 points2 贏的次數 int counter3 = 0; // 累計平手的次數 srand ( time (NULL)); // 建立兩組骰子的亂數表 for (i = 0; i < SIZE; i++) { temp = rand () % 6; if (temp == 0) { temp = 6; } points1[i] = temp; temp = rand () % 6; if (temp == 0) { temp = 6; } points2[i] = temp; } // 進行兩組骰子的大小比較 for (i = 0; i < SIZE; i++) { if (points1[i] == points2[i]) { counter3++; } if (points1[i] > points2[i]) { counter1++; } if (points1[i] < points2[i]) { counter2++; } } // 印出模擬結果 printf ( "\n進行 %d 次擲骰子模擬\n" , SIZE); printf ( "電腦 A 贏了 %d 次, 機率為 %f\n" , counter1, ( float ) counter1 / SIZE); printf ( "電腦 B 贏了 %d 次, 機率為 %f\n" , counter2, ( float ) counter2 / SIZE); printf ( "雙方平手 %d 次, 機率為 %f\n" , counter3, ( float ) counter3 / SIZE); return 0; } /* 《程式語言教學誌》的範例程式 檔名:dice5.c 功能:簡單的擲骰子遊戲 作者:張凱慶 時間:西元2010年7月 */ |
程式主要增加了第 34 行到第 47 行
34 35 36 37 38 39 40 41 42 43 44 45 46 47 | // 進行兩組骰子的大小比較 for (i = 0; i < SIZE; i++) { if (points1[i] == points2[i]) { counter3++; } if (points1[i] > points2[i]) { counter1++; } if (points1[i] < points2[i]) { counter2++; } } |
我們用一個 for 迴圈重新循序存取兩個陣列中儲存的點數值,再進行相等、大於或小於的測試,那一項為真,就將相關變數遞增。
第 49 行到第 53 行
49 50 51 52 53 | // 印出模擬結果 printf ( "\n進行 %d 次擲骰子模擬\n" , SIZE); printf ( "電腦 A 贏了 %d 次, 機率為 %f\n" , counter1, ( float ) counter1 / SIZE); printf ( "電腦 B 贏了 %d 次, 機率為 %f\n" , counter2, ( float ) counter2 / SIZE); printf ( "雙方平手 %d 次, 機率為 %f\n" , counter3, ( float ) counter3 / SIZE); |
這裡除了顯示累計的次數外,也計算機率,注意機率要得到正確的結果,就需要用 cast 運算子強制轉換型態為浮點數。
好了,來編譯執行看看吧!

問題與討論
- 為什麼進行骰子點數大小比較時,是利用三個獨立分開的 if 陳述,而不是巢狀的 if-else 陳述?
- 請重複執行編譯程式,比較看看每一次的模擬結果有什麼不同?
- 將 SIZE 改成 10000 ,重新編譯執行的結果如何?
沒有留言:
張貼留言