Python列表去重:国际象棋游戏中避免棋子重复放置于同一方格
解决国际象棋棋子重复放置同一方格的问题
嘿,我一眼就看出你代码里的逻辑问题啦!咱们来一步步拆解:
你的add方法现在的逻辑是只要遇到一个位置不冲突的棋子,就直接把当前pawn的坐标设为目标位置——这就导致哪怕前面已经有一个棋子和目标位置冲突了,后面只要有一个位置不同的棋子,就会覆盖掉之前的-1设置,最终还是会把pawn放到冲突的格子里。这完全搞反了判断逻辑!
修正后的代码
def add(self, pawn, x_coordinate, y_coordinate, piece_color): # 先默认允许放置,把pawn设为目标位置 pawn.x_coordinate = x_coordinate pawn.y_coordinate = y_coordinate pawn.piece_color = piece_color # 匹配你传入的颜色参数 # 遍历所有已存在的棋子,检查位置冲突 for each_pawn in self.pawns: if (each_pawn.x_coordinate == x_coordinate and each_pawn.y_coordinate == y_coordinate): # 发现冲突,标记为无效位置 pawn.x_coordinate = -1 pawn.y_coordinate = -1 break # 找到冲突就不用继续检查了,提升效率 # 别忘了把pawn加入到棋子列表里!原代码好像漏了这一步 self.pawns.append(pawn)
逻辑解释
- 先预设合法位置:一开始就把pawn的位置设为目标坐标,因为我们默认这个位置是可用的。
- 冲突检查:遍历已有的棋子,一旦发现有棋子和目标位置重合,立刻把pawn的位置设为
-1,并且跳出循环(没必要继续检查其他棋子了)。 - 加入棋子列表:不管最终位置是否合法,都把pawn加入到
self.pawns里(如果不需要保留无效棋子,可以在这里加个判断,只加入位置合法的实例)。
进阶优化建议
如果你的棋子数量比较多,每次遍历所有棋子检查冲突会有点慢。可以维护一个已占用位置的集合,这样检查冲突的时间复杂度会从O(n)降到O(1):
def __init__(self): self.pawns = [] self.occupied_positions = set() # 存储已占用的坐标元组,比如(x, y) def add(self, pawn, x_coordinate, y_coordinate, piece_color): target_pos = (x_coordinate, y_coordinate) if target_pos in self.occupied_positions: # 位置已被占用,标记无效 pawn.x_coordinate = -1 pawn.y_coordinate = -1 else: # 位置可用,设置坐标并标记为已占用 pawn.x_coordinate = x_coordinate pawn.y_coordinate = y_coordinate pawn.piece_color = piece_color self.occupied_positions.add(target_pos) self.pawns.append(pawn) # 别忘了在移除棋子的时候,也要把对应的位置从集合里删掉! def remove_pawn(self, pawn): if pawn in self.pawns: self.pawns.remove(pawn) self.occupied_positions.discard((pawn.x_coordinate, pawn.y_coordinate))
这样处理会更高效,尤其是当游戏里棋子数量较多的时候。
内容的提问来源于stack exchange,提问作者poppashingles
相关产品推荐
相关产品推荐

