You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift测验游戏Answer结构体重置逻辑问题求助

问题解决方案

核心问题分析

  1. 值类型拷贝导致数据不同步:Quiz初始化时rounds = Answer.allAnswers是值拷贝,后续Answer.allAnswers更新后,Quiz内部的rounds仍是旧数组,不会自动同步。
  2. 方法调用错误:Answer的resetAnswers是实例方法,但你调用的是Answer.resetAnswers()(类型方法),编译会报错,且无法修改静态数组。
  3. 无索引边界检查:advanceRound未判断是否已到最后一轮,直接递增索引会导致越界。

分步修复代码

1. 修复Answer的重置方法为静态方法

将resetAnswers改为静态方法,确保能通过类型调用并更新静态数组:

import Foundation

let roots = ["A", "B", "C", "D", "E", "F", "G"]
let chordType = ["Major", "Minor"]

func chooseChord() -> String {
    let randomRoot = roots.randomElement()!
    let randomType = chordType.randomElement()!
    let randomChord = randomRoot + randomType
    return randomChord
}

func genAnswer() -> (String, [String]) {
    var answers = [String]()
    while answers.count < 4 {
        let randChord = chooseChord()
        if !answers.contains(randChord) {
            answers.append(randChord)
        }
    }
    let correctAnswer = answers.randomElement()!
    return (correctAnswer, answers)
}

struct Answer {
    private(set) var correctAnswer: String
    private(set) var possibleAnswers: [String]
    
    init() {
        let answer = genAnswer()
        self.correctAnswer = answer.0
        self.possibleAnswers = answer.1
    }
    
    static var allAnswers: [Answer] = [
        Answer(),
        Answer(),
        Answer(),
        Answer(),
        Answer()
    ]
    
    // 修改为静态方法
    static func resetAnswers() {
        var newAnswers = [Answer]()
        for _ in 1...Answer.allAnswers.count {
            newAnswers.append(Answer())
        }
        Answer.allAnswers = newAnswers
    }
}

2. 更新Quiz的重置逻辑与边界检查

在reset方法中同步rounds数组,同时添加索引越界防护:

import Foundation

class Quiz {
    private var rounds = Answer.allAnswers
    private var currentRoundIndex = 0
    
    var currentRound: Answer {
        return rounds[currentRoundIndex]
    }
    
    var totalRounds: Int {
        rounds.count - 1
    }
    
    // 新增:判断是否可进入下一轮
    func canAdvance() -> Bool {
        currentRoundIndex < rounds.count - 1
    }
    
    func advanceRound() {
        guard canAdvance() else {
            // 已到最后一轮,可在此添加测验结束逻辑
            return
        }
        currentRoundIndex += 1
    }
    
    func reset() {
        Answer.resetAnswers()
        // 同步最新的问题数组
        rounds = Answer.allAnswers
        currentRoundIndex = 0
    }
}

3. 给QuizViewModel添加重置方法

供UI层调用以重置整个测验:

import Foundation

class QuizViewModel: ObservableObject {
    @Published var game = Quiz()
    
    var correctAnswerText: String {
        game.currentRound.correctAnswer
    }
    
    func answerText() -> [String] {
        game.currentRound.possibleAnswers
    }
    
    var totalRounds: Int {
        return game.totalRounds
    }
    
    func advanceGame() {
        game.advanceRound()
    }
    
    // 新增:重置游戏方法
    func resetGame() {
        game.reset()
    }
}

关键优化说明

  • 将Answer的getter方法替换为private(set)属性,更符合Swift的面向值编程风格,减少冗余代码。
  • Quiz的canAdvance方法可用于UI层判断是否显示"下一题"按钮,避免无效操作。
  • 重置时手动同步rounds数组,解决值类型拷贝导致的数据不同步问题。

内容的提问来源于stack exchange,提问作者Ness Earthbound

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 12:15:31