猜數(shù)游戲

游戲規(guī)則

玩家先輸入四個數(shù)字争便,與系統(tǒng)產(chǎn)生的四個1-9之間的不重復的且從小到大排序隨機數(shù)進行比較级零,如果錯誤,根據(jù)顯示的結果再次進行猜測始花,直至正確妄讯。

游戲原理

1.產(chǎn)生四個1-9之間的不重復的隨機數(shù)孩锡。
2.將其從小到大排序酷宵。
3.與玩家輸入的數(shù)字進行比較。
4.如果有n個數(shù)字正確且位置正確的數(shù)躬窜,則輸出nA浇垦,如果有m個數(shù)字正確,位置不正確的數(shù)荣挨,則輸出mB男韧。
若玩家第一次猜錯,則可以根據(jù)nAmB這個結果進行合理分析并再次猜測默垄。

實現(xiàn)

先寫好頭文件
/#include <stdio.h>
/#include <stdlib.h>
/#include <time.h>

生成隨機數(shù)

步驟

1生成數(shù)組
2產(chǎn)生隨機數(shù)的同時去比較是否重復
3如果重復就重新再產(chǎn)生一個隨機數(shù)
4如果不重復就保存
5每次i的值正好可以用來判斷已經(jīng)有幾個了

首先定義一個數(shù)組并初始化此虑,再生成隨機數(shù)
注:有關生成隨機數(shù)的內(nèi)容在‘C語言基礎練習-隨機數(shù)’里面詳細介紹過,這里便不再復述口锭。
代碼如下

int array[4] = {};
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一個 直接保存 
            array[i] = temp;
        }else{
            //判斷前面是否已經(jīng)存在了
            int j = 0; 
            for(; j <i; j++){
                //比較j對應的值和temp是否相同 
                if(array[j] == temp){
                    //重復了
                //  printf("重復了:%d\n",temp); 
                    break; 
                } 
            }
            //判斷是怎么出來的
            if (j == i){
                //將i前面的比較一遍都沒發(fā)現(xiàn)重復的
                //保存temp值
                array[i] = temp; 
            }else{
                //重復了
                //重新回到當前這一次 
                i--; 
            }
        } 
    }

  • 雖然說隨機數(shù)在前面的筆記中有介紹過朦前,但是這里有一個新的要求,就是四個數(shù)中不能有相同的數(shù)字鹃操。
  • 所以在保存生成的這個數(shù)之前韭寸,要先判斷這個數(shù)與之前的數(shù)是否相同,若相同荆隘,就不能保存恩伺,然后重新生成再進行判斷,直至生成的數(shù)與前面的不同椰拒,再保存到數(shù)組中晶渠。
  • 由代碼可知,首先判斷這個數(shù)是否是第一個生成的數(shù)燃观,因為第一個生成的數(shù)前面沒有數(shù)字褒脯。所以直接保存即可。
  • 從第二個數(shù)字起仪壮,就要進行是否相同的判斷憨颠。
    這里假設已經(jīng)生成了第四個數(shù)字,現(xiàn)在要將其與前三個數(shù)進行對比。定義一個整型j爽彤,且j = 0养盗,此時i = 3,要將第四個數(shù)從第一個數(shù)開始進行判斷,就用一個for循環(huán)适篙,進行次數(shù)控制并連續(xù)判斷往核,只要進行了i -1次判斷且判斷數(shù)字都不相同,生成的這個數(shù)即可保存到數(shù)組嚷节,如若順序判斷中一旦相同聂儒,即停止判斷,退出當前for循環(huán)硫痰。
  • 當退出當前for循環(huán)后衩婚,若數(shù)字有相同的,會再次進行最外層的for循環(huán)中的i++從而效斑,而此時i=3非春,再次生成一個隨機數(shù)后,i就等于4了缓屠,就不會再生成隨機數(shù)奇昙,所以我們在內(nèi)層for循環(huán)執(zhí)行完或break出來之后,若要再次生成隨機數(shù)就要進行一下i - -敌完。
     if (j == i){
        array[i] = temp; 
        }else{
        i--; 
        }


將數(shù)組排序

排序的方法有很多储耐,在這里我們使用冒泡排序將數(shù)組按從小到大排好序
(由于在上一篇筆記中介紹過冒泡排序,這里就直接放上代碼)
代碼如下

    int i,j,t;          //從小到大排序 滨溉;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍歷次數(shù) 有N個數(shù)什湘,遍歷N-1次; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 

由于這個游戲是讓玩家猜數(shù)业踏,所以并不需要輸出生成的數(shù)組禽炬,但是在邊寫代碼的時候,可以輸出這個數(shù)組以便檢查是否存在bug勤家。
輸出的代碼如下

    //輸出  
    for (int i = 0; i< 4; i++){
        printf("%d ", array[i]);
    }
    printf("\n");

用戶輸入腹尖,游戲“開始”

用戶輸入

int input[4],shu;
    printf("請輸入四個數(shù)字\n");
    for(int a = 0;a < 4;a++){  //用另外一個數(shù)組儲存輸入的數(shù)字 
        scanf("%d",&shu);
        input[a] = shu;
    }

