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 擲出的點數,所有的程式碼如下
#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; } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:dice5.c 功能:簡單的擲骰子遊戲 作者:張凱慶 時間:西元2010年7月 */
程式主要增加了第 34 行到第 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 行
// 印出模擬結果 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 ,重新編譯執行的結果如何?
沒有留言:
張貼留言