终端数独游戏程序问题排查:初始数组棋盘与制表渲染棋盘不一致
问题排查与修复方案
我仔细捋了你的代码,发现导致原始board数组和渲染表格内容不一致的核心问题出在table_print()函数的表格拼接逻辑上,另外win_check()也有几处影响功能的bug,下面逐一拆解并给出修复方案:
1. 核心问题:表格渲染逻辑错误,行列结构被强行重组
你当前的table_print()把9x9的board拆成了9个3x3小表格,然后按「大九宫格的行」来横向拼接——比如把所有行的前三列拼成一块、中间三列拼成一块,再把这三块并排显示。这完全打乱了原始board的行结构,导致渲染出的表格和实际board数组的内容对应不上。
举个直观的例子:原始board第0行是[a,b,c,d,e,f,g,h,i],但你的渲染逻辑会把所有行的a,b,c集中在第一块,所有行的d,e,f集中在第二块,最终显示的第一大段是前3行的前三列,第二大段是前3行的中间三列,这和数独正常的「每行9个数字连续排列」的结构完全不符,自然和你打印的原始board数组看起来对不上。
2. 完整修复步骤
步骤1:重构table_print,正确渲染数独结构
我们不需要拆成一堆小表格,直接基于原始board的行结构,在每3行、每3列之间添加分隔线,用tabulate的grid格式就能轻松实现符合视觉习惯的数独排版。
步骤2:修复win_check的功能bug
- 用户输入的行/列号是字符串,需要转成整数,且要从用户习惯的1-9转成数组的0索引
- 原来的递归调用会导致无限循环,改成循环结构更合理
- 缺失胜利条件判断,需要新增数独合法性检查和填满判断
修复后的完整代码
import random from tabulate import tabulate base = 3 side = base**2 level = 1 def create_table(row, column): return (base * (row % base) + row // base + column ) % side def shuffling(s): return random.sample(s, len(s)) # 生成合法数独终局 row_base = range(base) rows = [var1*base + row for var1 in shuffling(row_base) for row in shuffling(row_base)] cols = [var1*base + column for var1 in shuffling(row_base) for column in shuffling(row_base)] nums = shuffling(range(1, side+1)) board = [[nums[create_table(row, column)] for column in cols] for row in rows] # 优化挖空逻辑:按难度控制挖空数量 empty_cells = level * 20 # level1挖20个,level2挖30个,可按需调整 for _ in range(empty_cells): row = random.randint(0, side-1) col = random.randint(0, side-1) board[row][col] = "" def table_print(): display_board = [] for i, row in enumerate(board): display_row = [] for j, val in enumerate(row): # 空位置显示空格,更美观 display_row.append(val if val != "" else " ") # 每3列添加竖分隔符 if (j+1) % base == 0 and j != side-1: display_row.append("|") display_board.append(display_row) # 每3行添加横分隔符 if (i+1) % base == 0 and i != side-1: separator = ["-"*2 if k%2 ==0 else "+" for k in range(len(display_row))] display_board.append(separator) # 用grid格式打印,结构清晰对齐 print(tabulate(display_board, tablefmt="grid", stralign="center")) def is_valid(row, col, num): # 检查行是否重复 if num in board[row]: return False # 检查列是否重复 if num in [board[i][col] for i in range(side)]: return False # 检查所在3x3九宫格是否重复 start_row = (row // base) * base start_col = (col // base) * base for i in range(start_row, start_row + base): for j in range(start_col, start_col + base): if board[i][j] == num: return False return True def win_check(): while True: table_print() # 明确提示输入格式,降低用户出错概率 print("输入格式:enter,数字,行号(1-9),列号(1-9) | 输入quit退出游戏") your_command = input("请输入指令:").strip().split(",") # 输入格式校验 if len(your_command) !=4: print("格式错误!请按照提示输入哦~") continue function, entered_number, row_str, col_str = your_command if function.lower() == "quit": print("游戏结束啦!") break if function.lower() != "enter": print("未知指令,请输入enter或quit!") continue # 转换输入为整数并校验范围 try: num = int(entered_number) row = int(row_str) -1 # 转成数组的0索引 col = int(col_str) -1 if num <1 or num>9 or row<0 or row>=9 or col<0 or col>=9: print("数字必须是1-9,行/列号必须是1-9哦!") continue except ValueError: print("数字和行/列号必须是整数呀!") continue # 检查位置是否为空 if board[row][col] != "": print("这个位置已经有数字啦,换个空位置试试~") continue # 检查数字是否符合数独规则 if not is_valid(row, col, num): print("这个数字不符合数独规则哦,再想想!") continue # 填入数字 board[row][col] = num # 检查是否完成数独 if all(all(cell != "" for cell in row) for row in board): print("🎉 恭喜你!成功完成数独谜题!") break # 启动游戏 win_check()
修复效果说明
- 表格一致性:现在渲染的表格和原始board数组内容完全对应,排版符合数独的视觉习惯,每3行3列的大九宫格有明显分隔。
- 挖空合理性:替换了原来可能导致挖空数量异常的循环,改成按难度控制挖空数量,不同level的难度差异更合理。
- 输入稳定性:新增了输入格式、类型、范围的校验,避免用户误操作导致程序崩溃。
- 完整游戏逻辑:新增了数独合法性检查,确保用户填入的数字符合规则,填满后自动判定胜利。
内容的提问来源于stack exchange,提问作者Vishal 10B
相关产品推荐
相关产品推荐

