-1

I'm writing code for a forms application where whenever you mouse over the exit button, a duck quacks at you, and it makes another exit button in a random location that does the same thing. However, whenever I generate a new exit button they follow a downward trend from the top left of the form to the bottom right. The Diagonal Exit Buttons

    public Form1()
    {
        InitializeComponent();
    }

    private void buttonExit_MouseEnter(object sender, EventArgs e)
    {
        int x = 745;
        int y = 475;
        Random randx = new Random();
        Random randy = new Random();
        Button newButton = new Button();
        this.Controls.Add(newButton);
        newButton.Location = new Point(randx.Next(x), randy.Next(y));
        newButton.Size = new Size(88, 37);
        newButton.MouseEnter += NewButton_MouseEnter;
        newButton.Text = ("Exit");


        buttonExit.Location = new Point(randx.Next(x), randy.Next(y));
        SoundPlayer simpleSound = new SoundPlayer(@"C:\Users\Michael\Documents\duck_quack.wav");
        simpleSound.Play();
    }

    private void NewButton_MouseEnter(object sender, EventArgs e)
    {
        int x = 745;
        int y = 475;
        Random randx = new Random();
        Random randy = new Random();
        Button newButton = new Button();
        this.Controls.Add(newButton);
        newButton.Location = new Point(randx.Next(x), randy.Next(y));
        newButton.Size = new Size(88, 37);
        newButton.MouseEnter += NewButton_MouseEnter;
        newButton.Text = ("Exit");

        buttonExit.Location = new Point(randx.Next(x), randy.Next(y));
        SoundPlayer simpleSound = new SoundPlayer(@"C:\Users\Michael\Documents\duck_quack.wav");
        simpleSound.Play();
    }

    private void Form1_FormClosing_1(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
    }
}

What do I seem to be doing wrong? Why are the buttons generating like that? How can I write it so that the buttons generate randomly across the form?

  • You should use just one random generator object. You don't need two, since the next received the maxValue as a param, and do that outside the function, as a member- so the randomness will be effective – audzzy Oct 06 '20 at 17:48
  • A control (which is a form as well as a button) has 4 properties 1) Top 2) Left 3) Height 4) Width. So you want to set the Left and Top location of the button so it is within the width and Height of the form. – jdweng Oct 06 '20 at 17:50
  • What happens now is each random generates the same "random" numbers for x and y, and that's why you get a diagonal... – audzzy Oct 06 '20 at 17:53

3 Answers3

0

Since both handlers do the same thing, just make them point to the same method, no need to have another method with duplicated code.

Also, as the others stated, move your Random out to class level. You can do the same thing with the SoundPlayer:

private int x = 745;
private int y = 475;
private Random rand = new Random();
private SoundPlayer simpleSound = new SoundPlayer(@"C:\Users\Michael\Documents\duck_quack.wav");

private void buttonExit_MouseEnter(object sender, EventArgs e)
{
    // make a new, random button
    Button newButton = new Button();
    newButton.Location = new Point(rand.Next(x), rand.Next(y));
    newButton.Size = new Size(88, 37);
    newButton.MouseEnter += buttonExit_MouseEnter; // <-- they all use the same code!
    newButton.Text = "Exit";
    this.Controls.Add(newButton);

    // move the current button somewhere else:
    Button btn = (Button)sender;
    btn.Location = new Point(rand.Next(x), rand.Next(y));        
    simpleSound.Play();
}

At the bottom, I made whatever button was entered jump to a different location by casting the "sender" parameter to a button and changing its location.

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
0

The random generator is "psudo random" - meaning it generates a number based on a seed it creates based on the time.

Since the Random ganerators are generated at basically the same time (same seed)- and run at the same pace, the numbers are the same - and you get a diagonal... create the Random once, and use it everywhere.

private Random m_rand = new Random();

and in the mouse enter function :

   {
        Button newButton = new Button();
        this.Controls.Add(newButton);
        newButton.Location = new Point(m_rand.Next(this.Width), m_rand.Next(this.Height));
        newButton.Size = new Size(88, 37);
        newButton.MouseEnter += NewButton_MouseEnter;
        newButton.Text = ("Exit");
    }

read more about it here: https://www.codementor.io/@marcell225/the-ultimate-system-random-guide-ts6spvspb

by the way, do you mean to do this in both the exitbutton and the new button?

audzzy
  • 721
  • 1
  • 4
  • 12
-1

Try following :

            int form_width = this.Width;
            int form_height = this.Height;

            Random rand = new Random();

            int buttonLeft = rand.Next(form_width);
            int buttonTop = rand.Next(form_height);

            button1.Left = buttonLeft;
            button1.Top = buttonTop;
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • While this code may solve the question, [including an explanation](//meta.stackexchange.com/q/114762) of how and why this solves the problem would really help to improve the quality of your post, and probably result in more up-votes. Remember that you are answering the question for readers in the future, not just the person asking now. Please [edit] your answer to add explanations and give an indication of what limitations and assumptions apply. – gunr2171 Oct 06 '20 at 17:58