Python 基于嵌套列表字典存储战舰坐标的射击命中判断失效问题
问题根本原因
你当前的判断逻辑存在核心逻辑偏差:
- 存战舰坐标的字典调用
values()方法时,返回的是每艘战舰对应坐标列表组成的二维可迭代对象,而非所有零散坐标组成的一维集合。 - 原有判断
shot not in self.__dict.values()的实际执行逻辑,是把字符串格式的射击坐标,和每一艘战舰的完整坐标列表做等值比较。这种比较永远不可能成立,所以代码会永远走未命中分支,插入*标记。
举个实际校验的例子:当shot = "A3"时,判断过程会依次对比"A3"和['A1','A2','A3','A4']、['E1','F1','G3']、['D5','D6']、['I9']是否相等,所有对比结果都是False,自然永远判定为未命中。
修复实现方案
方案1:即时判断命中(改动量最小)
在判断环节把所有坐标列表展开遍历,只要射击坐标存在于任意一艘战舰的坐标列表中,就判定为命中。核心判断代码改造为:
# 遍历所有战舰的坐标列表,只要命中任意一个坐标就算命中成功 is_hit = any(shot in ship_coords for ship_coords in self.__dict.values()) if not is_hit: changin_line.insert(x_index, "*") else: changin_line.insert(x_index, "X")
这里的any()方法会在遇到第一个包含当前射击坐标的列表时直接返回True,不会进行无意义的后续遍历,执行效率足够支撑常规游戏逻辑。
方案2:预生成扁平坐标集合(适合高频命中校验场景)
如果游戏对局中射击校验的频次很高,可以在类初始化阶段提前把所有战舰坐标整理为一维集合,后续判断的时间复杂度为O(1),查询效率更高:
# 类初始化阶段提前生成所有战舰坐标的扁平集合 self._valid_ship_pos = { coord for ship_coord_list in self.__dict.values() for coord in ship_coord_list }
后续射击判断时直接查询集合即可:
if shot not in self._valid_ship_pos: changin_line.insert(x_index, "*") else: changin_line.insert(x_index, "X")
额外注意:
self.__dict是Python类实例自带的属性存储字典,直接用这个属性名存业务数据,容易和Python内部的实例属性管理逻辑产生冲突,建议把存储战舰坐标的字典换一个语义更明确的命名,比如self.ship_pos_map,避免后续出现难以排查的隐性问题。
内容的提问来源于stack exchange,提问作者Alsakka
相关产品推荐
相关产品推荐

