You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:49:54