CS50AI扫雷代码出现IndexError: list index out of range错误求助
问题排查与修复:CS50AI扫雷程序IndexError崩溃
核心错误根源:非法坐标生成
程序崩溃的直接原因是AI生成了超出棋盘范围的坐标,导致is_mine方法访问数组时触发IndexError。以下是具体问题及修复方案:
1. 相邻单元格遍历的边界判断错误
在MinesweeperAI.add_knowledge方法中,遍历目标单元格相邻区域时,存在两个致命逻辑错误:
- 坐标与边界对应关系搞反:行索引
i应与棋盘高度height比较,列索引j应与棋盘宽度width比较,但原代码中错误地将列索引与高度、行索引与宽度做对比。 - 边界条件使用错误:棋盘索引范围是
0到height-1/width-1,原代码使用>判断边界,导致等于height/width的非法索引未被过滤。
原错误代码片段:
up = cell[1] - 1 down = cell[1] + 1 left = cell[0] - 1 right = cell[0] + 1 horizontal_boundary = self.width vertical_boundary = self.height for i in range(left, right + 1): for j in range(up, down + 1): if j < 0 or j > vertical_boundary or i < 0 or i > horizontal_boundary or (i,j) == cell: continue
修正后代码片段:
# 明确行、列的边界范围 start_row = cell[0] - 1 end_row = cell[0] + 1 start_col = cell[1] - 1 end_col = cell[1] + 1 row_boundary = self.height col_boundary = self.width for i in range(start_row, end_row + 1): for j in range(start_col, end_col + 1): # 正确过滤超出边界的索引和当前单元格 if i < 0 or i >= row_boundary or j < 0 or j >= col_boundary or (i,j) == cell: continue
2. 知识更新循环的标记变量未正确初始化
在add_knowledge的知识迭代更新环节,knowledge_changed变量未在每次循环开始时重置为False,会导致循环无法正确终止,进而引发后续逻辑混乱。
修正后的循环逻辑:
modified = True while modified: modified = False safes = set() mines = set() knowledge_changed = False # 每次循环初始化标记 # 收集所有可确定的安全单元格和地雷 for sentence in self.knowledge: safes.update(sentence.known_safes()) mines.update(sentence.known_mines()) # 标记安全单元格 if safes: knowledge_changed = True for safe in safes: self.mark_safe(safe) # 标记地雷单元格 if mines: knowledge_changed = True for mine in mines: self.mark_mine(mine) # 移除空语句(优化判断逻辑) self.knowledge = [x for x in self.knowledge if x.cells or x.count != 0] # 推理新的逻辑语句 new_sentences = [] for s1 in self.knowledge: for s2 in self.knowledge: if s1 is s2 or not s1.cells or not s2.cells: continue if s1.cells.issubset(s2.cells): new_cells = s2.cells - s1.cells new_count = s2.count - s1.count new_sent = Sentence(new_cells, new_count) if new_sent not in self.knowledge and new_sent not in new_sentences: new_sentences.append(new_sent) if new_sentences: knowledge_changed = True self.knowledge.extend(new_sentences) modified = knowledge_changed
3. 随机移动方法不符合随机要求
原make_random_move方法会返回第一个符合条件的单元格,而非随机选取。修正为收集所有合法单元格后随机选择:
def make_random_move(self): possible_moves = [] for i in range(self.height): for j in range(self.width): move = (i, j) if move not in self.moves_made and move not in self.mines: possible_moves.append(move) if possible_moves: return random.choice(possible_moves) return None
内容的提问来源于stack exchange,提问作者Gustavo Velandia
相关产品推荐
相关产品推荐

