#16 選擇題App — 難讀漢字

中文使用者看到日文漢字都能以形來猜意思,去日本自由行暢行無阻,但對於日文學習者來說,不光要認也要會唸,記住日文漢字的讀音需要另下功夫,背了又忘也是常有的事^^”

這次做的是基本的選擇題App,挑了一些難讀的日文漢字當題目,主要有下面這些功能

  • 題庫隨機抽10題,每題4個選項隨機排列
  • 答對一題得10分,畫面上顯示分數
  • 以進度條及文字顯示目前第幾題
  • 自訂資料型別
  • 遊戲結束後跳出總分

程式部分①自訂資料型別

新增file,宣告結構體question,在struct內宣告三個變數,分別是用來存放題目的description、存放正確答案的answer、存放選項的option
每題選項有四個,所以只有option用陣列存放

程式部分②宣告變數、拉outlet

宣告一個存放題目的陣列,存放的是剛才建立的結構體,每個結構體裡有三種屬性。寫完發現名字取太像,寫的時候有點搞混XD

var Questions = [question]()

宣告題目索引 index、分數score、正確答案correctAnswer

var index = 0 
var score = 0
var correctAnswer = ""

拉outlet

@IBOutlet weak var questionLbl: UILabel!

@IBOutlet weak var numberLbl: UILabel!

@IBOutlet weak var scoreLbl: UILabel!
//把四個選項的button都拉到同一個outlet collection
@IBOutlet var answer: [UIButton]!

@IBOutlet weak var progressBar: UIProgressView!

程式部分③建立題目、題目洗牌

寫的時候練習了三種寫法,比較偏好第二種

1.

var Questions = [question]()let question1 = question(description: "蝙蝠", answer: "こうもり", option: ["ぺんふく", "へんぷう", "こうもり", "もうふり"])
Questions.append(question1)
let question2 = question(description: "啄木鳥", answer: "きつつき", option: ["きつつき", "たくぼくちょう", "たっきちょう", "つきき"])
Questions.append(question2)

2.

var Questions = [question]()Questions.append(question(description: "蝙蝠", answer: "こうもり", option: ["ぺんふく", "へんぷう", "こうもり", "もうふり"]))
Questions.append(question(description: "啄木鳥", answer: "きつつき", option: ["きつつき", "たくぼくちょう", "たっきちょう", "つきき"]))

3.

var Questions = [
question(description: "蝙蝠", answer: "こうもり", option: ["ぺんふく", "へんぷう", "こうもり", "もうふり"]),
question(description: "啄木鳥", answer: "きつつき", option: ["きつつき", "たくぼくちょう", "たっきちょう", "つきき"])
]

程式部分④把遊戲開始的動作寫成函數

func gamePlay(){            //選項洗牌
Questions[index].option.shuffle()
//顯示題目
questionLbl.text = Questions[index].description
//存入正確答案
correctAnswer = Questions[index].answer
//設置選項
for i in 0...3{
answer[i].setTitle(Questions[index].option[i], for: .normal)
}
//顯示第幾題
numberLbl.text = "第\(index+1)問"
}

程式部分⑤設置選答案的動作

@IBAction func clickAnswer(_ sender: UIButton) {        //答完一題索引要+1(進入下一題)
index += 1
//進度條跟著跑,1代表100%,共10題,一題是0.1
progressBar.progress += 0.1
/* 檢查用
print(index)
print(progressBar.progress)
*/

//如果按下的選項等於正確答案,加10分並顯示分數
if sender.currentTitle == correctAnswer{
score += 10
scoreLbl.text = String(score)
}
//過了第10題就不繼續遊戲
if index < 10{
gamePlay()
}
else{
gameOver()
}

}

程式部分⑥設置重新開始的動作

索引、分數都變回0,進度條退回第一題的狀態,題目再次洗牌,遊戲進行

@IBAction func restart(_ sender: Any) {
index = 0
score = 0
scoreLbl.text = String(score)
progressBar.progress = 0.1
Questions.shuffle()
gamePlay()
}

程式部分⑦設置遊戲結束的動作、彈跳視窗

上次也有寫彈跳視窗的程式,這次用「有參數無回傳」的function簡化程式碼

func alertMessage(switchTitle: String, switchMessage: String){

let alert = UIAlertController(
title: switchTitle,
message: switchMessage,
preferredStyle: .alert)

let okAction = UIAlertAction(title: "もう一度挑戦する",
style: .default,
handler: (restart(_:)))
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
}

在gameOver的函數裡重複呼叫alertMessage,同時設定title跟message

翻譯蒟蒻:
まさに漢字の神です! → 你是名副其實的漢字之神!
漢字の修練は、まだ終わりませんね! → 漢字的修煉還沒有結束!
国語の授業は、ちゃんと受けていましたか? → 以前有認真上國文課嗎?

func gameOver(){

if score >= 80{
alertMessage(switchTitle: "score:\(score)", switchMessage: "まさに漢字の神です!")
}
else if score < 80 && score > 60{
alertMessage(switchTitle: "score:\(score)", switchMessage: "漢字の修練は、まだ終わりませんね!")
}
else{
alertMessage(switchTitle: "score:\(score)", switchMessage: "国語の授業は、ちゃんと受けていましたか?")
}
}

}

成果展示

GitHub

參考文章

--

--

xxinlei
彼得潘的 Swift iOS / Flutter App 開發教室

不務正業的日文筆譯,半個AR Creator,正在用力成為iOS Developer