Reputation: 138
I am semi new to C# and I have decided to try out coding a 15 puzzle. This is an exercise I have done in the past in Delphi (Paschal) using 16 buttons, 16 button click events, and a whole lot of if statements. This time, I programmatically created the buttons and I am using a single buttonClick method that all buttons use, and it is set up to check adjacent buttons and change the text of the button if the blank one is there. This I have no problem with. However, when trying to create a scrambler button, the way we did it in Delphi was to create a for look that looped 10,000 times. Inside the loop we randomly picked a number (0-15) and called the Click method for that button. Obviously not all clicks would register but doing this 10,00 times would sufficiently scramble the puzzle. This takes about 1 second to complete in Delphi. In C# I am having a hard time getting the code to perform fast. The Button.PerformClick action seems to run exceedingly slower than I expect it to. Is there something I am doing wrong? I appreciate any help. Thanks!
Here is the code for the scramble button.
void scramble_Click(object sender, MouseEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
int temp = rand.Next(16);
int div = temp % 4;
int rem = temp / 4;
buttonClick(puzzle[div, rem], new EventArgs());
Refresh();
}
}
the buttons are in a 4x4 grid, and are accessed via the random number mod 4, as the x cooridate and random number intDiv 4 for the y coordinate. If you would like any other information please let me know! Thanks again!
Upvotes: 1
Views: 2635
Reputation: 1120
I think most of the "lost time" is trying to move unmovable pieces.
Maybe you could keep a track of the empty space in your puzzle and by using rand.Next(4)
to decide which adjacent piece to move (even refine it to use 3 or 2 if the empty space is on a side or in a corner)
Also, i guess that if the refresh
function is used to "repaint" your board, then it must be because you want to see the puzzle being scrambled. If so, it'll probably look more fluid if you only move movable pieces instead of having delays between moves because the program tries to move unmovable pieces. Else, if you don't care to actually see it moving, you can simply "repaint" the whole board once it has finished scrambling the pieces.
Upvotes: 0
Reputation: 8866
Try this, might help:
void scramble_Click(object sender, MouseEventArgs e)
{
EventArgs ea = new EventArgs();
for (int i = 0; i < 1000; i++)
{
int temp = rand.Next(16);
int div = temp % 4;
int rem = temp / 4;
buttonClick(puzzle[div, rem], ea);
}
Refresh();
}
You shouldn't need to create a new EventArgs object for each click, and you certainly don't need to refresh 1000 times. As Ed S. pointed out in the comments, that's a lot of pointless repainting.
Upvotes: 1