Homework Help (C# GUI, Random Number Guessing Game)

manicmike

Honorable
Mar 3, 2012
26
0
10,580
As the title states, this is for homework.

I'm tasked with creating a program that allows a user to input a number into a GUI, and then compares their answer to the random number. Most of the remaining code is cake but when I tested what I have so far, EVERY time the Guess button is clicked, it generates a new random Number.

All I want to know is how to keep it from generating a new number every time I click Guess...

Simple code from VS 2013 Ultimate
Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RandomNumbersGame
{
    public partial class RandomNumbersForm : Form
    {
        
        
        public RandomNumbersForm()
        {
            InitializeComponent();
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void RandomNumbersForm_Load(object sender, EventArgs e)
        {
            Random randomGenerator = new Random();
            int randomNum = randomGenerator.Next(1,101);
            int randomNumber = randomNum;
            
        }

        private void guessButton_Click(object sender, EventArgs e, int randomNumber)
        {
            
            int myGuess, counter = 0;
            int.TryParse(userGuessTextBox.Text, out myGuess);
            counter++;

            MessageBox.Show(randomNumber.ToString()); // Inplace to check random number, will  be removed from final

            if (randomNumber == myGuess)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(myGuess + "\t\t\tNumber of Guesses: " + counter);
                MessageBox.Show("Congratulations! You guessed Correctly in only " + counter + " guesses!");
            }

            if (myGuess > randomNumber)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(myGuess + "\t\t\tToo High, Try Again");
            }

            if (myGuess < randomNumber)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(myGuess + "\t\t\tToo Low, Try Again");
            }
        }
    }
}



Full Code
Code:
namespace RandomNumbersGame
{
    partial class RandomNumbersForm
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.guessesListBox = new System.Windows.Forms.ListBox();
            this.guessInputLabel = new System.Windows.Forms.Label();
            this.userGuessTextBox = new System.Windows.Forms.TextBox();
            this.userGuessLabel = new System.Windows.Forms.Label();
            this.guessButton = new System.Windows.Forms.Button();
            this.giveUpButton = new System.Windows.Forms.Button();
            this.newButton = new System.Windows.Forms.Button();
            this.exitButton = new System.Windows.Forms.Button();
            this.numberOfGuessesLabel = new System.Windows.Forms.Label();
            this.numberOfGuessesTextBox = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // guessesListBox
            // 
            this.guessesListBox.FormattingEnabled = true;
            this.guessesListBox.Location = new System.Drawing.Point(13, 13);
            this.guessesListBox.Name = "guessesListBox";
            this.guessesListBox.Size = new System.Drawing.Size(433, 407);
            this.guessesListBox.TabIndex = 0;
            // 
            // guessInputLabel
            // 
            this.guessInputLabel.AutoSize = true;
            this.guessInputLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.guessInputLabel.Location = new System.Drawing.Point(453, 13);
            this.guessInputLabel.Name = "guessInputLabel";
            this.guessInputLabel.Size = new System.Drawing.Size(408, 24);
            this.guessInputLabel.TabIndex = 1;
            this.guessInputLabel.Text = "Please enter a Number between 1 and 100";
            // 
            // userGuessTextBox
            // 
            this.userGuessTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.userGuessTextBox.Location = new System.Drawing.Point(705, 43);
            this.userGuessTextBox.Name = "userGuessTextBox";
            this.userGuessTextBox.Size = new System.Drawing.Size(100, 29);
            this.userGuessTextBox.TabIndex = 2;
            // 
            // userGuessLabel
            // 
            this.userGuessLabel.AutoSize = true;
            this.userGuessLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.userGuessLabel.Location = new System.Drawing.Point(522, 46);
            this.userGuessLabel.Name = "userGuessLabel";
            this.userGuessLabel.Size = new System.Drawing.Size(99, 24);
            this.userGuessLabel.TabIndex = 4;
            this.userGuessLabel.Text = "My Guess:";
            // 
            // guessButton
            // 
            this.guessButton.Location = new System.Drawing.Point(466, 159);
            this.guessButton.Name = "guessButton";
            this.guessButton.Size = new System.Drawing.Size(200, 80);
            this.guessButton.TabIndex = 5;
            this.guessButton.Text = "Check my Guess";
            this.guessButton.UseVisualStyleBackColor = true;
            this.guessButton.Click += new System.EventHandler(this.guessButton_Click);
            // 
            // giveUpButton
            // 
            this.giveUpButton.Location = new System.Drawing.Point(672, 159);
            this.giveUpButton.Name = "giveUpButton";
            this.giveUpButton.Size = new System.Drawing.Size(200, 80);
            this.giveUpButton.TabIndex = 6;
            this.giveUpButton.Text = "Give Up";
            this.giveUpButton.UseVisualStyleBackColor = true;
            // 
            // newButton
            // 
            this.newButton.Location = new System.Drawing.Point(466, 246);
            this.newButton.Name = "newButton";
            this.newButton.Size = new System.Drawing.Size(200, 80);
            this.newButton.TabIndex = 7;
            this.newButton.Text = "New Number";
            this.newButton.UseVisualStyleBackColor = true;
            // 
            // exitButton
            // 
            this.exitButton.Location = new System.Drawing.Point(673, 246);
            this.exitButton.Name = "exitButton";
            this.exitButton.Size = new System.Drawing.Size(200, 80);
            this.exitButton.TabIndex = 8;
            this.exitButton.Text = "Exit";
            this.exitButton.UseVisualStyleBackColor = true;
            this.exitButton.Click += new System.EventHandler(this.exitButton_Click);
            // 
            // numberOfGuessesLabel
            // 
            this.numberOfGuessesLabel.AutoSize = true;
            this.numberOfGuessesLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.numberOfGuessesLabel.Location = new System.Drawing.Point(522, 361);
            this.numberOfGuessesLabel.Name = "numberOfGuessesLabel";
            this.numberOfGuessesLabel.Size = new System.Drawing.Size(187, 24);
            this.numberOfGuessesLabel.TabIndex = 9;
            this.numberOfGuessesLabel.Text = "Number Of Guesses:";
            // 
            // numberOfGuessesTextBox
            // 
            this.numberOfGuessesTextBox.BackColor = System.Drawing.SystemColors.Window;
            this.numberOfGuessesTextBox.Enabled = false;
            this.numberOfGuessesTextBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.numberOfGuessesTextBox.Location = new System.Drawing.Point(740, 361);
            this.numberOfGuessesTextBox.Name = "numberOfGuessesTextBox";
            this.numberOfGuessesTextBox.Size = new System.Drawing.Size(65, 29);
            this.numberOfGuessesTextBox.TabIndex = 0;
            // 
            // RandomNumbersForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(884, 433);
            this.Controls.Add(this.numberOfGuessesTextBox);
            this.Controls.Add(this.numberOfGuessesLabel);
            this.Controls.Add(this.exitButton);
            this.Controls.Add(this.newButton);
            this.Controls.Add(this.giveUpButton);
            this.Controls.Add(this.guessButton);
            this.Controls.Add(this.userGuessLabel);
            this.Controls.Add(this.userGuessTextBox);
            this.Controls.Add(this.guessInputLabel);
            this.Controls.Add(this.guessesListBox);
            this.Name = "RandomNumbersForm";
            this.Text = "Random Number Guessing Game";
            this.Load += new System.EventHandler(this.RandomNumbersForm_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.ListBox guessesListBox;
        private System.Windows.Forms.Label guessInputLabel;
        private System.Windows.Forms.TextBox userGuessTextBox;
        private System.Windows.Forms.Label userGuessLabel;
        private System.Windows.Forms.Button guessButton;
        private System.Windows.Forms.Button giveUpButton;
        private System.Windows.Forms.Button newButton;
        private System.Windows.Forms.Button exitButton;
        private System.Windows.Forms.Label numberOfGuessesLabel;
        private System.Windows.Forms.TextBox numberOfGuessesTextBox;
    }
}
 
