C語(yǔ)言模擬擲骰子游戲
實(shí)現(xiàn)擲骰子小游戲
在開(kāi)始今天的練習(xí)前,我先寫(xiě)一個(gè)有趣的C語(yǔ)言小游戲——擲骰子(zhì tóu zi)
實(shí)現(xiàn)原理
大家對(duì)骰子應(yīng)該不陌生,讓我們先看看百度詞條的介紹:
擲骰子
拼音:zhì tóu zi
骰子: 既色子,用象牙、骨頭或塑料等較堅(jiān)硬物體做的小四方塊;每面刻有點(diǎn)數(shù),一到六,常用一對(duì)做各種游戲或賭博。
擲骰子:先搖動(dòng)骰子,然后拋擲使兩個(gè)骰子都隨意停止在一平面上。
——百度百科
擲骰子時(shí),每次能擲出的點(diǎn)數(shù)為1~6
,且是隨機(jī)的,那么如何用C語(yǔ)言來(lái)產(chǎn)生這一隨機(jī)數(shù)呢?
這時(shí)就要用到rand()
和srand()
函數(shù)了:
srand
函數(shù)是隨機(jī)數(shù)發(fā)生器的初始化函數(shù)。原型:void srand(unsigned int seed)
;
srand
和rand()
配合使用產(chǎn)生偽隨機(jī)數(shù)序列。
rand()
:
原型:int rand(void)
,
功能:產(chǎn)生隨機(jī)值,從srand (seed)
中指定的seed
開(kāi)始,返回一個(gè)[seed, RAND_MAX(0x7fff))
間的隨機(jī)整數(shù)。
srand():
原型:void srand(unsigned seed)
,
參數(shù):seed
是rand()
的種子,用來(lái)初始化rand()
的起始值。
功能:可以認(rèn)為rand()
在每次被調(diào)用時(shí),它都會(huì)查看srand(seed)
中指定的seed值,如果存在srand(seed)
,那么它會(huì)自動(dòng)調(diào)用srand(seed)
一次來(lái)初始化它的起始值。如果用戶在此之前沒(méi)有調(diào)用過(guò)srand(seed)
,它會(huì)自動(dòng)調(diào)用srand(1)
一次。
——百度百科
上面提到了rand()
函數(shù)只能生成偽隨機(jī)數(shù),意思是如果起始值seed
固定,那么每次程序運(yùn)行,它產(chǎn)生的隨機(jī)數(shù)序列都是相同的,而不是真正意義上的隨機(jī)數(shù)。形象地說(shuō),如果seed
值固定,那每次程序運(yùn)行,第一次擲到的點(diǎn)數(shù)都是固定的,這顯然不合理,那怎么生成更加合理的隨機(jī)數(shù)呢?
補(bǔ)充:
種子在每次啟動(dòng)計(jì)算機(jī)時(shí)是隨機(jī)的,但是一旦計(jì)算機(jī)啟動(dòng)以后它就不再變化了;也就是說(shuō),每次啟動(dòng)計(jì)算機(jī)以后,種子就是定值了,所以根據(jù)公式推算出來(lái)的結(jié)果(也就是生成的隨機(jī)數(shù))就是固定的?!?a rel="external nofollow" target="_blank">http://c.biancheng.net/view/2043.html
我們都知道系統(tǒng)的時(shí)間值(總秒數(shù))是時(shí)刻都在變化著的,如果把時(shí)間秒數(shù)當(dāng)做隨機(jī)數(shù)的種子seed
,那豈不是能實(shí)現(xiàn)真正的隨機(jī)數(shù)?答案是方法可行,但并不能產(chǎn)生真正的隨機(jī)數(shù),因?yàn)闀r(shí)間是遞增的,是有規(guī)律的數(shù)字序列,所以產(chǎn)生的隨機(jī)數(shù)也會(huì)呈現(xiàn)一定的規(guī)律,但是,此時(shí)的隨機(jī)數(shù)已經(jīng)足夠我們用來(lái)完成擲骰子游戲了,所以我們也沒(méi)必要去糾結(jié)是否是真正的隨機(jī)數(shù)(可能計(jì)算機(jī)本來(lái)就無(wú)法產(chǎn)生真正隨機(jī)數(shù))。
要想獲取系統(tǒng)時(shí)間秒數(shù),需要用到time()
函數(shù):
time()
是指返回自 Unix 紀(jì)元(January 1 1970 00:00:00 GMT)起的當(dāng)前時(shí)間的秒數(shù)的函數(shù),主要用來(lái)獲取當(dāng)前的系統(tǒng)時(shí)間,返回的結(jié)果是一個(gè)time_t
類型。
time_t time(time_t *t);
如果t是空指針,直接返回當(dāng)前時(shí)間。如果t不是空指針,返回當(dāng)前時(shí)間的同時(shí),將返回值賦予t指向的內(nèi)存空間。
——百度百科
time_t
的原型就是long int
,這個(gè)函數(shù)的實(shí)現(xiàn)原理我們也沒(méi)必要去深究,我們只要清楚它能返回秒數(shù)就足夠了。
程序中,我們可以通過(guò)下面的語(yǔ)句初始化隨機(jī)數(shù)種子和產(chǎn)生隨機(jī)數(shù):
srand((unsigned)time(NULL)); //用系統(tǒng)秒數(shù)初始化隨機(jī)數(shù)種子 ret = rand(); //產(chǎn)生隨機(jī)數(shù),賦值給ret變量
現(xiàn)在生成了隨機(jī)數(shù),那如何將隨機(jī)數(shù)轉(zhuǎn)換成骰子的點(diǎn)數(shù)呢?
骰子一般都是正方體,有6個(gè)面,正面朝上的即為點(diǎn)數(shù),那么它就有6種點(diǎn)數(shù),分別是1~6,我們將剛才生成的隨機(jī)數(shù)對(duì)6取余,即可將隨機(jī)數(shù)限定在0~5之間,再加上1,就是我們要的隨機(jī)點(diǎn)數(shù)了:
ret = rand() % 6 + 1; //ret即為隨機(jī)點(diǎn)數(shù)
源碼介紹
原理介紹完了,接下來(lái)直接上代碼
代碼由兩個(gè)部分構(gòu)成:
- 菜單打?。捍蛴」δ苓x擇,顯示上次投骰子的結(jié)果
- 操作選擇:選擇擲骰子或退出退出程序
#include <stdio.h> #include <stdlib.h> //srand()/rand() #include <time.h> //time() int main() { char choice = '\0'; //菜單選擇 int ret = 0; //用系統(tǒng)秒數(shù)初始化隨機(jī)數(shù)種子 srand((unsigned)time(NULL)); while(1) { /* 1.菜單打印 */ system("cls"); //清屏--Windows系統(tǒng) printf("======================\n"); printf("| 擲骰子游戲 |\n"); printf("| 1:擲骰子 0:退出 |\n"); if(ret) printf("| 上輪點(diǎn)數(shù):%d |\n", ret); printf("======================\n"); /* 2.操作選擇 */ printf("請(qǐng)選擇>>>>>>>\n"); scanf(" %c", &choice); //輸入選擇 //" %c" 可以吃前面的空格和回車 while(getchar() != '\n'); //吃掉除choice外其它字符 ret = 0; //初始化點(diǎn)數(shù) switch(choice) { case '0': printf("Goodbye!\n"); return 0; //退出 //擲骰子(產(chǎn)生1 ~ 6 隨機(jī)數(shù)) case '1': ret = rand() % 6 + 1; break; default: printf("無(wú)效選擇!\n"); } } return 0; }
效果展示
今日練習(xí)
題目描述
骰子是一個(gè)有六個(gè)面的正方體,每個(gè)面分別印有1?6之間的小圓點(diǎn)代表點(diǎn)數(shù)。假設(shè)這個(gè)游戲的規(guī)則是:兩個(gè)人輪流擲骰子6次,并將每次投擲的點(diǎn)數(shù)累加起來(lái)。點(diǎn)數(shù)多者獲勝;點(diǎn)數(shù)相同則為平局。
要求編寫(xiě)程序模擬這個(gè)游戲的過(guò)程,并求出玩100盤之后誰(shuí)是最終的獲勝者。
問(wèn)題分析
思路可以參照前面擲骰子小游戲的實(shí)現(xiàn)原理。
實(shí)現(xiàn)步驟:兩層循環(huán),外層循環(huán)100次,內(nèi)層循環(huán)6次,每次都將他們擲骰子的點(diǎn)數(shù)進(jìn)行累加,最后總點(diǎn)數(shù)大的即為贏家,如果點(diǎn)數(shù)相同,則平局。
代碼實(shí)現(xiàn)
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int sum_1 = 0, sum_2 = 0; int i = 0, j = 0; //用系統(tǒng)秒數(shù)初始化隨機(jī)數(shù)種子 srand((unsigned)time(NULL)); for(i = 0; i < 100; i++) { for(j = 0; j < 6; j++) { //獲取骰子點(diǎn)數(shù) sum_1 += rand() % 6 + 1; sum_2 += rand() % 6 + 1; } } printf("甲的總點(diǎn)數(shù):%d\n", sum_1); printf("乙的總點(diǎn)數(shù):%d\n", sum_2); if(sum_1 > sum_2) printf("甲獲勝!\n"); else if(sum_1 == sum_2) printf("平局...\n"); else printf("乙獲勝!\n"); return 0; }
運(yùn)行結(jié)果
由于擲骰子點(diǎn)數(shù)是隨機(jī)的,所以獲勝者也是隨機(jī)的。
結(jié)果1:
結(jié)果2:
把他們擲骰子次數(shù)調(diào)為1,試了n次之后,終于平局了
相關(guān)文章
C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有顏色彈跳小球
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言基于EasyX庫(kù)實(shí)現(xiàn)有顏色彈跳小球,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01C語(yǔ)言SetConsoleCursorPosition函數(shù)使用方法
這篇文章介紹了C語(yǔ)言SetConsoleCursorPosition函數(shù)的使用方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-12-12詳解C++語(yǔ)言中的加法運(yùn)算符與賦值運(yùn)算符的用法
這篇文章主要介紹了C++語(yǔ)言中的加法運(yùn)算符與賦值運(yùn)算符的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-01-01C語(yǔ)言示例講解動(dòng)態(tài)/文件/靜態(tài)功能版本的通訊錄實(shí)現(xiàn)
通訊錄是一個(gè)可以記錄親人、好友信息的工具,這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07C語(yǔ)言strlen,strcpy,strcmp,strcat,strstr字符串操作函數(shù)實(shí)現(xiàn)
這篇文章主要介紹了C語(yǔ)言strlen,strcpy,strcmp,strcat,strstr字符串操作函數(shù)實(shí)現(xiàn),,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09手把手帶你學(xué)習(xí)C++的數(shù)據(jù)類型
這篇文章主要為大家介紹了C++的數(shù)據(jù)類型,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助,希望能夠給你帶來(lái)幫助2021-11-11解決gcc編譯報(bào)錯(cuò)unknown type name ‘bool‘問(wèn)題
這篇文章主要介紹了解決gcc編譯報(bào)錯(cuò)unknown type name ‘bool‘問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07