如何追踪国际象棋兵模拟代码的Runtime Error?
问题描述
这段代码用于模拟国际象棋棋盘上两个兵的交替移动:兵每次仅能向前移动一格,不能处于同一列;获胜条件为率先抵达对方棋盘底线,或按规则吃掉对方兵。
将代码提交至在线评测系统后,所有测试用例均通过,仅一个测试用例出现Runtime Error。尝试了所有能想到的输入变体,但仍无法复现该问题。
输入格式示例
(w代表白兵,b代表黑兵)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - b - - - - - - - - - - - - - - w - - - - - - - - - - - - - -
代码实现
matrix = [[x for x in input().split()] for row in range(8)] # matrix 8x8 chess_col = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] # reference list of the chess columns chess_row = [8, 7, 6, 5, 4, 3, 2, 1] # reference list of the chess rows row_w, col_w, row_b, col_b = 0, 0, 0, 0 square = [] # to store reference values of chess col and row for calculating the final position of the winning pawn. win = False promoted = False # for loop to determine position of the pawns for row in range(8): for col in range(8): if matrix[row][col] == 'w': row_w = row col_w = col if matrix[row][col] == 'b': row_b = row col_b = col # starting with white pawn while True: # check if black pawn position is in one of diagonals on the next row if matrix[row_w - 1][col_w - 1] == 'b' or matrix[row_w - 1][col_w + 1] == 'b': win = True winning_pawn = 'White' # taking the reference values row = [chess_row[x] for x in range(len(chess_row)) if x == row_b] col = [chess_col[x] for x in range(len(chess_col)) if x == col_b] square.append(col[0] + str(row[0])) break # moving the pawn in the matrix(only foreword) matrix[row_w][col_w] = '-' row_w -= 1 matrix[row_w][col_w] = 'w' # if the pawn reach end of the board if row_w == 0: promoted = True winning_pawn = 'White' row = [chess_row[x] for x in range(len(chess_row)) if x == row_w] col = [chess_col[x] for x in range(len(chess_col)) if x == col_w] square.append(col[0] + str(row[0])) break if matrix[row_b + 1][col_b - 1] == 'w' or matrix[row_b + 1][col_b + 1] == 'w': win = True winning_pawn = 'Black' row = [chess_row[x] for x in range(len(chess_row)) if x == row_w] col = [chess_col[x] for x in range(len(chess_col)) if x == col_w] square.append(col[0] + str(row[0])) break matrix[row_b][col_b] = '-' row_b += 1 matrix[row_b][col_b] = 'b' if row_b == 7: promoted = True winning_pawn = 'Black' row = [chess_row[x] for x in range(len(chess_row)) if x == row_b] col = [chess_col[x] for x in range(len(chess_col)) if x == col_b] square.append(col[0] + str(row[0])) break if win: print(f"Game over! {winning_pawn} win, capture on {''.join(square)}.") elif promoted: print(f"Game over! {winning_pawn} pawn is promoted to a queen at {''.join(square)}.")
提问
请问追踪此类代码运行时错误的最佳方法是什么?
解决方案:追踪运行时错误的实用步骤
针对你遇到的「本地无法复现、仅在线评测系统触发Runtime Error」的情况,可按以下方向排查:
1. 优先排查数组越界问题
你的代码中多处直接访问row_w-1、col_w±1等索引,完全未做边界校验,这是Runtime Error的高发原因:
- 当白兵处于第0列(
col_w=0)时,col_w-1会变成-1,访问matrix[row_w-1][-1]直接触发索引越界; - 当白兵已经在第0行(对方底线),进入循环后执行
row_w-1会得到-1,同样越界; - 黑兵处于第7列时,
col_b+1=8,超出矩阵的列范围(0-7)。
这些极端场景很可能就是评测系统中的触发用例。
2. 校验输入合法性
虽然题目描述输入是合法棋盘,但评测用例可能包含异常情况:
- 棋盘缺失
w或b,导致row_w、col_w等变量保持初始值0,后续访问matrix[-1][...]直接越界; - 棋盘出现多个
w/b,导致最后一个棋子的位置覆盖之前的,引发逻辑错误。
建议在代码开头增加校验逻辑:
found_w = found_b = False for row in range(8): for col in range(8): if matrix[row][col] == 'w': row_w, col_w = row, col found_w = True if matrix[row][col] == 'b': row_b, col_b = row, col found_b = True if not found_w or not found_b: # 按题目要求处理异常输入,比如直接退出 exit()
3. 构造极端边界测试用例
手动模拟你之前忽略的场景:
- 白兵在a2(代码中
row=6, col=0),黑兵在b3(row=5, col=1):白兵尝试访问col_w-1=-1; - 白兵已经在第0行(对方底线),进入循环后直接执行
row_w-1; - 黑兵在h7(
row=1, col=7),尝试访问col_b+1=8。
4. 利用在线评测系统的调试功能
如果评测系统支持:
- 查看运行时错误详情:部分OJ会显示错误类型(如
IndexError)及错误发生的行号,直接定位问题; - 提交带日志的版本:在关键步骤打印变量值(如
row_w、col_w的当前值),通过日志定位错误触发时机。
5. 代码健壮性修复示例
针对你的代码,先修复最可能触发错误的边界判断:
# 白兵吃子判断修改为带边界检查的版本 can_capture_white = False if row_w - 1 >= 0: # 确保白兵还能向前走 if col_w - 1 >= 0 and matrix[row_w - 1][col_w - 1] == 'b': can_capture_white = True elif col_w + 1 < 8 and matrix[row_w - 1][col_w + 1] == 'b': can_capture_white = True if can_capture_white: win = True winning_pawn = 'White' row = chess_row[row_b] col = chess_col[col_b] square.append(f"{col}{row}") break
同时给黑兵的吃子判断加上相同的边界校验,避免越界访问。
内容的提问来源于stack exchange,提问作者Atanas Dinkov
相关产品推荐
相关产品推荐

