C#:如何基于空间条件将队列中的俄罗斯方块阵型二维数组存入目标数组?
实现队列到目标数组的移入逻辑方案
我之前做类似方块堆叠系统的时候也踩过不少坑,咱们一步步拆解核心环节:
1. 先搞定「空间充足」的判断逻辑
不能只看阵型的整体宽高(毕竟俄罗斯方块阵型大多带空白,比如L型的最小包围矩形是2x3,但实际只有3个块),正确的判断方式是:
- 先提取阵型的有效块相对坐标:遍历阵型数组,把所有非空白(比如非0)的块的坐标记录下来,比如
[(0,0), (1,0), (1,1), (1,2)] - 遍历目标数组的所有可能起始位置,检查把阵型的有效块放到对应位置时,所有块都在目标数组边界内,且对应位置都是空白未填充状态
- 只要存在至少一个符合条件的起始位置,就判定为空间充足
举个Python示例:
def has_enough_space(target_grid, shape): # 提取阵型的有效块相对坐标 shape_blocks = [] for dy, row in enumerate(shape): for dx, cell in enumerate(row): if cell != 0: # 假设0代表空白区域 shape_blocks.append((dx, dy)) if not shape_blocks: return True # 空阵型直接跳过 target_height = len(target_grid) target_width = len(target_grid[0]) if target_height > 0 else 0 # 遍历所有可能的起始位置(x为列,y为行) for start_y in range(target_height): for start_x in range(target_width): valid = True for dx, dy in shape_blocks: x = start_x + dx y = start_y + dy # 检查是否越界或已被填充 if x < 0 or x >= target_width or y < 0 or y >= target_height or target_grid[y][x] != 0: valid = False break if valid: return True return False
2. 实现「最优填充」的位置查找
这里的「最优」默认遵循俄罗斯方块的通用逻辑:找最底部的可用位置,同一高度下选最靠左的,这样能最大化后续消除行的可能。
实现思路:
- 从目标数组最底层往上遍历(找能放下阵型的最大y值,y越大越靠下)
- 对每个y值,从左到右找第一个可行的x位置
- 找到第一个符合条件的位置直接返回,这就是最优位置
代码示例:
def find_best_position(target_grid, shape): shape_blocks = [] for dy, row in enumerate(shape): for dx, cell in enumerate(row): if cell != 0: shape_blocks.append((dx, dy)) if not shape_blocks: return (0, 0) target_height = len(target_grid) target_width = len(target_grid[0]) if target_height > 0 else 0 best_y, best_x = -1, -1 # 从下往上找最高的可行y(最底部位置) for start_y in range(target_height - 1, -1, -1): # 从左往右找第一个可行x for start_x in range(target_width): valid = True for dx, dy in shape_blocks: x = start_x + dx y = start_y + dy if x < 0 or x >= target_width or y < 0 or y >= target_height or target_grid[y][x] != 0: valid = False break if valid: best_y, best_x = start_y, start_x break # 同一y下取最靠左的位置,直接跳出 if best_y != -1: return (best_x, best_y) # 理论上前面已检查空间充足,这里不会走到 return (0, 0)
3. 队列的循环处理逻辑
把前面的逻辑串起来,处理队列的核心流程:
- 循环取出队列头部的阵型
- 空间充足则找最优位置填充,空间不足则重新入队
- 加个计数器避免无限循环(比如队列所有元素都无法放入时,循环一轮后暂停)
代码示例(用Python的collections.deque实现队列):
from collections import deque def process_shape_queue(shape_queue, target_grid): processed_count = 0 total_shapes = len(shape_queue) while processed_count < total_shapes: current_shape = shape_queue.popleft() if has_enough_space(target_grid, current_shape): # 填充阵型到目标数组 start_x, start_y = find_best_position(target_grid, current_shape) for dy, row in enumerate(current_shape): for dx, cell in enumerate(row): if cell != 0: target_grid[start_y + dy][start_x + dx] = cell # cell为方块标识值 # 有新填充,重置计数器重新检查队列 processed_count = 0 total_shapes = len(shape_queue) else: # 空间不足,重新入队 shape_queue.append(current_shape) processed_count += 1
额外优化建议
- 预先缓存每个阵型的有效块坐标,避免重复遍历计算,提升效率
- 填充后可立即执行行消除逻辑,快速腾出空间给后续阵型
- 可自定义「最优」规则,比如优先选择能消除最多行的位置,需要计算每个可行位置的消除行数后再筛选
内容的提问来源于stack exchange,提问作者akiron111
相关产品推荐
相关产品推荐

