puedes comprimir al maximo este codigo para que pueda ser usado luego en chatgpt como memoria de la IA: "private void AnimarGemasCaen(List<(int, int)> listaGemas, List<(int, int)> listaPrimerBlanco)
    {
        foreach (var columnas in listaPrimerBlanco)
        {
            //seleccionar las gemas de la columna en listaPrimerBlanco
            var gemas = listaGemas.Where(x => x.Item2 == columnas.Item2).ToList();
            var target = positions.FirstOrDefault(p => p.row == columnas.Item1 && p.col == columnas.Item2);
            int i = 0;
            foreach (var gema in gemas)
            {
                GameObject gem = GameObject.Find($"Piece_{gema.Item1}_{gema.Item2}");
                gem.transform.DOMoveY(target.y, 1f).SetEase(Ease.InFlash).SetDelay(2f + (i/2f));
                gem.name = $"Piece_{columnas.Item1 - i}_{columnas.Item2}";
                i++;
                if (columnas.Item1 - i >= 0)
                {
                    target = positions.FirstOrDefault(p => p.row == columnas.Item1 - i && p.col == columnas.Item2);
                }
            }
        }
    }

    private void ShowBoard(int[,] board)
    {
        //Debug Log formatted of the board and in order to see the board
        var mensaje = string.Join("\n", board.Cast<int>().Select((value, index) => new {value, index})
            .GroupBy(x => x.index / N)
            .Select(x => string.Join(" ", x.Select(v => v.value))));

        Debug.Log(mensaje);
    }

    private void ShowGems(List<(int, int)> gems)
    {
        // Debug.Log of the List<(int, int)> gems
        var mensaje = string.Join("\n", gems.Select(row => string.Join(" ", row)));
        Debug.Log(mensaje);
    }

    private void GenerateScreenBoard()
    {
        Vector2 screenSize = new Vector2(Screen.width, Screen.height);
        Debug.Log(screenSize);

        float iconSize = 50f;
        float spacing = 15f;

        float tableWidth = 6 * (iconSize + spacing) - spacing;
        float tableHeight = 6 * (iconSize + spacing) - spacing;
        Vector2 tablePosition = (screenSize - new Vector2(tableWidth, tableHeight)) / 2f;

        List<Vector2> iconPositions = CalculateIconPositions(tablePosition, iconSize, spacing);
        List<Vector2> iconWorldPositions = CalculateIconWorldPositions(iconPositions);

        CreateIcons(iconWorldPositions);
    }

    private List<Vector2> CalculateIconPositions(Vector2 tablePosition, float iconSize, float spacing)
    {
        List<Vector2> iconPositions = new List<Vector2>();
        for (int row = 0; row < 6; row++)
        {
            for (int col = 0; col < 6; col++)
            {
                float x = tablePosition.x + col * (iconSize + spacing);
                float y = tablePosition.y + row * (iconSize + spacing);
                iconPositions.Add(new Vector2(x, y));
            }
        }

        return iconPositions;
    }

    private List<Vector2> CalculateIconWorldPositions(List<Vector2> iconPositions)
    {
        List<Vector2> iconWorldPositions = new List<Vector2>();
        foreach (var iconPosition in iconPositions)
        {
            Vector2 iconWorldPosition = Camera.main.ScreenToWorldPoint(new Vector3(iconPosition.x, iconPosition.y, 0));
            iconWorldPositions.Add(iconWorldPosition);
        }

        return iconWorldPositions;
    }

    private void CreateIcons(List<Vector2> iconWorldPositions)
    {
        //create icons with board data
        for (int row = 0; row < 6; row++)
        {
            for (int col = 0; col < 6; col++)
            {
                var rowi = 5 - row;
                int index = rowi * 6 + col;
                Vector2 iconWorldPosition = iconWorldPositions[index];
                char icon = _board[row][col];
                int spriteIndex = Array.IndexOf(G, icon);
                GameObject newPiece = Instantiate(gemPrefab, iconWorldPosition, Quaternion.identity);
                newPiece.transform.parent = transform;
                newPiece.name = $"Piece_{row}_{col}";
                Position pos = new Position();
                pos.row = row;
                pos.col = col;
                pos.x = iconWorldPosition.x;
                pos.y = iconWorldPosition.y;
                positions.Add(pos);
                newPiece.GetComponent<SpriteRenderer>().sprite = sprites[spriteIndex];
            }
        }
    }

    private GameObject CreateIconsAtPosition(int fila, int columna)
    {
        GameObject newPiece = null;
        // Luego, buscamos la posición del mundo correspondiente en la lista ‘positions’
        Position targetPos = null;
        targetPos = positions.FirstOrDefault(p => p.row == fila && p.col == columna);

        if (targetPos != null)
        {
            int spriteIndex = board[fila, columna];
            newPiece = Instantiate(gemPrefab, new Vector2(targetPos.x, targetPos.y + 6f), Quaternion.identity);
            newPiece.transform.parent = transform;
            newPiece.name = $"Piece_{fila}_{columna}";
            newPiece.GetComponent<SpriteRenderer>().sprite = sprites[spriteIndex];
        }

        return newPiece;
    }


    private static List<List<char>> GenerateBoard()
    {
        List<List<char>> board = new List<List<char>>();
        for (int i = 0; i < N; i++)
        {
            List<char> row = new List<char>();
            for (int j = 0; j < N; j++)
            {
                row.Add(G[Random1.Next(0, G.Length)]);
            }

            board.Add(row);
        }

        return board;
    }

    // Update is called once per frame
    private void Update()
    {
    }

    public List<(int, int)> FindHorizontalLine(int[,] tablero1)
    {
        int N = tablero1.GetLength(1);
        List<List<(int, int)>> gemLines = new List<List<(int, int)>>();

        for (int i = 0; i < tablero1.GetLength(0); i++)
        {
            for (int j = 0; j < N - 2; j++)
            {
                int count = 1;
                for (int k = j + 1; k < N; k++)
                {
                    if (tablero1[i, k] != tablero1[i, j])
                    {
                        break;
                    }

                    count++;
                }

                if (count >= 3)
                {
                    List<(int, int)> gemLine = new List<(int, int)>();
                    for (int l = j; l < j + count; l++)
                    {
                        gemLine.Add((i, l));
                    }

                    gemLines.Add(gemLine);
                    j += count - 1;
                }
            }
        }

        List<(int, int)> gemList = new List<(int, int)>();
        foreach (List<(int, int)> line in gemLines)
        {
            gemList.AddRange(line);
        }

        return gemList;
    }

    public List<(int, int)> FindVerticalLines(int[,] tablero1)
    {
        int N = tablero1.GetLength(1);
        List<List<(int, int)>> gemLines = new List<List<(int, int)>>();

        for (int i = 0; i < tablero1.GetLength(0); i++)
        {
            for (int j = 0; j < N - 2; j++)
            {
                int count = 1;
                for (int k = j + 1; k < N; k++)
                {
                    if (tablero1[k, i] != tablero1[j, i])
                    {
                        break;
                    }

                    count++;
                }

                if (count >= 3)
                {
                    List<(int, int)> gemLine = new List<(int, int)>();
                    for (int l = j; l < j + count; l++)
                    {
                        gemLine.Add((l, i));
                    }

                    gemLines.Add(gemLine);
                    j += count - 1;
                }
            }
        }

        List<(int, int)> gemList = new List<(int, int)>();
        foreach (List<(int, int)> line in gemLines)
        {
            gemList.AddRange(line);
        }

        return gemList;
    }
}"