Python战舰游戏AI棋盘生成问题:舰船重叠与函数返回异常
控制台战舰游戏AI棋盘生成问题解决方法
我正在用Python开发一款控制台战舰游戏,AI方拥有3艘长度为3格的舰船,舰船格用O表示,水域格用*表示,棋盘是7x7的二维列表。多数情况下create_board函数能正常生成3艘3格舰船,但偶尔会出现舰船重叠,导致2艘3格舰船和1艘2格舰船,总舰船格数不足9。我尝试通过检查总舰船格数,若不足则重新调用函数生成棋盘,但此时函数未返回结果,出现列表为空的错误。请问如何确保舰船永不重叠,且始终生成3艘长度为3格的舰船?
附原始代码:
import random ai_board = [['*' for _ in range(7)] for _ in range(7)] def create_board(starting_board): for i in range(3): anchor_x = random.randint(0, 6) anchor_y = random.randint(0, 6) starting_board[anchor_y][anchor_x] = 'O' orientation = random.choice(['h', 'v']) if orientation == 'h': if anchor_x > 4: starting_board[anchor_y][anchor_x-1] = 'O' starting_board[anchor_y][anchor_x-2] = 'O' else: starting_board[anchor_y][anchor_x+1] = 'O' starting_board[anchor_y][anchor_x+2] = 'O' else: if anchor_y > 4: starting_board[anchor_y-1][anchor_x] = 'O' starting_board[anchor_y-2][anchor_x] = 'O' else: starting_board[anchor_y+1][anchor_x] = 'O' starting_board[anchor_y+2][anchor_x] = 'O' ship_count = 0 for row in starting_board: for column in row: if column == 'O': ship_count += 1 if ship_count == 9: return starting_board if ship_count < 9: new_board = [['*' for _ in range(7)] for _ in range(7)] create_board(new_board) ai_board = create_board(ai_board) for row in ai_board: print(" ".join(row))
我原本期望通过递归调用函数修正棋盘,但实际出现了函数未返回内容的错误。
问题根源
- 递归未返回结果:当
ship_count < 9时,递归调用create_board(new_board)但未将递归的返回值向上传递,导致上层函数接收到None,最终ai_board为空。 - 无重叠检查逻辑:直接随机放置舰船,未提前验证目标位置是否已被占用,导致重叠后总舰船格数不足9。
修正方案
方案一:修复递归返回问题(治标)
在递归调用时添加return语句,确保有效棋盘能逐层返回:
if ship_count < 9: new_board = [['*' for _ in range(7)] for _ in range(7)] return create_board(new_board) # 添加return传递递归结果
但此方法仅解决返回问题,本质靠重试避免重叠,效率较低,极端情况可能陷入递归循环。
方案二:预检查放置位置(治本)
修改舰船放置逻辑,每艘船放置前先验证所有目标格子是否为水域,只有全部可用时才放置,从根源避免重叠。
完整修正代码:
import random def create_board(): # 初始化空棋盘 board = [['*' for _ in range(7)] for _ in range(7)] ships_placed = 0 while ships_placed < 3: # 随机生成锚点和方向 anchor_x = random.randint(0, 6) anchor_y = random.randint(0, 6) orientation = random.choice(['h', 'v']) positions = [] # 计算当前舰船的所有格子位置 if orientation == 'h': if anchor_x <= 4: positions = [(anchor_y, anchor_x + offset) for offset in range(3)] else: positions = [(anchor_y, anchor_x - offset) for offset in range(3)] else: if anchor_y <= 4: positions = [(anchor_y + offset, anchor_x) for offset in range(3)] else: positions = [(anchor_y - offset, anchor_x) for offset in range(3)] # 检查所有位置是否未被占用 valid = True for y, x in positions: if board[y][x] != '*': valid = False break # 位置有效则放置舰船 if valid: for y, x in positions: board[y][x] = 'O' ships_placed += 1 return board ai_board = create_board() for row in ai_board: print(" ".join(row))
代码说明
- 移除原始函数的
starting_board参数,改为内部初始化空棋盘,逻辑更简洁。 - 使用
while循环确保3艘舰船全部成功放置,每艘船放置前先验证所有目标位置的可用性。 - 预计算舰船的所有格子位置,通过遍历检查是否存在已占用的
O,只有全部有效才执行放置操作,彻底避免重叠。 - 无需再通过统计总格子数重试,效率更高且逻辑更可靠。
内容的提问来源于stack exchange,提问作者baral
相关产品推荐
相关产品推荐

