Python实现Match-3游戏:如何编写二维数组水平匹配检测函数?
嘿,作为刚入坑Python的Match-3游戏开发者,这个问题其实挺典型的,咱们一步步拆解清楚~
水平匹配检测的核心思路
首先得明确你的棋盘结构:每个子列表代表一列,所以水平方向的匹配,本质是同一行里,不同列的连续3个及以上相同非0宝石。比如第1行(索引从0开始)的宝石,是board[0][1]、board[1][1]、board[2][1]...这样的顺序,这点一定要搞对,不然很容易搞混索引。
具体实现函数
我直接给你写一个可复用的函数,附带详细注释,你可以直接拿去测试:
def detect_horizontal_matches(board): # 先获取棋盘的列数和行数,动态适配任意大小的棋盘 num_cols = len(board) if num_cols == 0: return [] num_rows = len(board[0]) # 存储所有匹配的位置,每个元素是(行号, 列号)的元组 matches = [] # 遍历每一行 for row in range(num_rows): current_color = None current_streak = 0 streak_start_col = 0 # 记录当前连续宝石的起始列 # 遍历当前行的每一列 for col in range(num_cols): gem = board[col][row] # 遇到占位符0,先检查之前的连续 streak 是否达标 if gem == 0: if current_streak >= 3: # 把这段连续的所有位置加入匹配列表 for c in range(streak_start_col, col): matches.append((row, c)) # 重置 streak 状态 current_color = None current_streak = 0 continue # 当前宝石和上一个颜色相同, streak +1 if gem == current_color: current_streak += 1 else: # 颜色变化,先检查之前的 streak 是否达标 if current_streak >= 3: for c in range(streak_start_col, col): matches.append((row, c)) # 重置为当前颜色的 streak current_color = gem current_streak = 1 streak_start_col = col # 遍历完当前行后,别忘了检查最后一段连续的宝石(避免漏掉行末尾的匹配) if current_streak >= 3: for c in range(streak_start_col, num_cols): matches.append((row, c)) return matches
函数的使用与适配
测试示例
用你给出的测试棋盘试试:
test_board = [[0,0,0,0], [0,'R',0,0], [0,'R',0,0], [0,'R',0,0], [0,'R',0,0]] matches = detect_horizontal_matches(test_board) print(matches) # 输出:[(1, 1), (1, 2), (1, 3), (1, 4)]
这个结果表示第1行(索引从0开始)的列1到4都是R,连续4个,符合匹配条件。
适配更多宝石/更大棋盘的情况
这个函数完全是动态适配的:
- 不管你的棋盘是5列4行,还是10列8行,只要保持“子列表代表列”的结构,函数会自动读取列数和行数,不需要硬编码数值。
- 新增宝石颜色(比如G、B、Y)也不需要改核心逻辑,只要颜色是可比较的类型(字符串、枚举类都可以),函数能自动识别连续相同的颜色。
可选优化
如果你的需求只是“判断是否存在水平匹配”,不需要具体位置,可以在检测到第一个连续3个宝石时直接返回True,这样能节省性能:
def has_horizontal_match(board): num_cols = len(board) if num_cols == 0: return False num_rows = len(board[0]) for row in range(num_rows): current_color = None current_streak = 0 for col in range(num_cols): gem = board[col][row] if gem == 0: current_streak = 0 current_color = None continue if gem == current_color: current_streak += 1 if current_streak >=3: return True else: current_color = gem current_streak =1 return False
内容的提问来源于stack exchange,提问作者B. Nguyen
相关产品推荐
相关产品推荐

