iT邦幫忙

7

【Python 超入門】(11) (完結篇) 實作你的第一個遊戲-金頭腦益智問答

大家好,我是「心原一馬」,內心原來一心喜歡打程式碼。
相信很多人可能看過一些益智問答的電視節目,
幾個參賽者競爭高額獎金,回答節目裡的問題。

雖然小馬沒有提供高額獎金,
不過利用到目前為止所學的程式知識,
我們也可以做一個益智問答遊戲出來。

設計問題與答案

其實關於題目的類型你都可以隨自己的喜好來替換,
這邊小馬以數理邏輯類的問題為例,
給出三個問題:
Q1: 姜太公釣魚,猜一個數學名詞
A1: 等於 (等魚)

Q2: 小馬老師想把一打鉛筆分給一群小朋友,每個人都要拿到鉛筆而且每個人拿到的鉛筆數量不一樣多,試問: 最多可以分給幾個人? (輸入一個數字)
A2: 4
(解析: 如果分給5個人,至少要1+2+3+4+5=15隻筆; 分給4個人則每人可以分別拿1,2,3,6支筆,OK)

Q3: 計算下列算式之值: 2019*20202020-2020*20192019
A3: 0
(解析: 兩個數字都是 2019*2020*10001)

【Python 超入門】(9) input()函數- 使用者跟電腦對話的方法這篇文章中,
小馬教過各位用input()函數可以讓電腦取得使用者輸入的訊息。

輸入第一個問題

設計好自己的問題後,
我們用input()讀入使用者的答案,
再檢查答案是否正確。

#主程式
ans1 = input("姜太公釣魚,猜一個數學名詞: ")
if ans1=="等於":
    print("恭喜你答對了")

執行結果:
https://ithelp.ithome.com.tw/upload/images/20190716/20117114YbqwK2oygs.png

添加更多問題

同樣的方法,我們可以再把另外兩道問題加進去:

#主程式
ans1 = input("姜太公釣魚,猜一個數學名詞: ")
if ans1=="等於":
    print("恭喜你答對了")
ans2 = input("小馬老師想把一打鉛筆分給一群小朋友,每個人都要拿到鉛筆而且每個人拿到的鉛筆數量不一樣多,試問: 最多可以分給幾個人? (輸入一個數字) ")
if ans2=="4":
    print("恭喜你答對了")
ans3 = input("計算下列算式之值: 2019*20202020-2020*20192019= ")
if ans3=="0":
    print("恭喜你答對了")

這樣程式可以運行,
但是判斷答案是否正確的程式碼其實很類似,
我們可以獨立定義一個「檢查函式」,
讓主程式更簡潔。
(自定函數觀念可參考「【Python 超入門】(10) 自定義函數介紹- 主人向他的機器人管家抱怨:「你跟我這麼多年了,也該了解我們家的習慣了吧?」 」)

"""
自訂函式: check_answer
<參數> guess :使用者猜的答案,
       answer : 我們的標準答案
函數功能: 檢查使用者的答案跟標準答案是否一致。
"""
def check_ans(guess, answer):
    if guess==answer:
        print("恭喜你答對了")

修改主程式

有了自定義函數,我們可以簡單把主程式修改如下:

#主程式
ans1 = input("姜太公釣魚,猜一個數學名詞: ")
check_ans(ans1,"等於")
ans2 = input("小馬老師想把一打鉛筆分給一群小朋友,每個人都要拿到鉛筆而且每個人拿到的鉛筆數量不一樣多,試問: 最多可以分給幾個人? (輸入一個數字) ")
check_ans(ans2,"4")
ans3 = input("計算下列算式之值: 2019*20202020-2020*20192019= ")
check_ans(ans3,"0")

添加遊戲性- 計分

目前程式寫到這邊,
我們發現程式只是問問題,
然後告訴你答案對不對,略顯單調。
我們可以添加一個變數score,
記錄玩家所獲得的分數。

score = 0

我們修改自定函數 check_ans,讓使用者答對時加一分,
並且在使用者答錯時,也印出提示字串:

score = 0
def check_ans(guess, answer):
    global score 
    if guess==answer:
        print("恭喜你答對了")
        score += 1
    else:
        print("答錯了,再接再勵")

函數內使用了一個關鍵字global
這個字在之前的課程沒有講解到,這邊說明一下。
global score的意思是將 score 這個變數設為全域變數,
當在函數內修改這個變數時,
對整個程式都有影響。

結合所有程式碼

我們即將大功告成了,
我們把這些程式碼都寫在同一個檔案裡:

score = 0 #記錄玩家的分數

"""
自訂函式: check_answer
<參數> guess :使用者猜的答案,
       answer : 我們的標準答案
函數功能: 檢查使用者的答案跟標準答案是否一致。
"""
def check_ans(guess, answer):
    global score 
    if guess==answer:
        print("恭喜你答對了")
        score += 1  #每答對一題加1分
    else:
        print("答錯了,再接再勵")
        
#主程式
print("歡迎來到金頭腦益智問答遊戲~")
ans1 = input("姜太公釣魚,猜一個數學名詞: ")
check_ans(ans1,"等於")
ans2 = input("小馬老師想把一打鉛筆分給一群小朋友,每個人都要拿到鉛筆而且每個人拿到的鉛筆數量不一樣多,試問: 最多可以分給幾個人? (輸入一個數字) ")
check_ans(ans2,"4")
ans3 = input("計算下列算式之值: 2019*20202020-2020*20192019= ")
check_ans(ans3,"0")
print("您總共得到 "+str(score)+" 分") #印出最後的結果

