C語言探索之旅 | 第二部分第十課: 實戰"懸掛小人&quo

lee_lgw發表於2021-09-09

圖片描述

作者 謝恩銘,慕課網精英講師 Oscar老師。

內容簡介


  1. 前言
  2. 解方(1. 遊戲的程式碼)
  3. 解方(2. 詞庫的程式碼)
  4. 第二部分第十一課預告

1. 前言


經過上一課 之後,相信大家都或多或少都寫了自己的“懸掛小人”的遊戲程式碼吧。

這一課我們就來"終結"這個遊戲吧 (聽著怎麼有點嚇人…)。

“Yes, you are terminated.”

2. 解方(1. 遊戲的程式碼)


如果你開始閱讀這裡,說明:

  • 或者你寫完了遊戲,想來看看我們怎麼寫。
  • 或者你沒完成這個遊戲,想來看看怎麼寫。

不管你是哪種情況,我都會介紹一下如何來完成這個遊戲。

“說不說在我,聽不聽在您”~

事實上,我自己花了比想象中更多的時間來完成這遊戲。

人生總是這樣的,“理想豐滿,現實骨感;看似美滿,人艱不拆”。

但是,我還是堅信大家是有能力獨自完成這個小遊戲的(如果你認真學習了之前的 C語言課程),可以去查閱網上資料,花點時間(幾十分鐘,幾小時,幾天?),這並不是一次競賽,所以不用著急。

我更希望您花了不少時間,最終實現了這個遊戲; 比之您只花 5 分鐘,然後就來看答案要好很多。

千萬不要覺得我是一蹴而就寫成這個遊戲的,這個遊戲雖小,但也還沒簡單到可以在腦中構思好一切,然後“下筆如有神”: 我也是一步步寫出來的。

我們將會分 2 步來介紹我們的解方:

  1. 首先我們會演示如何一步步寫遊戲的主體部分,一開始我們會只有一個猜測的單詞,而且是固定的;我選了 BOTTLE(表示“瓶子”),因為我們要測試對於單詞中有大於等於兩個相同字母的情況是否處理正確了(BOTTLE 中有 2 個 T)。

  2. 然後我們會演示如何加入詞庫的處理程式,以便每一輪遊戲可以從詞庫中隨機抽取一個單詞。

牢記:重要的不是結果,而是我們思考的方式和過程。

分析 main 函式


大家都知道,我們的 C語言程式都是由 main 函式作為入口的。

我們也不要忘了引入一些標準庫的標頭檔案:stdio.h,stdlib.h,ctype.h(為了 toupper 函式)。

因此,我們的程式一開始會是這樣的:

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

int main(int argc, char* argv[])
{
    return 0;
}

是不是很簡單啊,慢慢來麼。

我們的 main 函式將控制遊戲的大部分運作,並且呼叫我們將要寫的不少函式。

我們來宣告一些必要的變數吧。這些變數也不是一次就能全部想到的,都是寫一點,想到一些。“羅馬不是一日建成的, 小人也不是一日能懸掛完的”。

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

int main(int argc, char* argv[])
{
    char letter = 0;  // 儲存使用者輸入的字母
    char secretWord[] = "BOTTLE";  // 要猜測的單詞
    int letterFound[6] = {0};  // 布林值的陣列。陣列的每一個元素對應猜測單詞的一個字母。0 = 還沒猜到此字母, 1 = 已猜到字母
    int leftTimes = 7;  // 剩餘猜測次數(0 = 失敗)
    int i = 0;  // 為了遍歷陣列,需要一個下標

    return 0;
}

上述的變數中,起到關鍵作用的就是 letterFound 這個 int 型陣列了。這個陣列用於表示猜測的單詞中哪些字母已經猜到,哪些還沒猜到。

一開始,我們實現得簡單些:我們的單詞 BOTTLE 有 6 個字母,因此我們的陣列就固定是 6 個元素的陣列。

如果元素為 0,表示對應的那個字母還沒猜到;如果為 1,則表示已猜到。隨著遊戲的進行,這個陣列的元素值會被修改。

例如,如果當下我們玩遊戲直到:

B*TT*E

那麼,letterFound 這個陣列的值應該是這樣:

101101

之後我們要測試遊戲的一輪是否已經勝利也就比較簡單了:只需要測試 letterFound 陣列的所有元素是否都等於 1。

我們就來寫判斷一輪是否勝利的函式吧,取名為 win(表示 “勝利”)好了。

int win(int letterFound[])
{
    int i = 0;
    int win = 1;  // 1 為勝利,0 為失敗

    for (i = 0 ; i < 6 ; i++)
    {
        if (letterFound[i] == 0)
            win = 0;
    }

    return win;
}

可以看到,我們的 win 函式的引數是一個 int 型陣列,我們在 main 函式中呼叫 win 函式時,會將我們的 letterFound 陣列傳給它。

這個函式很簡單:遍歷陣列,只要還有一個元素為 0,那遊戲還沒勝利;如果所有元素都為 1,則遊戲勝利。

為了與此函式搭配,我們還需要寫一個函式,起名叫 researchLetter,這個函式將有兩個功能:

  1. 返回一個布林值(在 C語言裡用 int 型表示),用於表示所猜的字母是否存在於單詞中。

  2. 更新 letterFound 陣列的元素,如果所猜的字母在單詞中,那麼就把對應的元素值修改為 1。

int researchLetter(char letter, char secretWord[], int letterFound[])
{
    int i = 0;
    int correctLetter = 0;  // 0 表示字母不在單詞裡,1 表示字母在單詞裡

    // 遍歷單詞陣列 secretWord,以判斷所猜字母是否在單詞中
    for (i = 0 ; secretWord[i] != '

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1020/viewspace-2825683/,如需轉載,請註明出處,否則將追究法律責任。

相關文章