este codigo tiene un error: ""import pygame
import sys
import random
from collections import deque
import heapq

# Configuración de Pygame
pygame.init()

# Constantes
TILE_SIZE = 100
GRID_SIZE = 4
WINDOW_HEIGHT = TILE_SIZE * GRID_SIZE + 50  # Espacio extra para el botón
WINDOW_WIDTH = TILE_SIZE * GRID_SIZE
FPS = 30  # Frames por segundo

# Colores
BACKGROUND_COLOR = (255, 255, 255)
TILE_COLOR = (0, 102, 204)
TEXT_COLOR = (255, 255, 255)
BUTTON_COLOR = (0, 204, 102)

# Inicializar pantalla
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Puzzle 15')

# Fuente
font = pygame.font.Font(None, 72)
button_font = pygame.font.Font(None, 48)

def create_initial_board():
    numbers = list(range(1, GRID_SIZE * GRID_SIZE))
    numbers.append(0)
    random.shuffle(numbers)
    board = [numbers[i:i + GRID_SIZE] for i in range(0, len(numbers), GRID_SIZE)]
    return board

def draw_board(board):
    screen.fill(BACKGROUND_COLOR)
    for row in range(GRID_SIZE):
        for col in range(GRID_SIZE):
            value = board[row][col]
            if value != 0:
                x = col * TILE_SIZE
                y = row * TILE_SIZE
                pygame.draw.rect(screen, TILE_COLOR, (x, y, TILE_SIZE, TILE_SIZE))
                text = font.render(str(value), True, TEXT_COLOR)
                text_rect = text.get_rect(center=(x + TILE_SIZE // 2, y + TILE_SIZE // 2))
                screen.blit(text, text_rect)
    
    # Dibujar botón de resolver
    solve_button = pygame.Rect(0, WINDOW_HEIGHT - 50, WINDOW_WIDTH, 50)
    pygame.draw.rect(screen, BUTTON_COLOR, solve_button)
    button_text = button_font.render('Resolver', True, TEXT_COLOR)
    button_rect = button_text.get_rect(center=solve_button.center)
    screen.blit(button_text, button_rect)

def find_empty_tile(board):
    for row in range(GRID_SIZE):
        for col in range(GRID_SIZE):
            if board[row][col] == 0:
                return (row, col)
    return None

def is_valid_move(empty_tile, click_pos):
    empty_row, empty_col = empty_tile
    click_row, click_col = click_pos
    return (abs(empty_row - click_row) == 1 and empty_col == click_col) or (abs(empty_col - click_col) == 1 and empty_row == click_row)

def swap_tiles(board, tile1, tile2):
    board[tile1[0]][tile1[1]], board[tile2[0]][tile2[1]] = board[tile2[0]][tile2[1]], board[tile1[0]][tile1[1]]

def is_solved(board):
    correct = list(range(1, GRID_SIZE * GRID_SIZE)) + [0]
    flat_board = sum(board, [])
    return correct == flat_board

def get_neighbors(position):
    row, col = position
    neighbors = [
        (row + 1, col), (row - 1, col),
        (row, col + 1), (row, col - 1)
    ]
    valid_neighbors = [(r, c) for r, c in neighbors if 0 <= r < GRID_SIZE and 0 <= c < GRID_SIZE]
    return valid_neighbors

def bfs_solve(start_board):
    start = tuple(map(tuple, start_board))
    goal = tuple(tuple(range(1, GRID_SIZE * GRID_SIZE)) + (0,))
    queue = deque([(start, [])])
    visited = set([start])
    
    while queue:
        current, path = queue.popleft()
        if current == goal:
            return path
        
        empty_pos = next((i, j) for i, row in enumerate(current) for j, val in enumerate(row) if val == 0)
        for neighbor in get_neighbors(empty_pos):
            new_board = [list(row) for row in current]
            swap_tiles(new_board, empty_pos, neighbor)
            new_board_tuple = tuple(map(tuple, new_board))
            
            if new_board_tuple not in visited:
                visited.add(new_board_tuple)
                queue.append((new_board_tuple, path + [neighbor]))
    
    return None  # Si no hay solución

def manhattan_distance(board):
    distance = 0
    for i in range(GRID_SIZE):
        for j in range(GRID_SIZE):
            if board[i][j] != 0:
                current_row, current_col = i, j
                goal_row, goal_col = divmod(board[i][j] - 1, GRID_SIZE)
                distance += abs(current_row - goal_row) + abs(current_col - goal_col)
    return distance

def a_star_solve(start_board):
    # Constantes
    INF = float('inf')
    GRID_SIZE = 4

    # Función de costo
    def manhattan_distance(board):
        distancia = 0
        for i in range(GRID_SIZE):
            for j in range(GRID_SIZE):
                value = board[i][j]
                if value != 0:
                    correct_position = (value - 1) // GRID_SIZE, (value - 1) % GRID_SIZE
                    distancia += abs(correct_position[0] - i) + abs(correct_position[1] - j)
        return distancia

    # Función de costo total
    def total_cost(node):
        return node['cost'] + manhattan_distance(node['board'])

    # Pila de nodos a visitar
    open_list = []
    heapq.heappush(open_list, {'board': start_board, 'cost': 0, 'parent': None})

    # Diccionario para almacenar los nodos visitados
    closed_list = set()

    while open_list:
        # Obtener el nodo con el costo mínimo de la pila
        node = heapq.heappop(open_list)

        # Si el nodo es la solución, devolver el camino
        if is_solved(node['board']):
            camino = []
            while node['parent'] is not None:
                camino.append(node)
                node = node['parent']
            camino.reverse()
            return camino

        # Marcamos el nodo como visitado
        closed_list.add(tuple(map(tuple, node['board'])))

        # Obtener los vecinos del nodo
        for neighbor in get_neighbors(node['board']):
            # Obtener el valor del vecino
            neighbor_value = node['board'][neighbor[0]][neighbor[1]]

            # Si el vecino es cero, es un movimiento válido
            if neighbor_value == 0:
                # Crear un nuevo nodo con el vecino
                new_board = [row[:] for row in node['board']]
                new_board[neighbor[0]][neighbor[1]] = 15 - sum(sum(row) for row in new_board)  # Ingresar el valor correcto al vecino

                # Calcular el costo total del nuevo nodo
                new_cost = node['cost'] + 1

                # Verificar si el nuevo nodo ya se ha visitado
                if tuple(map(tuple, new_board)) not in closed_list:
                    # Agregar el nuevo nodo a la pila
                    heapq.heappush(open_list, {'board': new_board, 'cost': new_cost, 'parent': node})

    # Si no se encuentra una solución, devolver None
    return None

# Modificar la función main para usar a_star_solve en lugar de bfs_solve
def main():
    clock = pygame.time.Clock()
    board = create_initial_board()
    solving = False
    solution_path = []

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.MOUSEBUTTONDOWN and not solving:
                x, y = pygame.mouse.get_pos()
                if y > WINDOW_HEIGHT - 50:  # Click en el botón de resolver
                    solving = True
                    solution_path = a_star_solve(board)
                else:
                    click_pos = (y // TILE_SIZE, x // TILE_SIZE)
                    empty_tile = find_empty_tile(board)
                    if empty_tile and is_valid_move(empty_tile, click_pos):
                        swap_tiles(board, empty_tile, click_pos)

        if solving and solution_path:
            next_move = solution_path.pop(0)
            empty_tile = find_empty_tile(board)
            swap_tiles(board, empty_tile, next_move)
            if not solution_path and is_solved(board):
                solving = False

        draw_board(board)
        pygame.display.flip()
        clock.tick(FPS)

        if is_solved(board) and not solving:
            print("¡Puzzle resuelto!")

if __name__ == "__main__":
    main()
"" ha dado un error: "Traceback (most recent call last):
  File "c:\Users\david\Documents\Proyectos Python\Test python\slider.py", line 223, in <module>
    main()
  File "c:\Users\david\Documents\Proyectos Python\Test python\slider.py", line 201, in main
    solution_path = a_star_solve(board)
                    ^^^^^^^^^^^^^^^^^^^
  File "c:\Users\david\Documents\Proyectos Python\Test python\slider.py", line 164, in a_star_solve
    for neighbor in get_neighbors(node['board']):
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "c:\Users\david\Documents\Proyectos Python\Test python\slider.py", line 79, in get_neighbors
    row, col = position
    ^^^^^^^^
ValueError: too many values to unpack (expected 2)"