C 語言初學教材 - 第四章 完成版的擲骰子遊戲

跑完一百萬次的模擬會不會有點久,因為電腦處理的資料很多啊!想一想,一百萬次的模擬,程式要先替每一次模擬建立具有 2000 個骰子點數的亂數表,另外 3000 次的條件判斷,印出工作也有 300 次,其餘小計算不計,那麼,程式至少需要做 53 億次,也就是 5.3 × 109 的計算。所以當處理的資料量越大,有效率的演算法跟資料結構也就越重要。



我們先暫停討論有關演算法跟資料結構的問題唄!來想想擲骰子遊戲應該要怎麼與使用者互動,先印出使用者目前有多少籌碼,然後要求使用者輸入要壓的籌碼數,接著印出雙方點數,最後顯示使用者贏或輸,剩下多少籌碼。


根據這樣的互動概念,我們提供完成版的擲骰子遊戲如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

#define SIZE 1000

int main(void)
{
    int points1[SIZE]; // 第一組骰子表格
    int points2[SIZE]; // 第二組骰子表格
    int temp; // 暫存變數
    int i; // 迴圈用變數
    int jeton = 100; // 玩家的籌碼
    char input[10]; // 接受玩家所要壓的籌碼值
    int n; // 儲存籌碼值
    int counter; // 累計遊戲次數,用為用為存取骰子表格
    
    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;
    }
    
    // 遊戲執行的迴圈
    counter = 0; 
    printf("\n這是擲骰子遊戲,您目前有 %d 個籌碼\n", jeton);
    while (1) {
        printf("請輸入要壓多少籌碼 1-10: ");
        scanf("%s", input);
        
        if (!strcmp(input, "exit")) {
            printf("\n您即將離開遊戲....\n");
            break;
        }
        
        n = atoi(input);
        
        if (n > 10 || n < 1) {
            printf("\n輸入籌碼值不正確,請重新輸入....\n");
            continue; 
        }
        
        printf("\n您的點數: %d\n", points1[counter]);
        printf("電腦的點數: %d\n", points2[counter]);
        
        if (points1[counter] == points2[counter]) {
            counter++;
            printf("雙方平手,直接擲下一輪....\n");
            continue;
        }
        
        if (points1[counter] > points2[counter]) {
            counter++;
            jeton += n;
            printf("您的點數大於電腦的點數,現在有 %d 籌碼\n", jeton);
            continue;
        }
        
        if (points1[counter] < points2[counter]) {
            counter++;
            jeton -= n;
            printf("您的點數小於電腦的點數,現在有 %d 籌碼\n", jeton);
            continue;
        }

    }
    
    printf("\n\n\n遊戲即將結束....\n\n");
    
    return 0;
}

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


遊戲在 while (1) 迴圈中執行,所以我們提供的結束機制就是使用者輸入 exit ,這樣就會跳出迴圈結束遊戲。


因為使用者輸入可能會有文字,如 exit ,第 41 行
scanf("%s", input);


接收使用者輸入的是字串,因為不是數字,所以第 48 行
n = atoi(input);


我們利用標準函數庫 stdlib.h 的函數 atoi() ,進行字串與整數之間的轉換。 atoi() 需要一個字串當作參數,然後讀取字串開頭前屬於數字的字元,組合成數字回傳整數值。


來編譯執行,玩看看吧!



問題與討論
  1. 為什麼接受使用者所猜的數字要用字串?
  2. 將接受使用者輸入的轉換字符改為 %d ,也就是接受輸入整數,然後另設機制如輸入 99 作為結束 while (1) 迴圈之用。
  3. 承上例,這樣的程式執行時,有可能發生什麼問題嗎?




沒有留言: