我們繼續重複進行遊戲的模擬,程式碼如下
#include <stdio.h> #include <stdlib.h> #include <time.h> #define SIZE_A 1000 // 用為骰子表格 #define SIZE_B 100 // 用為模擬次數 #define ORIGIN 100 // 使用者籌碼的原始值 int main(void) { int points1[SIZE_A]; // 第一組骰子表格 int points2[SIZE_B]; // 第二組骰子表格 int result[SIZE_A]; // 儲存玩家的籌碼變化 int s[SIZE_B]; // 儲存每一次的模擬結果 int temp; // 暫存變數 int i, j; // 迴圈用變數 int jeton; // 玩家的籌碼 int n = 5; // 儲存籌碼值 int counter1 = 0; // 累計 points1 贏的次數 int counter2 = 0; // 累計 points2 贏的次數 int counter3 = 0; // 累計平手的次數 int second; // 取得現在的秒數 srand(time(NULL)); for (j = 0; j < SIZE_B; j++) { jeton = ORIGIN; second = time(NULL); // 建立兩組骰子的亂數表 for (i = 0; i < SIZE_A; i++) { temp = rand() % 6; if (temp == 0) { temp = 6; } points1[i] = temp; temp = rand() % 6; if (temp == 0) { temp = 6; } points2[i] = temp; } // 假設玩 SIZE 次,計算使用者手中籌碼的變化 for (i = 0; i < SIZE_A; i++) { if (points1[i] == points2[i]) { result[i] = jeton; } if (points1[i] > points2[i]) { jeton += n; result[i] = jeton; } if (points1[i] < points2[i]) { jeton -= n; result[i] = jeton; } } // 印出 300 次的使用者現有籌碼 for (i = 1; i < 301; i++) { printf("%3d ", result[i]); if (i % 15 == 0) { printf("\n"); } } printf("\n"); // 約暫停 1 秒 while (second == time(NULL)) { } // 將第 300 次使用者的籌碼值存進陣列 s[] 中 s[j] = result[i]; } // 累計總共輸贏的次數 for (j = 0; j < SIZE_B; j++) { if (s[j] == ORIGIN) { counter3++; } if (s[j] > ORIGIN) { counter1++; } if (s[j] < ORIGIN) { counter2++; } printf("%d ", s[j]); } printf("\n"); printf("\n模擬結果,使用者贏了 %d 次, 電腦贏了 %d 次,平手 %d 次....\n", counter1, counter2, counter3); return 0; } /* 《程式語言教學誌》的範例程式 http://pydoing.blogspot.com/ 檔名:dice7.c 功能:簡單的擲骰子遊戲 作者:張凱慶 時間:西元2010年7月 */
我們在原本模擬 300 次遊戲的外層,多增加另一個 for 迴圈,用為記錄重複進行遊戲的結果,常數 SIZE_B 則是我們進行模擬的次數,目前設為 100 次。
第 72 行到第 74 行
// 約暫停 1 秒 while (second == time(NULL)) { }
我們在 for 迴圈開始時,先用 second 取得函數 time() 回傳的目前秒數,這裡則是 for 迴圈結束的地方,這樣做的目的是會產生螢幕畫面約暫停一秒的效果,好讓我們可以看到每一次的模擬的情況。
來編譯執行看看吧!
嗯,使用者贏 51 次,電腦贏 48 次,平手一次,這樣其實看不出什麼。所以,我們再來模擬一百萬次看看吧!很簡單的,就把 SIZE_B 的值調整為 1000000 就可以囉!
使用者贏的次數與電腦贏的次數相當接近,於是我們可以做出一個結論,採用擬隨基數的設計方式執行這個遊戲,使用者與電腦贏的機都是 48.7% ,平手的機率則是 2.6% 。
問題與討論
- 我們所使用的約暫停 1 秒的機制,有沒有什麼缺點?
- 用自己的電腦模擬一百萬次,看看得到的結果如何?
- 想一想,有沒有方法可以調整輸贏的機率,例如給玩遊戲的使用者多點樂趣,將使用者贏的機率提高為 75% 。
3 則留言:
請問第77行 s[j] = result[i]; 應該是 s[j] = result[300];這樣才是將第300次使用者的籌碼值存進陣列吧?
仔細看63行
i最後的值會是300
又63行到75行沒有對i初始化 所以是可行的
請問一下
在第12行的宣告中
將point2宣告大小為SIZE_B(100)
然而在31行其迴圈將重複執行的次數為SIZE_A(1000)
而此迴圈又對point2進行指派值的動作
這樣不是就超過point2的宣告大小嗎@@
張貼留言