You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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")

问题根源

  1. 递归调用导致计数器重置:每次有效移动后调用milestone_2,会重新创建新的valid_moves函数实例,每个实例都有独立的number_moves变量,最终多个实例都会打印胜利信息。
  2. 无效移动错误计数:把无效输入(不存在的数字、不相邻的数字)也计入步数,不符合需求。

修复后的代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 20:33:11