为何在井字棋实现中,多维列表调用containsAll始终返回false?
问题原因分析
你的代码里containsAll始终返回false,核心问题有两个:
- 数据结构不匹配:
decisions里的元素是一维列表(比如listOf(0,1,2),代表第一行的三个全局位置索引),但whereXPlaced/whereOPlaced是3x3的二维列表,两者元素类型完全不同,containsAll自然找不到匹配项。 - 位置记录逻辑错误:给
whereXPlaced[i][j]赋值j的操作,只是存了列号,并没有正确记录X在棋盘上的全局索引(0-8),完全偏离了判断获胜的逻辑。
正确实现思路
判断获胜的核心是:收集所有X/O的全局位置索引(比如第一行第一格是0,第二格是1…第三行第三格是8),然后检查是否存在一个获胜组合(来自原decisions)的所有元素都在这个集合里。
修正后的代码
fun main() { val userInput = readln() // 收集X和O的全局位置索引(0-8) val xPositions = mutableSetOf<Int>() val oPositions = mutableSetOf<Int>() for (index in userInput.indices) { when (userInput[index]) { 'X' -> xPositions.add(index) 'O' -> oPositions.add(index) } } // 获胜组合列表(修正了原代码中第三列的错误) val winCombos = listOf( setOf(0, 1, 2), setOf(3, 4, 5), setOf(6, 7, 8), setOf(0, 3, 6), setOf(1, 4, 7), setOf(2, 5, 8), setOf(0, 4, 8), setOf(2, 4, 6) ) // 检查是否有任意一个获胜组合被X/O的位置完全包含 val xWins = winCombos.any { combo -> xPositions.containsAll(combo) } val oWins = winCombos.any { combo -> oPositions.containsAll(combo) } when { xWins -> println("x win") oWins -> println("o win") else -> println("draw or ongoing") } }
额外说明
- 使用
Set存储位置比List更高效,且避免重复值; - 原代码的
decisions存在错误:第三列的获胜组合应该是listOf(2,5,8),你写成了listOf(2,6,8),这会导致第三列获胜判断失效; - 用
any函数遍历获胜组合,只要有一个组合被完全包含就判定获胜,这才是符合逻辑的判断方式。
内容的提问来源于stack exchange,提问作者Souke Chan
相关产品推荐
相关产品推荐

