C 語言初學教材 - 第三章 建立自己的亂數表

我們也可以建立自己的亂數表,利用標準函數庫 stdlib.h rand() 就能取得虛擬整數值,範圍從 0 到 RAND_MAX ,其中, RAND_MAX 至少會是 32767 。



猜數字遊戲大體已完備,答案取自 time() 回傳的總秒數除以 25 的餘數即可,加入迴圈後答案固定,猜錯了又可以依提示繼續猜,所以,我們來發展另一個需要亂數表的遊戲唄!


簡單一點,我們接下來發展個擲骰子遊戲。遊戲的概念也很簡單,讓使用者押籌碼與電腦對擲,使用者贏籌碼加倍,使用者輸則籌碼被電腦沒收,最後完整的版本希望能如此囉!


第一步該怎麼做呢?我們先不考慮使用者押籌碼的部份,純粹直接取得兩個擲骰子的點數,然後各自存入兩個表格,如下
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int points1[10]; // 第一組骰子表格
    int points2[10]; // 第二組骰子表格
    int temp; // 暫存變數
    int i; // 迴圈用變數
        
    // 利用迴圈取得骰子點數,然後存入表格
    for (i = 0; i < 10; i++) {
        temp = rand() % 6;
        if (temp == 0) {
            temp = 6;
        }
        points1[i] = temp;
        
        temp = rand() % 6;
        if (temp == 0) {
            temp = 6;
        }
        points2[i] = temp;
    }
    
    // 印出表格內的值
    printf("第一個骰子點數表為 ");
    for (i = 0; i < 10; i++) {
        printf("%d ", points1[i]);
    }
    printf("\n");
    printf("第二個骰子點數表為");
    for (i = 0; i < 10; i++) {
        printf("%d ", points2[i]);
    }
    printf("\n");
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:dice1.c
    功能:簡單的擲骰子遊戲
    作者:張凱慶
    時間:西元2010年7月 */ 


先來編譯執行看看吧!



我們利用陣列來儲存擲骰子點數的表格,每一次遊戲就可以從兩個陣列中拿出相同索引的值來當作雙方的點數,這樣滿方便的,先把點數都計算出來存到陣列中,然後遊戲過程直接操作陣列即可。咦,可是這個程式每次執行都一樣,假如使用者點數是儲存在 points2[] 的話,那不就總是第一次平手,然後連輸六次,好不容易贏一次,接著再平手兩次。


這樣就不好完了,不是嗎?因為 rand() 取得的是虛擬亂數,所得到的值就像是從系統亂數表中的固定位置取值,取得不同的值在於第幾次呼叫,因此,當呼叫順序是相同的時候,我們自己建立的亂數表就都會一樣。


能不能每次執行都能建立不同的亂數表呢?可以的,我們只需要另外利用 stdlib.h 的函數 srand() ,作用就像是能改成從系統亂數表中的不同位置取值。


我們加入呼叫 srand() 的版本如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int points1[10]; // 第一組骰子表格
    int points2[10]; // 第二組骰子表格
    int temp; // 暫存變數
    int i; // 迴圈用變數
    
    srand(time(NULL));
        
    // 利用迴圈取得骰子點數,然後存入表格
    for (i = 0; i < 10; i++) {
        temp = rand() % 6;
        if (temp == 0) {
            temp = 6;
        }
        points1[i] = temp;
        
        temp = rand() % 6;
        if (temp == 0) {
            temp = 6;
        }
        points2[i] = temp;
    }
    
    // 印出表格內的值
    printf("第一個骰子點數表為 ");
    for (i = 0; i < 10; i++) {
        printf("%d ", points1[i]);
    }
    printf("\n");
    printf("第二個骰子點數表為 ");
    for (i = 0; i < 10; i++) {
        printf("%d ", points2[i]);
    }
    printf("\n");
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:dice2.c
    功能:簡單的擲骰子遊戲
    作者:張凱慶
    時間:西元2010年7月 */ 


第 12 行呼叫 srand()
srand(time(NULL));


srand() 需要一個正整數值當做參數,作為產生一系列虛擬亂數的種子數,簡單一點就利用函數 time() 囉!這樣每一次執行就能得不不同的結果,編譯執行,結果如下



問題與討論
  1. 將模擬骰子的亂數表擴展到 1000 組,然後計算 point1 贏的次數?
  2. 承上例,將這個計算寫進程式內,然後印出結果?
  3. 承上列,計算平手的結果,並將之寫進程式內印出來?




1 則留言:

Unknown 提到...

point[10]是為了易於閱讀而這樣設置的嗎
因為point[10]始終用不到,只會用到[9]