C# / I fill up a DataGridView from a string array by picking the next cell randomly and do not want to pick used cell again

Viewed 97

I have a string array and have to fill up a DataGridView with it by picking a random next cell. I want to use all items of the array but avoid to pick a cell I already filled up. It is fine if there are empty cells but I have to use all items.

What I tried:

foreach (var item in myarray)
        {
            y = random.Next(0, 5);
            x = random.Next(0, t.Rows.Count);
            t.CurrentCell = t[y, x];

            for (int j = 0; j < t.Columns.Count; j++)
            {
                
                for (int k = 0; k < t.Rows.Count; k++)
                {
                   
                    if (t.Rows[k].Cells[j].Value == null)
                    {
                        t.CurrentCell.Value = item;
                    }
                }
            }
        }

                    

Many thanks!

1 Answers

You can assign a number to each cell from left to right, like for 4x4 matrix each cell will be numbered from 0 to 15. After that you can shuffle 0...15 array of integers and iterate over that array by assigning a string to the corresponding cell which you can get by converting a number from array (cellNumber) back to coordinates like this: (cellNumber / rowsCount, cellNumber % columnsCount).

Consider following source code:

private static Random rng = new Random();  

public static void Shuffle<T>(this IList<T> list)  
{  
    int n = list.Count;  
    while (n > 1) {  
        n--;  
        int k = rng.Next(n + 1);  
        T value = list[k];  
        list[k] = list[n];  
        list[n] = value;  
    }  
}

public static (int x, int y) GetCoordinates(int cellNumber, int rowsCount, int columnsCount) {
    return (cellNumber / rowsCount, cellNumber % columnsCount);
}

public static void Main()
{
    var rowsCount = 4;
    var columnsCount = 4;
    var cellNumbers = Enumerable.Range(0,rowsCount*columnsCount - 1).ToList();
    cellNumbers.Shuffle();
    foreach (var cellCoordinates in cellNumbers.Select(x => GetCoordinates(x, rowsCount, columnsCount))) {
        Console.WriteLine($"{cellCoordinates.x},{cellCoordinates.y}");
    }
}
Related