Solution


Well the thing is that when you declare it in the function you might be setting it to 0 every call
which obviously isn't right. Of course you can only assign non constants in a function

I am absolutely stumped on why the number is changing though

smeezekitty

Honorable
Sep 11, 2012
55
0
10,590
I really don't know much about C# and cannot run your code without a C# compiler
But it would seem that RandomNumbersForm_Load is being called when it shouldn't be.

I would put a MessageBox.Show in the RandomNumbersForm_Load to know for sure if it is being called

Does it have a step through debugger?
 

manicmike

Honorable
Mar 3, 2012
26
0
10,580
No, the debugger just runs the program, complains about no Overload method for the guessButton, but runs anyways fine except for the number changing every time I guess. I will try that on Load to see if it is loading every time I guess
 

manicmike

Honorable
Mar 3, 2012
26
0
10,580
Ok, I tried both Message Boxing and adding to the list box a string that says the form loads, but it never displays either version of output... Here I sit, having saved the "easiest program" for last, and it's due at midnight. Stupid Titanfall...
 

manicmike

Honorable
Mar 3, 2012
26
0
10,580
The form looks like this:
Code:
______________________________
|_____________________________|
| [Output area]       |  [Instructions]      |
|                      |  [Input]            |
|                      |                     |
|                      |                     |
|                      |[Guess][Give Up] |
|                      |[StartOver][Exit]   |
|                      |  [# of guesses]   |
--------------------------------------------------

I edited this 4 times and this is close enough... >.<
(Side note, TH Preview button isn't working...)
 

manicmike

Honorable
Mar 3, 2012
26
0
10,580
That's another issue, no.

I've gotten to this...

Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace RandomNumbersGame
{

    public partial class RandomNumbersForm : Form
    {
        public RandomNumbersForm()
        {
            int randomNumber = randomInitializer();
            int counter = 0;
            InitializeComponent();
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void RandomNumbersForm_Load(object sender, EventArgs e)
        {
           
            //int randomNum = randomGenerator.Next(1, 101);
        }

        private void guessButton_Click(object sender, EventArgs e, int randomNumber, int counter)
        {
            int guess;
            int.TryParse(userGuessTextBox.Text, out guess);
            randomChecker(guess, randomNumber, counter);
        }

        private int randomInitializer()
        {
            Random randomGenerator = new Random();
            int randomNum = randomGenerator.Next(1, 101);
            return randomNum;
        }

        private void randomChecker(int guess, int randomNum, int counter)
        {


            if (randomNum == guess)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(guess + "\t\t\tNumber of Guesses: " + counter);
                MessageBox.Show("Congratulations! You guessed Correctly in only " + counter + " guesses!");
                counter++;
            }

            else if (guess > randomNum)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(guess + "\t\t\tToo High, Try Again");
                counter++;
            }

            else if (guess < randomNum)
            {
                numberOfGuessesTextBox.Text = counter.ToString();
                guessesListBox.Items.Add(guess + "\t\t\tToo Low, Try Again");
                counter++;
            }

            else
                counter++;
        }
 
    }
}

Random number will not stay constant, and Counter goes to 1 then will not increment further...
 

manicmike

Honorable
Mar 3, 2012
26
0
10,580
I did attempt that, I can declare the Random Object in the namespace, and I can declare int randomNum in the namespace, but it's won't let me assign a value in said Namespace.

If I assign the value elsewhere in the program it still changes. Also, I can't declare const int because the assigning variable also needs to be a const.
 

smeezekitty

Honorable
Sep 11, 2012
55
0
10,590


Well the thing is that when you declare it in the function you might be setting it to 0 every call
which obviously isn't right. Of course you can only assign non constants in a function

I am absolutely stumped on why the number is changing though
 
Solution

randomizer

Distinguished
Are you sure you're not constantly running an earlier version of your code? What you have here doesn't compile. Your event handler guess_Click has 4 parameters but should only have two to match the signature for a System.EventHandler delegate. You cannot pass the counter and random number to this method as parameters, you'll need to provide them elsewhere. The simplest way to do this is to store it in a private field within your RandomNumbersForm class (a field holds information about the state of its containing class). It will then be accessible anywhere within that class. Since you've already submitted the assignment I'll post a possible solution:

Code:
using System;
using System.Windows.Forms;

namespace RandomNumbersGame
{
    public partial class RandomNumbersForm : Form
    {
        public RandomNumbersForm()
        {
            _randomNumber = randomInitializer();
            InitializeComponent();
        }

        private void exitButton_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void RandomNumbersForm_Load(object sender, EventArgs e)
        {
            //int randomNum = randomGenerator.Next(1, 101);
        }

        private void guessButton_Click(object sender, EventArgs e)
        {
            int guess;

            if (int.TryParse(userGuessTextBox.Text, out guess))
            {
                randomChecker(guess);
            }
            else
            {
                MessageBox.Show(string.Format("'{0}' is not a valid guess!", userGuessTextBox.Text));
            }
        }

        private int randomInitializer()
        {
            return new Random().Next(1, 101);
        }


        private void randomChecker(int guess)
        {
            _counter++;
            numberOfGuessesTextBox.Text = _counter.ToString();

            if (guess == _randomNumber)
            {
                guessesListBox.Items.Add(guess + "\t\t\tNumber of Guesses: " + _counter);
                MessageBox.Show("Congratulations! You guessed Correctly in only " + _counter + " guesses!");
            }
            else if (guess > _randomNumber)
            {
                guessesListBox.Items.Add(guess + "\t\t\tToo High, Try Again");
            }
            else
            {
                guessesListBox.Items.Add(guess + "\t\t\tToo Low, Try Again");
            }
        }

        private int _randomNumber;
        private int _counter;
    }
}

A few points about what I've added/changed (most of which is likely outside of the scope of the assignment):


  • ■ I've added two private fields to the bottom of the class. They can go anywhere within the class, but typically go at the top, bottom, or near a property that exposes them (which you don't have here and don't need to concern yourself with). Their location within the class is just a code styling issue. You can see that both are accessed by multiple methods.
    ■ I've inlined the statements in randomInitializer() for brevity. Entirely unnecessary but I just hate variables that are only used once unless it aids readability. :)
    ■Your randomChecker() method had several bits of code that were duplicated in each branch of the if-else (counter increment and setting of the textbox text) because they are executed in all cases. I've moved these outside of those blocks so that they are only there once.
    ■ You were using int.TryParse() but ignoring the return value. If the user had entered something bad, you'd have always passed in 0 as the guess, since 0 is the default value for an integer. I've changed this so that an error message pops up if the text can't be parsed.