1. 程式人生 > >簡單C 程式 擲骰子

簡單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菜鳥起飛鋪跑道,和學生一起享受快樂和激情的大學 =====

  
    








           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述