Python滑块谜题开发:如何正确统计玩家完成游戏的步数?
滑块谜题游戏步数统计问题修复
问题描述
我正在用Python开发一款n×n网格的滑块谜题游戏,网格中除一个空白格外其余均为数字。玩家输入与空白格相邻(上下左右)的数字来交换位置,每次有效移动后更新并打印网格,直至谜题解开(所有数字按顺序排列,最后一格为空白)。需要实现统计玩家完成谜题的步数功能,但初始化number_moves为0后,每次玩家移动时加1,最终完成谜题时总是先打印You won in 0 moves. Congratulations!,再显示You won in 1 moves. Congratulations!。
原代码如下:
def milestone_2(tiles): def valid_moves(tiles_list, grid_size): number_moves = 0 while tiles_list[:-1] != sorted(tiles_list[:-1]) and tiles_list[-1] != "": while True: choice = input("Your move: ") if choice == 'quit': print("Quitting...") return if choice not in tiles_list: print(f"{choice} is not valid. Try again.") number_moves += 1 continue blank_square_index = tiles_list.index("") choice_index = tiles_list.index(choice) if abs(choice_index - blank_square_index) == grid_size or ((choice_index // grid_size) == (blank_square_index // grid_size)) and (abs(choice_index - blank_square_index)) == 1 : tiles_list[blank_square_index], tiles_list[choice_index] = tiles_list[choice_index], tiles_list[blank_square_index] milestone_2(','.join(tiles_list)) number_moves += 1 break else: print(f"{choice} is not valid. Try again.") number_moves += 1 print(f"You won in {number_moves} moves. Congratulations!") def create_grid(): tiles_list = tiles.split(',') grid_size = int(len(tiles_list) ** 0.5) result = "┌" + ("────┬") * (grid_size -1) + "────┐\n" for i in range(0, len(tiles_list), grid_size): result += "│" for j in range(grid_size): tile = tiles_list[i+j] if tile == "": result += " │" elif len(tile) == 1: result += " " + tile + " │" elif len(tile) == 2: result += " " + tile + " │" result += "\n" if i < len(tiles_list) - grid_size: result += "├" + (grid_size-1) * "────┼" + "────┤\n" result += "└" + (grid_size-1)*"────┴" + "────┘" print(result) valid_moves(tiles_list, grid_size) create_grid() milestone_2("1,2,3,4,5,6,7,8,9,10,11,12,13,14,,15")
问题根源
- 递归调用导致计数器重置:每次有效移动后调用
milestone_2,会重新创建新的valid_moves函数实例,每个实例都有独立的number_moves变量,最终多个实例都会打印胜利信息。 - 无效移动错误计数:把无效输入(不存在的数字、不相邻的数字)也计入步数,不符合需求。
修复后的代码
def milestone_2(tiles): def print_grid(tiles_list, grid_size): result = "┌" + ("────┬") * (grid_size - 1) + "────┐\n" for i in range(0, len(tiles_list), grid_size): result += "│" for j in range(grid_size): tile = tiles_list[i+j] if tile == "": result += " │" elif len(tile) == 1: result += " " + tile + " │" elif len(tile) == 2: result += " " + tile + " │" result += "\n" if i < len(tiles_list) - grid_size: result += "├" + (grid_size-1) * "────┼" + "────┤\n" result += "└" + (grid_size-1)*"────┴" + "────┘" print(result) def valid_moves(tiles_list, grid_size): number_moves = 0 # 定义目标状态:数字排序,最后一位为空 target = sorted(tiles_list[:-1]) + [""] while tiles_list != target: choice = input("Your move: ") if choice == 'quit': print("Quitting...") return if choice not in tiles_list: print(f"{choice} is not valid. Try again.") continue blank_idx = tiles_list.index("") choice_idx = tiles_list.index(choice) # 判断是否相邻:同列差grid_size 或 同行差1 is_adjacent = (abs(choice_idx - blank_idx) == grid_size) or \ ((choice_idx // grid_size == blank_idx // grid_size) and abs(choice_idx - blank_idx) == 1) if is_adjacent: # 交换位置 tiles_list[blank_idx], tiles_list[choice_idx] = tiles_list[choice_idx], tiles_list[blank_idx] number_moves += 1 # 打印更新后的网格 print_grid(tiles_list, grid_size) else: print(f"{choice} is not valid. Try again.") print(f"You won in {number_moves} moves. Congratulations!") tiles_list = tiles.split(',') grid_size = int(len(tiles_list) ** 0.5) print_grid(tiles_list, grid_size) valid_moves(tiles_list, grid_size) milestone_2("1,2,3,4,5,6,7,8,9,10,11,12,13,14,,15")
关键修改说明
- 移除递归:不再调用
milestone_2,而是直接修改当前的tiles_list并重新打印网格,确保number_moves始终是同一个计数器。 - 修正步数统计逻辑:仅在玩家做出有效移动(输入存在且相邻的数字)时,才增加步数计数,无效输入不统计。
- 明确目标状态:直接对比整个
tiles_list是否等于目标状态(排序后的数字+空白格),逻辑更清晰。 - 拆分打印函数:把网格打印逻辑拆分为独立的
print_grid函数,代码结构更清晰,避免重复调用初始化逻辑。
内容的提问来源于stack exchange,提问作者Sinister Pear
相关产品推荐
相关产品推荐

