Swift版井字棋应用电脑获胜时胜利计数异常问题求助
井字棋人机对战胜利计数异常问题
问题描述
开发Swift井字棋应用时出现以下异常:
- 双人对战模式下,玩家胜利计数逻辑正常
- 人机对战模式下,电脑获胜后其胜利数始终停留在0,无法正确递增
- 怀疑问题出在
checkForWinner()函数或人机对战场景的胜利计数逻辑
问题原因分析
1. 错误的提前返回逻辑阻断胜负检测
在checkForWinner()函数开头存在以下代码:
if GameSettings.shared.playAgainstComputer && currentPlayer == 2 { if !boardArray.contains("") { return "It's a tie!" } return nil }
该逻辑会直接跳过后续胜负检测流程:当人机对战且当前回合是电脑(玩家2)时,无论是否达成获胜条件,都会返回nil,导致电脑获胜的情况无法被识别。
2. 依赖currentPlayer判断获胜方的逻辑错误
在胜负检测分支中,人机对战模式下的计数逻辑依赖currentPlayer判断:
// X获胜分支 if GameSettings.shared.playAgainstComputer { if currentPlayer == 1 { countPlayer1 += 1 } } // O获胜分支 if GameSettings.shared.playAgainstComputer { if currentPlayer == 2 { countPlayer2 += 1 } }
但在buttonTapped()流程中,落子完成后会立刻调用switchPlayers()切换玩家。当电脑(玩家2)落子完成后,currentPlayer已被切换为1,此时判断currentPlayer == 2必然不成立,导致countPlayer2无法递增。
修复方案
1. 移除错误的提前返回逻辑
删除checkForWinner()函数开头的以下代码块:
if GameSettings.shared.playAgainstComputer && currentPlayer == 2 { if !boardArray.contains("") { return "It's a tie!" } return nil }
2. 修改获胜计数逻辑,直接根据棋子对应玩家
不再依赖currentPlayer,而是根据获胜的棋子类型(X/O)直接对应计数:
- X对应玩家1,直接递增
countPlayer1 - O对应玩家2(电脑),直接递增
countPlayer2
修复后的checkForWinner()函数:
func checkForWinner() -> String? { let winningPatterns: [[Int]] = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ] for pattern in winningPatterns { let positions = pattern.map { boardArray[$0] } if positions == ["X", "X", "X"] { countPlayer1 += 1 return "Congrats \(playerOneName ?? "X"), you won!" } else if positions == ["O", "O", "O"] { countPlayer2 += 1 return "Congrats \(playerTwoName ?? "O"), you won!" } } if boardArray.contains("") { return nil } else { return "Oh, it's a beautiful tie!" } }
3. 优化配置项访问(可选)
GameViewController中缓存的playAgainstComputer属性可能存在过期风险,建议直接访问单例的实时值,替换所有self.playAgainstComputer为GameSettings.shared.playAgainstComputer。
最佳实践建议
- 避免依赖切换后的玩家状态判断胜负:落子完成后会立刻切换玩家,此时
currentPlayer代表下一个回合的玩家,而非刚完成落子的玩家,应通过落子的棋子类型直接关联对应的玩家计数。 - 不要在胜负检测中加入无关的提前返回逻辑:提前返回会导致部分场景的胜负判断被跳过,需保证所有可能的获胜/平局情况都能被完整检测。
- 单例配置项直接访问:对于全局配置的单例对象,直接访问其属性而非缓存值,避免因配置更新导致的逻辑异常。
内容的提问来源于stack exchange,提问作者AranAli
相关产品推荐
相关产品推荐

