十五人游戏 (Swift):额外触摸以确认所有按钮均已排列

Game of Fifteen (Swift): extra touch to confirm all the buttons are arranged

谁能告诉我逻辑有什么问题吗?
我做了一个十五的游戏,遇到了一个问题。 我需要确保所有十五个按钮都以正确的方式排列:

逻辑:
每次触摸按钮
1. 函数 makeMove() 改变按钮的位置 .
2.函数checkGameOver()检查所有的按钮是否排列正确, 如果是,则函数 showAlert() 使弹出窗口 window 出现。

问题:
放置所有按钮后,showAlert() 不会触发并且 我需要再次触摸任何按钮才能弹出 window

谢谢。

func makeMove(button: UIButton) {
        var currentButtonNumber = button.tag - 1
        if ( currentButtonNumber >= 0 && currentButtonNumber <= 15 ) && button.tag != 4 && button.tag != 8 && button.tag != 12 {
            guard buttons[button.tag - 1].backgroundColor != .none else {
                buttons[button.tag - 1].backgroundColor = .yellow
                buttons[button.tag - 1].setTitle(button.titleLabel?.text, for: .normal)
                buttons[button.tag].backgroundColor = .none
                button.setTitle("", for: .normal)
                return
            }
        }

        currentButtonNumber = button.tag + 1
        if ( currentButtonNumber >= 0 && currentButtonNumber <= 15 ) && button.tag != 3 && button.tag != 7 && button.tag != 11 {
            guard buttons[button.tag + 1].backgroundColor != .none else {
                buttons[button.tag + 1].backgroundColor = .yellow
                buttons[button.tag + 1].setTitle(button.titleLabel?.text, for: .normal)
                buttons[button.tag].backgroundColor = .none
                button.setTitle("", for: .normal)
                return
            }
        }

        currentButtonNumber = button.tag - 4
        if currentButtonNumber >= 0 && currentButtonNumber <= 15 {
            guard buttons[button.tag - 4].backgroundColor != .none else {
                buttons[button.tag - 4].backgroundColor = .yellow
                buttons[button.tag - 4].setTitle(button.titleLabel?.text, for: .normal)
                buttons[button.tag].backgroundColor = .none
                button.setTitle("", for: .normal)
                return
            }
        }

        currentButtonNumber = button.tag + 4
        if currentButtonNumber >= 0 && currentButtonNumber <= 15 {
            guard buttons[button.tag + 4].backgroundColor != .none else {
                buttons[button.tag + 4].backgroundColor = .yellow
                buttons[button.tag + 4].setTitle(button.titleLabel?.text, for: .normal)
                buttons[button.tag].backgroundColor = .none
                button.setTitle("", for: .normal)
                return
            }
        }

    }
    func showAlert() {
        var minutes = 0
        var seconds = 0

        if timerCounter < 60 {
            seconds = timerCounter
        } else if timerCounter == 60 {
            minutes = 1
            seconds = 0
        } else {
            seconds = timerCounter % 60
            minutes = (timerCounter - seconds) / 60
        }

        let alert = UIAlertController(title: "Congratulations!",
                                      message: "You spent \(minutes) minutes and \(seconds) seconds", preferredStyle: .alert)

        let action = UIAlertAction(title: "OK",
                                   style: .default, handler: {
                                    action in
                                    self.setNewGame() 
        })

        alert.addAction(action)

        present(alert, animated: true, completion: nil)
    }

    func checkGameOver() -> Bool {
        var isGameOver = false
        var rightOrderCounter = 0

        for number in 0...14 {
            if (buttons[number].titleLabel?.text == String(number + 1)) {
                rightOrderCounter += 1
            } else {
                rightOrderCounter = 0
                break
            }
        }

        if rightOrderCounter == 15 {
            isGameOver = true
        }

        return isGameOver

    }

    @IBAction func moveButton(button: UIButton) {

        makeMove(button: button)

        if self.checkGameOver() {
            self.stopTimer()
            self.showAlert()
        }

    }

您的错误是使用按钮的标题作为您的模型。问题是用 setTitle(:for:) 设置按钮的标题不一定要在您离开主线程之后才会发生。因此,当您检查当前 titleLabel 时,它尚未更新并反映了之前的状态。

更好的方法是使用 Int 数组来 建模 您的拼图,并使用此数组更新按钮的标题。您的 checkGameOver() 方法应该检查此数组的顺序而不是按钮的标题。

一般的经验法则是:永远不要使用 UI 元素来存储你的状态