簡單C 程式 擲骰子
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
課程首頁在:http://blog.csdn.net/sxhelijian/article/details/11890759,內有完整教學方案及資源連結
看到一位同學釋出的博文,模擬了擲骰子。很好的題目,初學程式設計,就可以這樣,找到一個很小,很好玩的需求去完成,這是未來做大專案的“引子”。
他用程式碼實現了需求,這是最重要的。
我也按捺不住,給一個新的版本。目前,同學們習慣了面向過程的思維,只管著讓程式按照流程做完事即可,對面向物件程式的結構還沒有感覺。類的封裝,該如何體現?函式的介面,怎樣才算簡潔?這些問題,用講的方式起個頭可以,更重要的是,在用的過程中得到領悟。
學生的程式是:
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;class shaizi{public: void yaodian();private: int a;};int main(){ cout << "搖出的點數" << endl; shaizi s1; s1.yaodian(); return 0;}void shaizi::yaodian(){ int x; srand(time(0)); x=rand()%5 +1; a=x; cout<<a;}
我改寫的程式是:
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;class shaizi{public: int getdian();private: int dian;};int main(){ shaizi s1; cout << "搖出的點數" <<s1.getdian()<<endl; return 0;}int shaizi::getdian(){ srand(time(0)); dian=rand()%6+1; return dian;}
這個程式的結構要好一些。輸出的工作交給main,物件s1只管提供數就行了。
一個很簡單的要求,輸入輸出儘可能交給測試函式,類只做圍繞資料的處理工作。除非實在必要,不要在成員函式中用cin和cout。
學習了後面的建構函式,這個簡單程式還可以別的改造。
再寫了一個好玩的,希望用常量定下局數後,能夠多輪決輸贏。例如,下面的程式,想9局5勝。
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;class shaizi{public: void setdian(); int getdian();private: int dian;};const int round=9; //round必須置一個奇數int main(){ shaizi s1,s2; int i=1,n1=0,n2=0; while(i<=round) { s1.setdian(); s2.setdian(); cout<<"第"<<i<<"輪: 甲 "<<s1.getdian()<<",乙: "<<s2.getdian(); if(s1.getdian()>s2.getdian()) n1++; else if (s2.getdian()>s1.getdian()) n2++; else { cout<<",平局重擲 "; continue; } i++; cout<<endl; if(n1==(round/2+1)||n2==(round/2+1)) break; } cout << "甲贏 "<<n1<<" 輪,乙贏 "<<n2<<" 輪"; if(n1>n2) cout<<",甲勝"<<endl; else if(n2>n1) cout<<",乙勝"<<endl; return 0;}int shaizi::getdian(){ return dian;}void shaizi::setdian(){ srand(time(0)); dian=rand()%6+1;}
程式中用了類的“標配”,set和get成員函式都有,這個結構更好。在main函式中多設了些道道,能夠9局5勝,且平局不算。
但是,程式執行是死迴圈!
在螢幕上的數字快速滾動中,猜測問題的原因是,每次都平局,都continue了。把28-32行的處理平局的程式碼去掉執行,果然如此。見圖:
為什麼會這樣?還得說隨機數的原理。用rand()得到的隨機數,並不是完全隨機,是“偽隨機”,隨機數序列取決於“種子數”,種子數由srand(long)設定。也就是說,當種子數相同時,得到的隨機序列就是完全相同的。為此,常取系統時間(time(0)返回的是從1970年1月1日午夜起到現在的秒數)作種子數,這是個可以讓每次執行時種子數都不同的辦法。
然而 在這個程式中,呼叫s1和s2兩個物件的setdian成員函式時,間隔的時間太短了,現在再慢的計算機,也不會讓再次呼叫間隔超過1秒,甚至在這1秒末,那一秒初的那一瞬間的可能性都沒有。每次都平局,不可避免。
好不容易想到個好玩的簡單遊戲,就此罷休?想到的一個解決方案,讓兩次“投擲”停頓一下(這在專業中叫做“延時”),可以做到能夠得出不同的種子數。
程式如下:
#include <iostream>#include <cstdlib>#include <ctime>#include <windows.h>using namespace std;class shaizi{public: void setdian(); int getdian();private: int dian;};const int round=9; //round必須置一個奇數int main(){ shaizi s1,s2; int i=1,n1=0,n2=0; while(i<=round) { s1.setdian(); Sleep(1000); //延時1000毫秒,即1秒 s2.setdian(); cout<<"第"<<i<<"輪: 甲 "<<s1.getdian()<<",乙: "<<s2.getdian(); if(s1.getdian()>s2.getdian()) n1++; else if (s2.getdian()>s1.getdian()) n2++; else { cout<<",平局重擲 "<<endl; continue; } i++; cout<<endl; if(n1==(round/2+1)||n2==(round/2+1)) break; } cout << "甲贏 "<<n1<<" 輪,乙贏 "<<n2<<" 輪"; if(n1>n2) cout<<",甲勝"<<endl; else if(n2>n1) cout<<",乙勝"<<endl; return 0;}int shaizi::getdian(){ return dian;}void shaizi::setdian(){ srand(time(0)); //設定種子數,由於有了間隔,能夠保證種子數不同 dian=rand()%6+1; //實際每次取出的是,種子數確定的隨機序列中的第一個}
加入的Sleep(1000)是延遲1000毫秒,為了呼叫此函式,需要#include<window.h>。
由於延時,結果每隔1秒出來一行,倒也好看。見圖:
下面再給一種方案,種子數不再每次獲得隨機數前置,而是在main函式開始時設定,也能得到好的效果。見程式:
#include <iostream>#include <cstdlib>#include <ctime>using namespace std;class shaizi{public: void setdian(); int getdian();private: int dian;};const int round=9; //round必須置一個奇數int main(){ shaizi s1,s2; int i=1,n1=0,n2=0; srand(time(0)); //設定一次種子數,決定整個程式中用到的隨機序列 while(i<=round) { s1.setdian(); s2.setdian(); cout<<"第"<<i<<"輪: 甲 "<<s1.getdian()<<",乙: "<<s2.getdian(); if(s1.getdian()>s2.getdian()) n1++; else if (s2.getdian()>s1.getdian()) n2++; else { cout<<",平局重擲 "<<endl; continue; } i++; cout<<endl; if(n1==(round/2+1)||n2==(round/2+1)) break; } cout << "甲贏 "<<n1<<" 輪,乙贏 "<<n2<<" 輪"; if(n1>n2) cout<<",甲勝"<<endl; else if(n2>n1) cout<<",乙勝"<<endl; return 0;}int shaizi::getdian(){ return dian;}void shaizi::setdian(){ dian=rand()%6+1;}
該還有別的方案,評論中接龍。
china-pub 卓越網 圖靈社群 官方試讀本下載 豆瓣 |
==================== 迂者 賀利堅 CSDN部落格專欄=================|== IT學子成長指導專欄 專欄文章分類目錄(不定期更新) ==||== C++ 課堂線上專欄 賀利堅課程教學連結(分課程年級) ==|===== 為IT菜鳥起飛鋪跑道,和學生一起享受快樂和激情的大學 ===== |