Python文本象棋项目二维数组异常:放置棋子后整行被填充
文本象棋项目棋子放置问题
我正在开发基于Python的文本象棋项目,已在控制台实现了外观良好的棋盘,但每当尝试放置棋子时,整行都会被填充。原本期望在数组的E4位置放置白兵字符,但结果整行都被填充。
所用代码如下:
import os global arrowKey global speed newchar = '' arrowKey = {'\x1b[A': 'up'} class Pieces: Black_rook = '♜' Black_knight = '♞' Black_bishop = '♝' Black_queen = '♛' Black_king = '♚' Black_pawn = '♟︎' White_rook = '♖' White_knight = '♘' White_bishop = '♗' White_queen = '♕' White_king = '♔' White_pawn = '♙' class Array: def __init__(self, x=16, y=8, board=None): self.pos = () self.x = x self.y = y grid = [' ' + '_' * self.x] for _ in range(y): row = ['|'] for _ in range(x): row.append(' ') row.append('|') grid.append(row) grid.append(' ' + '‾' * self.x) self.grid = grid if board != None: self.grid = board def reload(self, say=None): os.system('clear') if say != None: print(say) p = '' for i in self.grid: p = p + ''.join([x for x in i]) + '\n' print(p) def insert(self, char, x, y): self.pos = (x, y) self.grid[y][x] = char def move(self, direction, char): poslist = [] for y, i in enumerate(self.grid): for x, j in enumerate(i): if j == char: poslist.append((x, y)) count = 0 for posx, posy in poslist: if direction == 'down': if self.grid[posy + 1][posx] != '‾': self.insert(' ', posx, posy) self.insert(char, posx, posy + 1) self.pos = (posx, posy + 1) if direction == 'up': if self.grid[posy - 1][posx] != '_': self.insert(' ', posx, posy) self.insert(char, posx, posy - 1) self.pos = (posx, posy - 1) if direction == 'left': if self.grid[posy][posx - 1] != '|': self.insert(' ', posx, posy) self.insert(char, posx - 1, posy) self.pos = (posx - 1, posy) if direction == 'right': if self.grid[posy][posx + 1] != '|': self.insert(' ', posx, posy) self.insert(char, posx + 1, posy) self.pos = (posx + 1, posy) count += 1 def getpos(self, char): poslist = [] for y, i in enumerate(self.grid): for x, j in enumerate(i): if j == char: poslist.append((x, y)) return poslist class Chess(Array): def __init__(self): row = list(''.join(['.' for i in range(8)])) board = [row for i in range(8)] super().__init__(board=board) def reload(self): p = '' nums = [i + 1 for i in range(8)] nums.reverse() for x, i in enumerate(self.grid): i = [f'{z} ' for z in i] p += f'{nums[x]} {""".join(i)}\n' add = [i + ' ' for i in list('ABCDEFG')] add.append('H') p += ' ' + ''.join(add) + '\n' print(p) def move(self, move:str): move = move.split(' ') def placepiece(self, piece, pos): pos = list(pos) ykey = [i for i in range(8)] ykey.reverse() x = [x for x, i in enumerate('ABCDEF') if i == pos[0]][0] y = ykey[int(pos[1]) - 1] x = int(x) return x, y board = Chess() x, y = board.placepiece(Pieces.White_pawn, 'E4') board.grid[y][x] = Pieces.White_pawn print(board.grid) board.reload()
问题原因
Chess类的__init__方法中,创建棋盘数组时犯了Python列表引用的常见错误:
row = list(''.join(['.' for i in range(8)])) board = [row for i in range(8)]
这里的board由8个指向同一个row列表的元素组成,所有行本质是同一个列表的引用。修改任意一行的元素时,所有行对应位置都会同步改变,这就导致了整行被填充的现象。
另外,placepiece方法中枚举列坐标时只写到F列(enumerate('ABCDEF')),缺少G、H列,会导致放置这两列棋子时出现索引错误。
修复方案
- 修正棋盘数组创建逻辑,确保每一行都是独立列表:
class Chess(Array): def __init__(self): # 每次循环生成新的row列表,避免引用复用 board = [list('.' * 8) for _ in range(8)] super().__init__(board=board)
- 补全
placepiece方法的列枚举范围:
def placepiece(self, piece, pos): pos = list(pos) ykey = [i for i in range(8)] ykey.reverse() # 补充G、H列的枚举 x = [x for x, i in enumerate('ABCDEFGH') if i == pos[0]][0] y = ykey[int(pos[1]) - 1] x = int(x) return x, y
修改后运行代码,即可正常在E4位置放置单个白兵,不会出现整行填充的问题。
内容的提问来源于stack exchange,提问作者Mark Wilson
相关产品推荐
相关产品推荐

