擲骰子最廣泛的形式是用兩個6面骰子。ide
計算機能夠設計一種具備任意麪數的骰子,先從6面開始,再進行擴展。函數
咱們想獲得從1到6之間的一個隨機數。然而,rand()產生的是從0到RAND_MAX範圍內的整數;RAND_MAX在stdlib.h中定義,它一般是INT_MAX。所以,須要作一些調整。下面是一種方法:設計
一、把隨機數對6取模,將產生從0到5的整數。code
二、加1.新數將爲從1到6範圍內的整數。原型
三、爲了方便擴展,將步驟1中的數字6用骰子面數來代替。編譯器
下面的代碼實現了這些想法:io
#include <stdlib.h> /*爲rand()函數提供原型*/ int rollem(int sides) { int roll; roll = rand()%sides + 1; return roll; }
進一步,咱們想實現這樣的功能:它容許擲任意個骰子,而且返回點數總和。程序清單12.11實現了這樣的功能。編譯
/*diceroll.c --擲骰子的模擬程序*/ #include "diceroll.h" #include <stdio.h> #include <stdlib.h> /*爲rand()函數提供類庫*/ int roll_count = 0; /*外部連接*/ static int rollem(int sides) /*這個文件的私有函數*/ { int roll; roll=rand()%sides+1; ++roll_count; /*計數函數調用*/ return roll; } int roll_n_dice (int dice,int sides) { int d; int total = 0; if(sides<2) { printf("Need at least 2 sides.\n"); return -2; } if(dice<1) { printf("Need at least 1 die.\n"); return -1; } for(d=0;d<dice;d++) total += rollem(sides); return total; }
這個文件中加入了一些新東西。首先,它把rollem()變成由該文件私有的函數,這個函數用於輔助roll_n_dice();其次,爲了舉例說明外部連接如何工做,文件聲明瞭一個外部變量roll_count,這個變量跟蹤記錄函數rollem()的調用次數。例子自己有一點不妥,但它顯示了外部變量的如何工做的。ast
再次,文件包含下面的語句:function
#include "diceroll.h"
若是使用諸如rand()的標準庫函數,您須要在程序中包含標準頭文件(對rand()來講是stdlib.h),而不是聲明函數,由於頭文件中已經包含了正確的聲明。咱們將效仿這一作法,提供一個頭文件diceroll.h以供函數roll_n_dice()使用。將文件名置於雙引號而非尖括號中, 是爲了指示編譯器在本地尋找文件,而不是到編譯器存放標準頭文件的標準位置去尋找文件。「在本地尋找」的意義取決於具體的C實現。一些常看法釋是將頭文件與源代碼文件放在同一個目錄或文件夾中。程序清單12.12顯示了該頭文件的內容。
程序清單12.12 diceroll.h文件
//diceroll.h extern int roll_count; int roll_n_dice(int dice,int sides);
這個頭文件中包含函數原型聲明一和個extern聲明。由於文件diceroll.c包含了這一頭文件,它也就實際上包含了roll_count的兩個聲明:
extern int roll_count; //來自頭文件
int roll_count = 0; //來自源代碼文件
這是能夠的,一個變量只能夠有一個定義聲明,但使用extern的聲明是一個引用聲明,這樣的聲明想用多少就能夠用多少。
使用roll_n_dice()的程序也應該包含這一頭文件。這樣作不單單提供roll_n_dice()原型,還使得roll_count對程序可用。程序清單12.13證實了這些。
//manydice.c --屢次擲骰子的模擬程序 //與diceroll.c一塊兒編譯 #include<stdio.h> #include<stdlib.h> //爲srand()提供原型 #include<time.h> //爲time()提供原型 #include"dicerlll.h" //爲roll_n_dice()和roll-count提供原型 int main(void) { int dice ,roll; int sides; srand((unsigned int )time(0)); //隨機化種子 printf("Enter the number of sides per die,0 to stop.\n"); while(scanf("%d",&sides)==1 && sides>0) { printf("How many dice?\n"); scanf("%d",&dice); roll = roll_n_dice(dice,sides); printf("You have rolled a %d using %d %d-sided dice.\n",roll,dice,sides); printf("How many sides?Enter 0 to stop.\n); } printf("The rollem() function was called %d times.\n",roll_count); /*使用外部變量*/ printf("Good Fortune To You!\n"); return 0; }
將程序清單12.13與包含程序清單12.11的文件一塊兒編譯。爲了簡化問題,把程序清單12.十一、12.12和12.13放在同一文件中或同一目錄下。運行最後獲得的程序,輸出應該像下面這樣:
Enter the number of sides per die,0 to stop. 6 How many dice? 2 You have rolled a 12 using 2 6-sided dece. How many sides?Enter 0 to stop. 6 How many dice? 2 You have rolled a 4 using 2 6-sided dice. How many sides?Enter 0 to stop. 6 How many dice? 2 You have rolled a 5 using 2 6-sided dice. How many sides?Enter 0 to stop. 0 The rollem() funcation was called 6 times. GOOD FORRUNE TO YOU!
由於程序使用srand()來隨機肯定隨機數種子,因此大多數狀況下,即便有相同的輸入也不可能獲得相同的輸出。注意,manydice.c中的main()確實能夠訪問diceroll.c中定義的變量roll_count。
能夠使用多種方式使用roll_n_dice()。對於sides爲2的情形,程序模仿擲硬幣,面朝上爲2,背朝上爲1.您能夠很容易地修改程序來像顯示整體結果那樣顯示個別結果,或者建一個擲雙骰子賭博模擬器。