我們繼續重複進行遊戲的模擬,程式碼如下
#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的宣告大小嗎@@
張貼留言