十五人游戏 (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 元素来存储你的状态
谁能告诉我逻辑有什么问题吗?
我做了一个十五的游戏,遇到了一个问题。
我需要确保所有十五个按钮都以正确的方式排列:
逻辑:
每次触摸按钮
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 元素来存储你的状态