這里需要注意的是,要用另一個數(shù)組來儲存用戶輸入的數(shù)字伐脖。即代碼中的input热幔。

計算n、m

即在nAmB中的n讼庇、m绎巨。并判斷是否全對,若不對蠕啄,則告知玩家nAmB场勤,并再次進行猜測戈锻,直至猜對。

由上述可得和媳,整個輸入及計算過程要放在while(1)的循環(huán)里格遭。

計算過程有兩種方法。

方法一

分別計算A,B的值
代碼如下
首先計算A的值

int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出數(shù)字和位置都正確的個數(shù) 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }

再計算數(shù)字正確的個數(shù)

    a = 0; 
    while(a < 4){              //算出數(shù)字正確的個數(shù) 
        for(i = 0;i < 4;i++){
            if(input[a] == array[i]){
            space1++;
            }
        }
        a++;
    } 

在計算B之前留瞳,應將a重新變?yōu)?拒迅,因為在計算A的值之后,a 變成了3她倘。

計算B的值

 space2 = space1 - num;//算出數(shù)字正確璧微,位置不正確的個數(shù) ,即B的值
    printf("%dA%dB\n",num,space2);
    if(num == 4){
        printf("猜測正確硬梁!");
        break;
    }

用一個if語句前硫,使猜對后跳出while循環(huán)。


方法二

A,B一起計算.
代碼如下

 while(1){
        //提示輸入
        printf("請輸入猜測的數(shù)字:");
        for (int i = 0; i < 4; i++) {
            scanf("%d", &input[i]);
        }
//
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (org[i] == input[j]) {
                    //數(shù)字存在 判斷位置
                    if (i == j){
                        aCount++;
                    }else{
                        bCount++;
                    }
                }
            }
        }
        
        //提示用戶結果
        printf("%dA%dB\n", aCount, bCount);
        
        //判斷是否正確
        if( aCount == 4){
            printf("全對!!!!\n");
            break;
        }else{
            aCount = 0;
            bCount = 0;
        }
    }
  • 玩家輸入后靶溜,首先判斷是否有相同的數(shù)字存在开瞭。
  • 若存在懒震,則判斷位置罩息。
  • 若判斷位置正確,就意味著這個數(shù)位置个扰,數(shù)字都正確瓷炮,則aCount++。
  • 若判斷位置不正確递宅,就意味著這個數(shù)位置不正確但數(shù)字正確娘香,就bCount++。
  • 最后如果aCount != 4办龄。玩家再次進行猜測烘绽,而此時aCount, bCount都要進行清零才能重新正常地進行下一次猜測。

由上述可得俐填,方法二相當于是方法一的優(yōu)化版安接,因為方法二的計算過程更加直觀,簡潔英融。

將方法一改為函數(shù)版

#include <stdio.h>
#include <stdlib.h> 
#include <time.h>

int main(){
    int array[4] = {};
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一個 直接保存 
            array[i] = temp;
        }else{
            //判斷前面是否已經(jīng)存在了
            int j = 0; 
            for(; j <i; j++){
                //比較j對應的值和temp是否相同 
                if(array[j] == temp){
                    //重復了
                //  printf("重復了:%d\n",temp); 
                    break; 
                } 
            }
            //判斷是怎么出來的
            if (j == i){
                //將i前面的比較一遍都沒發(fā)現(xiàn)重復的
                //保存temp值
                array[i] = temp; 
            }else{
                //重復了
                //重新回到當前這一次 
                i--; 
            }
        } 
    }
    
    int i,j,t;          //從小到大排序 盏檐;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍歷次數(shù) 有N個數(shù),遍歷N-1次驶悟; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 

    
    while(1){
    
    
    int input[4],shu;
    printf("請輸入四個數(shù)字\n");
    for(int a = 0;a < 4;a++){  //用另外一個數(shù)組儲存輸入的數(shù)字 
        scanf("%d",&shu);
        input[a] = shu;
    }
    
    
    int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出數(shù)字和位置都正確的個數(shù) 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }
    
    a = 0; 
    while(a < 4){              //算出數(shù)字正確的個數(shù) 
        for(i = 0;i < 4;i++){
            if(input[a] == array[i]){
            space1++;
            }
        }
        a++;
    } 
    
    
    space2 = space1 - num;//算出數(shù)字正確胡野,位置不正確的個數(shù) 
    printf("%dA%dB\n",num,space2);
    if(num == 4){
        printf("猜測正確!");
        break;
    }
    
}
 
    return 0;
}

函數(shù)版

#include <stdio.h>
#include <stdlib.h> 
#include <time.h>
void randomNumber(int array[4]);// 生成隨機數(shù) 
void bubbleSort(int array[4]);//排序 
int game(int array[4]);//進行游戲 

