#20 基本Swift選擇題App

將目前為止所學Swift 基本且想得到的觀念作為選擇題題目。

實現功能

  • 從 Airtable 輸入問題與答案,將輸出的 csv 變成 array
  • 題庫有 15 題,隨機出其中的 10 題,每次玩的時候題目順序都不一樣
  • 每題有3個選項,每題3個選項的順序不固定
  • 答對一題加 10 分
  • 畫面上顯示目前題目是第幾題
  • 結束單局使用 UIAlertController顯示結果

建立問題與答案

題目建立

第一次使用Airtable,其實就像Google試算表,但是可不只是當作資料輸入還可以作為不同型態的database的介面,譬如旅遊規劃,專案管理…等。

  1. 資料輸入完後下載成csv格式,完整檔名為basicswift.csv
  2. 將檔案置入Xcode專案裡的Assets資料夾
  3. 安裝CodableCSV 第三方套件

建立資料接入的Quetions.swift

  1. 建立BasicSwift的struct,型別為Codable
  2. 建立問答題目內,宣告相對應的項目包含question、correctAnswer、wrongAnwser1和wrongAnwser2
  3. 另外宣告options的computing property可以將答案們組成選項array
struct BasicSwift: Codable {
let question: String
let correctAnswer: String
let wrongAnwser1: String
let wrongAnwser2: String

var options: [String] {
return [correctAnswer,wrongAnwser1,wrongAnwser2]
}
}

接下來就比較難理解,所以複製貼上修改。

extension BasicSwift {
static var data: [Self] {
var array = [Self]()
if let data = NSDataAsset(name: "basicswift")?.data {
let decoder = CSVDecoder {
$0.headerStrategy = .firstLine
}
do {
array = try decoder.decode([Self].self, from: data)
} catch {
print(error)
}
}
return array
}
}

建立介面狀態的State.swift

判別答案正確或錯誤的列舉

  1. 宣告wrong, right兩個case
  2. 宣告image,定義兩個狀態的顯示圖片
  3. 宣告color,定義兩個狀態的顯示顏色
enum answerState {
case wrong, right

var image: UIImage {
switch self {
case .wrong:
return UIImage(systemName: "x.square")!
case .right:
return UIImage(systemName: "checkmark.square")!
}
}
var color: UIColor {
switch self {
case .wrong:
return .red
case .right:
return .green
}
}
}

判別總得分等級的列舉

  1. 宣告high, middle, low三個case
  2. 宣告description,定義三個等級的描述
enum Level {
case high, middle, low

var description: String {
switch self {
case .high:
return "已經了解核心概念了,可以往下一階段邁進!"
case .middle:
return "已具備基本iOS程式開發知識!"
case .low:
return "好像還要重新複習一下?!加油!"
}
}
}

建立遊戲機制的Game.swift

宣告Game類別

問答資料的機制

  • 宣告questions實例化前面建立的問答資料
  • 宣告totalRound定義遊戲的局數
  • 宣告indextOfQuestion定義答案選項陣列的index
  • 宣告roundProcess與imageOfIndex定義題目數與顯示圖片
class Game {    var questions = BasicSwift.data    
let totalRound = 10
var indextOfQuestion = 0
var roundProcess: Int { return indextOfQuestion + 1 }
var imageOfIndex: UIImage {
return UIImage(systemName: "\(roundProcess).square.fill")!
}

遊戲分數的機制

  • 宣告scores以記錄總得分
  • 宣告scorePerRoundWon,定義猜對題目的得分
  • 宣告scoreResult,判別得分分數對應到的等級列舉
    var scores = 0
let scorePerRoundWon = 10
var scoreResult: Level {
switch scores {
case 90...100: return .high
case 60...89: return .middle
default: return .low
}
}

問答正確錯誤的機制

  • 宣告guessState,紀錄回答是否正確
  • 宣告guessState函數,判別選擇的答案是否與正確答案匹配,回答正確+10分
    var guessState = answerState.right    func guessState(userGuess sender: UIButton) {

if questions[indextOfQuestion].correctAnswer == sender.currentTitle {
scores += scorePerRoundWon
guessState = .right
}else {
guessState = .wrong
}
}

單局遊戲的機制

當目前局數為總局數時則為遊戲結束,反之則正在進行中。

    var gameState: GameState {
return roundProcess == totalRound ? .over : .ongoing
}
}

--

--