defadd_new_tile(self): empty_cells = [(r, c) for r inrange(4) for c inrange(4) ifself.grid[r][c] isNone] ifnot empty_cells: return r, c = random.choice(empty_cells) val = 2if random.random() < 0.9else4 # 创建新 Tile 对象 self.grid[r][c] = Tile(val, r, c)
defreset_tile_positions(self): """每轮动画开始前,同步所有 Tile 的起点""" self.moved_tiles.clear() for r inrange(4): for c inrange(4): ifself.grid[r][c]: self.grid[r][c].reset_position()
defmove_left(self): self.reset_tile_positions() moved = False for r inrange(4): # 1. 提取本行非空 Tile tiles = [self.grid[r][c] for c inrange(4) ifself.grid[r][c] isnotNone] new_row = [] skip = False # 2. 执行合并逻辑 for i inrange(len(tiles)): if skip: skip = False continue curr_tile = tiles[i] # 如果有下一个且值相同,合并 if i + 1 < len(tiles) and curr_tile.value == tiles[i + 1].value: next_tile = tiles[i + 1] merged_value = curr_tile.value * 2 self.score += merged_value # 创建合并后的新 Tile new_tile = Tile(merged_value, r, len(new_row)) # 关键:记录是由哪两个旧 Tile 合并而来,用于后续(可能的)合并动画 new_tile.merged_from = (curr_tile, next_tile) # 更新旧 Tile 的目标位置,以便它们滑向合并点 curr_tile.move_to(r, len(new_row)) next_tile.move_to(r, len(new_row)) new_row.append(new_tile) # 将这两个移动过的旧 tile 加入动画列表 self.moved_tiles.extend([curr_tile, next_tile]) skip = True moved = True else: # 不合并,直接放入新位置 curr_tile.move_to(r, len(new_row)) new_row.append(curr_tile) if curr_tile.old_col != curr_tile.col: self.moved_tiles.append(curr_tile) moved = True # 3. 填充 None 并更新网格 for c inrange(4): self.grid[r][c] = new_row[c] if c < len(new_row) elseNone return moved