如何动态缩放康威生命游戏预定义图案以适配任意世界尺寸?
解决方案:让康威生命游戏图案适配任意世界尺寸
核心思路
- 只处理图案中的存活细胞,跳过无效的dead/null条目,减少冗余计算
- 基于存活细胞的实际分布计算图案边界,而非依赖JSON里的预设world_size(可能包含大量空白)
- 将图案按相对位置映射到目标世界的指定角落(默认左上角),完全保留原始布局与方向
- 预填充整个目标世界为dead状态,再覆盖图案的存活细胞
修改后的代码
def populate_world(world_size, seed_pattern=None): width, height = world_size population = {} # 先初始化整个世界为死亡状态 for x in range(width): for y in range(height): population[(x, y)] = { 'state': cb.STATE_DEAD, 'neighbours': calc_neighbour_positions((x, y)) } if seed_pattern: pattern_data = cb.get_pattern(seed_pattern) alive_coords = [] # 提取所有存活细胞的原始坐标 for coord_str, state_data in pattern_data['population'].items(): # 根据你的JSON示例,存活状态对应state为"-",请匹配实际的cb.STATE_ALIVE值 if state_data and state_data.get('state') == cb.STATE_ALIVE: x, y = map(int, coord_str.strip("()").split(", ")) alive_coords.append((x, y)) if not alive_coords: return population # 计算图案的实际有效边界 min_x = min(coord[0] for coord in alive_coords) max_x = max(coord[0] for coord in alive_coords) min_y = min(coord[1] for coord in alive_coords) max_y = max(coord[1] for coord in alive_coords) # 计算偏移量,把图案左上角对齐到目标世界的(0,0) offset_x = -min_x offset_y = -min_y # 将存活细胞映射到目标世界 for orig_x, orig_y in alive_coords: target_x = orig_x + offset_x target_y = orig_y + offset_y # 确保坐标在当前世界范围内 if 0 <= target_x < width and 0 <= target_y < height: population[(target_x, target_y)] = { 'state': cb.STATE_ALIVE, 'neighbours': calc_neighbour_positions((target_x, target_y)) } return population
关键细节说明
- 预填充全dead世界:先遍历所有目标坐标初始化,避免遗漏任何位置,保证世界完整性
- 提取存活细胞:只处理真正存活的细胞,跳过JSON中大量的null条目,提升运行效率
- 动态计算图案边界:通过存活细胞的极值坐标确定图案实际大小,适配那些在大尺寸JSON中只占小区域的图案
- 坐标偏移映射:把图案的左上角对齐到目标世界的原点,确保图案的相对布局完全不变,不会错位
- 边界检查:如果目标世界比图案小,只会显示能容纳的部分,不会出现越界错误
扩展:支持其他对齐方式
如果需要把图案放在世界中间或右下角,只需修改偏移量计算:
- 居中对齐:
pattern_width = max_x - min_x + 1 pattern_height = max_y - min_y + 1 offset_x = (width - pattern_width) // 2 - min_x offset_y = (height - pattern_height) // 2 - min_y - 右下角对齐:
offset_x = (width - (max_x + 1)) - min_x offset_y = (height - (max_y + 1)) - min_y
内容的提问来源于stack exchange,提问作者simLight
相关产品推荐
相关产品推荐

