如何用Pygame制作Nip桌游圆形棋盘且不打乱单元格行列结构?
基于现有行列结构实现Pygame圆形Nip棋盘
你已经用8x8的board数组管理棋子状态,现在要保留原行列逻辑的同时把方形布局改成圆形,核心是给每个有效单元格(board[row][col] != 2)映射到圆形棋盘的极坐标位置,具体实现步骤如下:
1. 定义层级半径与角度映射
把原数组的行对应圆形棋盘的环层级(从外到内的半径),列对应每个环上的角度位置:
- 行0/7 → 最外层环,对应最大半径(比如你用的380),仅列2-5为有效单元格,角度间隔90°
- 行1/6 → 次外层环,半径缩小,有效列是1-6,角度间隔60°
- 行2/5 → 中间外层环,半径再缩小,有效列0-7,角度间隔45°
- 行3/4 → 最内层环,最小半径,有效列0-7,角度间隔45°
先创建映射配置:
import math # 棋盘中心坐标 CENTER_X, CENTER_Y = 400, 400 # 从外到内的四个环半径(可根据视觉效果调整) RADIUS_LEVELS = [380, 320, 260, 200] # 预定义每行的有效列对应的角度(单位:度) angle_maps = { 0: {2: 0, 3: 90, 4: 180, 5: 270}, 7: {2: 0, 3: 90, 4: 180, 5: 270}, 1: {1: 30, 2: 90, 3: 150, 4: 210, 5: 270, 6: 330}, 6: {1: 30, 2: 90, 3: 150, 4: 210, 5: 270, 6: 330}, 2: {i: i * 45 for i in range(8)}, 5: {i: i * 45 for i in range(8)}, 3: {i: i * 45 for i in range(8)}, 4: {i: i * 45 for i in range(8)}, }
2. 修改绘制逻辑
替换原来的方形绘制代码,用极坐标计算每个单元格的屏幕位置,同时保留原board的行列遍历逻辑:
# 遍历原board的所有行列 for row in range(8): for col in range(8): cell_val = board[row][col] if cell_val == 2: continue # 跳过无效单元格 # 获取当前单元格的半径 if row in (0, 7): radius = RADIUS_LEVELS[0] elif row in (1, 6): radius = RADIUS_LEVELS[1] elif row in (2, 5): radius = RADIUS_LEVELS[2] else: # 行3、4 radius = RADIUS_LEVELS[3] # 获取角度并转换为弧度 angle_deg = angle_maps[row][col] angle_rad = math.radians(angle_deg) # 计算屏幕坐标(转整数避免Pygame绘制异常) x = int(CENTER_X + radius * math.cos(angle_rad)) y = int(CENTER_Y + radius * math.sin(angle_rad)) # 绘制单元格边框 pygame.draw.circle(self.win, WHITE_COLOR, (x, y), PIECE_RADIUS//3, 2) # 绘制黑白棋子(如果有) if cell_val == BLACK: pygame.draw.circle(self.win, (0, 0, 0), (x, y), PIECE_RADIUS//3) elif cell_val == WHITE: pygame.draw.circle(self.win, (255, 255, 255), (x, y), PIECE_RADIUS//3)
3. 细节调整
- 修改
RADIUS_LEVELS的数值,可让各环间距更协调 - 调整
angle_maps中的角度值(比如加90°),可改变棋盘的起始方向 - 确保所有
board[row][col] !=2的单元格都在angle_maps中有对应项,避免报错
这样既保留了原board的行列逻辑来管理对局状态,又能绘制出符合Nip规则的圆形棋盘。
内容的提问来源于stack exchange,提问作者Igor Bond
相关产品推荐
相关产品推荐

