Python开发海战棋游戏逻辑库:架构设计与常见陷阱
该库实现了经典海战棋游戏的逻辑,专注于数学最优算法。主要类包括用于表示游戏棋盘的Field类和用于管理船只的Ship类。棋盘以10x10矩阵形式存储,使用列表的列表,其中符号表示状态:空格表示空单元格,'1'表示完好的船体部分,'.'表示未命中,'X'表示被摧毁的单元格。
Field类处理棋盘创建、坐标验证、船只放置和射击处理。坐标输入格式为'a1',其中字母A-J对应行,数字1-10对应列。规则固定:1艘四格船、2艘三格船、3艘两格船、4艘单格船;船只不得相互接触,即使在角落也不行。
实现Field类
初始化创建空网格:
class Field:
def __init__(self):
height = 10
weight = 10
self.grid = [[' ' for i in range(weight)] for i in range(height)]
display()方法将棋盘输出到控制台并附带坐标。初始版本存在错误——方法line.insert(0, letter)在重复调用时通过添加字母改变了原始网格。修复方法:单独打印字母而不改变结构。
def display(self):
print(' 1 2 3 4 5 6 7 8 9 10')
letters = 'ABCDEFGHIJ'
count_letters = 0
for line in self.grid:
print(letters[count_letters], *line)
count_letters += 1
坐标验证被提取到私有方法_validation_coordinate()中。它检查字符串长度(2-3个字符)、字母是否在A-J范围内以及数字是否在1-10范围内。方法find_coordinate()确定单元格状态:空、命中、摧毁、未受损、已射击。
用于坐标转换的字典存储为属性self.rows和self.columns:
- rows: {'a': 0, 'b': 1, ..., 'j': 9}
- columns: {'1': 0, '2': 1, ..., '10': 9}
Ship类与船只放置
Ship类将参数存储在字典中:
class Ship:
def __init__(self):
self.parameters = {
'alive coordinates': [],
'hitted coordinates': [],
'alive': True
}
self.field = None
def set_field(self, field):
self.field = field
Field中的方法add_ship(ship, coordinate_line, length)根据类似'a1-a2-a3'的字符串放置船只。首先,进行行验证_ship_line_validation():解析为坐标,检查线性(水平/垂直),并匹配长度。然后,为每个坐标调用ship.set_coordinate_in_ship(coordinate),在网格中设置'1'。
def add_ship(self, ship, coordinate_line, length):
ship.set_field(self)
if not self._ship_line_validation(coordinate_line):
return False
coordinates = coordinate_line.split('-')
if length != len(coordinates):
return False
for coordinate in coordinates:
result = ship.set_coordinate_in_ship(coordinate)
if result:
rows = self.rows[coordinate[0]]
columns = self.columns[coordinate[1:]]
self.grid[rows][columns] = '1'
return True
Field与Ship的关系是双向的:Field调用ship.set_field(self),而Ship使用self.field进行验证。这违反了基础层的封装原则,但简化了API。
重构见解
该项目揭示了关键的新手陷阱:
- 方法重载:find_coordinate()结合了验证、搜索和输出——拆分为_validation_coordinate()和get_cell_state()。
- 数据突变:避免在display()中使用insert();使用副本操作。
- 硬编码字典:提取为类常量或使用ord()进行转换。
- 返回值:标准化:True/False表示成功,字符串表示错误。
为优化游戏玩法,集成概率搜索算法:命中后扫描相邻单元格;摧毁后从概率中排除船体部分。
关键要点
- Field作为列表矩阵,使用符号表示状态;通过字典self.rows/self.columns进行坐标验证。
- Ship存储完好/命中坐标;通过set_field()与Field建立双向链接。
- 通过coordinate_line('a1-a2')放置;检查线性和缓冲区。
- 避免在display()中改变网格;将常见检查提取到私有方法中。
- 对于高级算法:将射击概率图单独存储于网格之外。
— Editorial Team
暂无评论。