int main(){
    int array[4] = {};
    randomNumber(array);
    bubbleSort(array);//()中的array是指針痕鳍,指向array這個數(shù)組的首地址硫豆,這樣做可以直接訪問地址,修改數(shù)據(jù) 

    while(1){
        game(array);
    
        if(game(array) == 4){
            printf("猜測正確!");
            break;
        }
    }
    return 0;
}

void randomNumber(int array[4]){
    srand(time(NULL));
    for (int i = 0; i < 4; i++){
        int temp = rand() % 9 + 1;
        
        if (i == 0){//第一個 直接保存 
            array[i] = temp;
        }else{
            //判斷前面是否已經(jīng)存在了
            int j = 0; 
            for(; j <i; j++){
                //比較j對應的值和temp是否相同 
                if(array[j] == temp){
                    //重復了
                //  printf("重復了:%d\n",temp); 
                    break; 
                } 
            }
            //判斷是怎么出來的
            if (j == i){
                //將i前面的比較一遍都沒發(fā)現(xiàn)重復的
                //保存temp值
                array[i] = temp; 
            }else{
                //重復了
                //重新回到當前這一次 
                i--; 
            }
        } 
    }   
}

void bubbleSort(int array[4]){
    
    int i,j,t;          //從小到大排序 熊响;冒泡排序 
    for(i = 0;i < 3;i++){  //控制遍歷次數(shù) 有N個數(shù)恭应,遍歷N-1次; 
        for(j =0;j < 4 -i -1;j++){
            if(array[j] > array[j + 1]){
                t = array[j];
                array[j] = array[j + 1];
                array[j + 1] = t;
            }
        }   
    } 
}

int game(int array[4]){

    int input[4],shu;
    printf("請輸入四個數(shù)字\n");
    for(int a = 0;a < 4;a++){  //用另外一個數(shù)組儲存輸入的數(shù)字 
        scanf("%d",&shu);
        input[a] = shu;
    }
    
    
    int num = 0,space1 = 0,a = 0,space2;
    for(int i = 0;i < 4;i++){   //算出數(shù)字和位置都正確的個數(shù) 
        if(input[a] == array[i]){
            num++;
        }
            a++;
    }
    
    a = 0; 
    while(a < 4){              //算出數(shù)字正確的個數(shù) 
        for(int m = 0;m < 4;m++){
            if(input[a] == array[m]){
            space1++;
            }
        }
        a++;
    } 
    
    
    space2 = space1 - num;//算出數(shù)字正確耘眨,位置不正確的個數(shù) 
    printf("%dA%dB\n",num,space2);
    return(num); 
}


//若要輸出原來的四個數(shù)字昼榛,則在array和while之間加入以下代碼  
/*  for (int i = 0; i< 4; i++){
        printf("%d ", array[i]);
    }
    printf("\n");
*/
  • 如果使用DEV C++,srand(time(NULL));中可以自動轉換剔难,若用Visual studio,則需進行強制轉換胆屿。srand((unsigned int)time(NULL));
  • 在Visual studio中,輸入需要使用vs封裝的scanf偶宫。scanf_s("%d",&shu);

作者有話說

  • 到此非迹,這個demo就做完啦!
  • 通過這個demo纯趋,對各種循環(huán)語句運用更加熟練了
  • 并且意識到要用自定義函數(shù)來單獨進行某個功能的重要性
  • 還有......熟能生巧憎兽!
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吵冒,隨后出現(xiàn)的幾起案子纯命,更是在濱河造成了極大的恐慌,老刑警劉巖痹栖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件亿汞,死亡現(xiàn)場離奇詭異,居然都是意外死亡揪阿,警方通過查閱死者的電腦和手機疗我,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來南捂,“玉大人吴裤,你說我怎么就攤上這事∧缃。” “怎么了麦牺?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長矿瘦。 經(jīng)常有香客問我枕面,道長,這世上最難降的妖魔是什么缚去? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任潮秘,我火速辦了婚禮,結果婚禮上易结,老公的妹妹穿的比我還像新娘枕荞。我一直安慰自己柜候,他們只是感情好,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布躏精。 她就那樣靜靜地躺著渣刷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矗烛。 梳的紋絲不亂的頭發(fā)上辅柴,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機與錄音瞭吃,去河邊找鬼碌嘀。 笑死,一個胖子當著我的面吹牛歪架,可吹牛的內(nèi)容都是我干的股冗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼和蚪,長吁一口氣:“原來是場噩夢啊……” “哼止状!你這毒婦竟也來了?” 一聲冷哼從身側響起攒霹,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤怯疤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后剔蹋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體旅薄,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年泣崩,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片洛口。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡矫付,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出第焰,到底是詐尸還是另有隱情买优,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布挺举,位于F島的核電站杀赢,受9級特大地震影響,放射性物質發(fā)生泄漏湘纵。R本人自食惡果不足惜脂崔,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梧喷。 院中可真熱鬧砌左,春花似錦脖咐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至产弹,卻和暖如春派歌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背痰哨。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工硝皂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人作谭。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓稽物,卻偏偏與公主長得像,于是被迫代替她去往敵國和親折欠。 傳聞我的和親對象是個殘疾皇子贝或,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容