這邊再嘗試執行一下,
小馬故意前兩題答錯,
最後一題答對,
順利顯示出 您總共得到 1 分:

https://ithelp.ithome.com.tw/upload/images/20190716/20117114abj5mzgiZk.png

至此已經製作出一個簡單的小遊戲了,
本篇內容活用了【Python 超入門】系列(1)~(10)的內容,
如有不理解之處,也歡迎在留言區發問。
再次感謝所有欣賞小馬文章及追蹤我的邦友。

【Python 超入門】系列完結了,接下來呢?

歷時一個多月,終於把【Python 超入門】系列寫完了,
過程中,看到許多邦友在留言區留言感謝小馬老師教學淺顯易懂,很有收穫;
也有許有邦友在留言區解答課後練習與小馬互動,心中覺得還蠻開心的。
感謝大家的喜歡哦~

若你跟著小馬的腳步學完【Python 超入門】,
現在你已經有程式的基礎概念了。
只是學習技術總是熟能生巧的,
新手也常會有「我不知道可以練什麼呀?」的疑惑。
歡迎可以收看我為新手而寫的心原一馬從零帶你認識線上解題系統- 專為新手設計的OJ 初體驗這篇文章,
它是個專為新手設計的練功平台,
既然學了程式語法,總是要多練才知道如何應用,
就像學外語要在生活中多講才會進步的快。
祝大家更上一層樓~

心原一馬接下來忙於準備iT邦幫忙的鐵人賽,
屆時會呈現更多python相較於其它程式語言的美妙之處~
九月再見囉~


1 則留言

1
naorosie
iT邦新手 5 級 ‧ 2019-07-23 11:57:22

不好意思 還是有點不懂為何score要先指定為0?以及score為何要設為全域變數呢?那數字加總還有其他寫法嗎?謝謝~

看更多先前的回應...收起先前的回應...

好的,謝謝你的發問哦~
這支程式確實融入了很多觀念在裡面呢~
小馬盡可能一一說清楚講明白~
(講解篇幅較長,我分兩個回應解答)

  1. 為何score要先指定為0?
    這邊隱含了兩個問題:
    (1)為何score要先設定初始值?
    (2)為何score的初始值設為0?
    小馬猜你的意思應該比較像是問(1),
    小馬著重在這部分回答:
    這個概念其實是說變數要使用之前必須要先「宣告」,
    什麼是「宣告」呢?
    就是一開始用「=」給這個變數設個初始值。
    例如下面簡單的程式,只有兩行:
score += 1
print(score)

實際執行之後會出現NameError: name 'score' is not defined
若沒有設定初始值,
程式並不知道score是什麼。

你可以想一個生活化的例子:
你今天到一間商店買東西,
老闆告訴你「這個商品降價100元」,
可是商品上並沒有標原價(也就是初始值),
那麼你還是不知道這個商品的價錢。
這也就是為什麼變數都需要一個初始值才能用。

上述程式可改為:

score = 0
score += 1
print(score)

即可印出結果1

  1. score為何要設為全域變數?
    簡言之,因為我們希望在函數裡面,
    去修改函數外面設定的變數值(玩家的分數)。
    變數有分兩種:區域變數全域變數
    區域變數是在函數內部的變數,
    使用它不會對整支程式造成影響。
    全域變數則是寫在函數外,在整支程式裡都可以用。
    例如以下程式碼:
x = 10
def myFunction():
    x = 5
    print("在函數裡面x的值為", x)
myFunction()
print("在函數外面x的值為", x)

這支程式做了幾件事情:

  1. 一開始設定x的值為10
  2. 我們定義一個函數,叫作myFunction(),
    希望去修改x的值。我們在第五行呼叫它。
  3. 我們分別在函數內、外使用print(),試著印出x的值

結果為:
在函數裡面x的值為 5
在函數外面x的值為 10
在函數裡面更改x的值是不影響全域變數 x的。
那麼怎麼樣可以用函數真的改到x的值呢?
所以要加上global x這句話,
告訴程式現在x要當做全域變數來操作,
而不是當成區域變數

更改後程式如下:

x = 10
def myFunction():
    global x
    x = 5
    print("在函數裡面x的值為", x)
myFunction()
print("在函數外面x的值為", x)

結果為
在函數裡面x的值為 5
在函數外面x的值為 5

  1. 數字加總還有其他寫法嗎?
    有點不確定您想問的意思,
    你是想問有沒有方法寫的更簡單嗎?
    由於我們希望每次玩家答對時,
    才去修改分數(即把分數加1),
    小馬尚未想到其它好的寫法。
    抱歉這次篇幅有點長~
    感謝您的耐心閱讀。

哇!了解~~感謝你的耐心解說 第三個問題其實是在問上一篇(10)的

scores = [50,60,35,20,40,0]
totolScore = 0 #用totolScore變數儲存全班的分數總和
for s in scores: #在迴圈中把每個人的分數加總
totolScore +=s

有點好奇是否有不用先將變數指定為0的寫法?
抱歉~不小心在這篇問了哈哈

哈哈~ 我了解你的問題了,
由於本系列文是新手教學,
所以我選擇用基礎的程式邏輯來寫數字加總。
但其實python語言的特性是簡潔
它有許多好用內建函數可以讓程式更簡短好懂,
譬如說把列表中的數字加總只需用內建sum()函數即可:

scores = [50,60,35,20,40,0]
totolScore = sum(scores)

哦哦原來 感謝你回答我這麼多新手問題哈哈~~

我要留言

立即登入留言