murderface murderface - 13 days ago 5
C# Question

Omitting the selection of checkboxes

So I have a drum machine with a random button that fills every checkbox randomly. I want no 2 drums to play at the same time. There are 16 beats, with 5 drums total. So I'm thinking of using a for loop that examines the current value in the list, then set the checkbox boolean to false for values plus or minus 16.

For example: if checkbox 1 is selected, checkboxes 17, 33, 49, and 65 should be empty. Likewise if checkbox 56 is selected, 8, 24, 40, and 72 should be unchecked. The same should go for every checkbox. I'm not sure how to do this.

This is my form it will help display my intent

Here is the code for randomly filling the checkboxes:

private void randombuttonClick(object sender, EventArgs e)
{
List<CheckBox> Checkboxlist = new List<CheckBox>();
foreach (CheckBox control in this.Controls.OfType<CheckBox>())
{
Checkboxlist.Add(control);
control.Checked = false;
}

for (int i = 0; i <= 50; i++)
{
var r = random.Next(0, Checkboxlist.Count);
var checkbox = Checkboxlist[r];
Checkboxlist[r].Checked = true;
}
}


Thanks for looking!

Answer

First of all - you probably want to order that list of checkboxes by something. If you have your TabIndex properties set correctly, you can do:

foreach (CheckBox control in this.Controls.OfType<CheckBox>().OrderBy(x => x.TabIndex))
{
    //...
}

Second, the simplest solution is probably to iterate through the columns, picking a random drum to play.

List<CheckBox> checkboxList = this.Controls.OfType<CheckBox>()
    .OrderBy(x => x.TabIndex)
    .ToList(); //it's simpler than a foreach loop
for (int i = 0; i < 16; i++)
{
    var instrumentIndex = random.Next(0, 4); //make it (0, 5) if you want to allow an entirely empty column
    for (int j = 0; j < 4; j++)
    {
        checkboxList[j*16 + i] = (j == instrumentIndex);
    }
}

The code loops over the columns using the i variable to store the current column number. For each column, it picks a random row out of four (like the comment says, if you want "no instrument in current beat" to be an option, just extend the random range to include 4, which will not match any of the rows).

Then, for each checkbox in that column (starting with ith checkbox, which is in the first row and in the ith column, and moving 16 checkboxes each time, which moves down exactly one row), it assigns true when the row number matches the randomly selected one, and false otherwise.