Python Board类set_colour方法问题:无法在同一网格更新符号
问题解决方案
核心问题
你的代码无法累积更新网格的根本原因是:没有将网格状态作为Board实例的持久化属性保存。当前__str__和set_colour方法每次都会重新创建全新的空网格,而非基于已有的状态修改,导致每次操作都是独立的新网格。
具体修改步骤
1. 初始化持久化网格属性
在__init__方法中创建实例属性self.grid,作为保存网格状态的二维列表,初始化为全空('E'对应的符号):
def __init__(self, size=19): self.size = size assert (2 <= self.size <= 26), "Illegal board size: must be between 2 and 26." # 初始化网格:二维列表,每个元素初始为'E'对应的符号 self.grid = [[self.points['E'] for _ in range(self.size)] for _ in range(self.size)]
2. 重构__str__方法
__str__的职责是返回表示当前网格的字符串,而非直接打印。基于self.grid生成字符串,同时处理行号倒序和列名:
def __str__(self): column_names = letters[:self.size] # 构建头部列名 header = ' ' + ' '.join(column_names) rows = [header] # 倒序遍历行号(从size到1) for row_num in reversed(range(1, self.size + 1)): # 找到对应的网格行:row_num=1对应grid的最后一行,索引为self.size - row_num grid_row = self.grid[self.size - row_num] # 格式化行号(右对齐2位)+ 行内容 row_str = f"{row_num:2d} {' '.join(grid_row)}" rows.append(row_str) # 拼接所有行并返回 return '\n'.join(rows)
3. 修复set_colour方法
移除方法内创建新网格的代码,直接操作self.grid,只负责修改状态,不处理输出:
- 修正坐标解析逻辑,转换为正确的网格索引
- 修复断言条件的错误
- 移除无用的循环、打印和变量
修改后的set_colour:
def set_colour(self, coords, colour_name): # 颜色合法性断言 assert colour_name in self.points, "invalid colour name" # 坐标格式断言 assert 2 <= len(coords) <= 3, "invalid coordinates" # 解析坐标 alphabetical_coord = coords[0].upper() # 统一转为大写,兼容小写输入 numerical_coord = coords[1:] # 坐标范围断言 assert ord(alphabetical_coord) in range(ord('A'), ord('Z')+1), "column out of range" assert numerical_coord.isdigit(), "invalid row number" row_num = int(numerical_coord) assert 1 <= row_num <= self.size, "row out of range" # 转换为网格索引:列是字母对应的索引,行是size - row_num(因为行号倒序) col_idx = ord(alphabetical_coord) - ord('A') row_idx = self.size - row_num # 修改网格对应位置的符号 self.grid[row_idx][col_idx] = self.points[colour_name]
4. 修正代码缩进和语法错误
确保所有方法(get_size、set_colour等)都缩进在Board类内部,移除重复的导入和无用代码。
修正后的完整代码
from string import ascii_uppercase as letters class Board(): points = {'E': '.', 'B': '@', 'W': 'O'} def __init__(self, size=19): self.size = size assert (2 <= self.size <= 26), "Illegal board size: must be between 2 and 26." # 初始化持久化网格 self.grid = [[self.points['E'] for _ in range(self.size)] for _ in range(self.size)] def __str__(self): column_names = letters[:self.size] header = ' ' + ' '.join(column_names) rows = [header] for row_num in reversed(range(1, self.size + 1)): row_idx = self.size - row_num grid_row = self.grid[row_idx] row_str = f"{row_num:2d} {' '.join(grid_row)}" rows.append(row_str) return '\n'.join(rows) def get_size(self): return self.size def set_colour(self, coords, colour_name): assert colour_name in self.points, "invalid colour name" assert 2 <= len(coords) <= 3, "invalid coordinates" alphabetical_coord = coords[0].upper() numerical_coord = coords[1:] assert ord(alphabetical_coord) in range(ord('A'), ord('Z')+1), "column out of range" assert numerical_coord.isdigit(), "invalid row number" row_num = int(numerical_coord) assert 1 <= row_num <= self.size, "row out of range" col_idx = ord(alphabetical_coord) - ord('A') row_idx = self.size - row_num self.grid[row_idx][col_idx] = self.points[colour_name] # 使用示例 if __name__ == "__main__": b = Board(5) b.set_colour("B1", "W") b.set_colour("C1", "B") b.set_colour("D1", "B") print(b)
验证输出
运行上述代码后,会得到预期的累积更新结果:
A B C D E 5 . . . . . 4 . . . . . 3 . . . . . 2 . . . . . 1 . O @ @ .
内容的提问来源于stack exchange,提问作者Anne_Music
相关产品推荐
相关产品推荐

