Search code examples
c#asp.netpostbackviewstatepage-lifecycle

Improving number guessing game code


I'm trying to make a small guessing game where it generates a random number, and the user enters in a number using a TextBox and Button. Currently it is creating the random number and doing everything I want, but every time the user presses submit on the button, it generates a new random number for them to guess

I am very new to ASP.NET type stuff, so my code is probably inefficient and incorrect lol, so I have two particular questions.

  1. How can I improve my code to make it work better/work at all.
  2. Do I need a runner class to make it work, and how would I do so?
public partial class WebPageSeparated : System.Web.UI.Page
{
    private int randNum;
    private int theirGuess;
    public WebPageSeparated()
    {
        Random randomNum = new Random();
        randNum = randomNum.Next(0, 10);
        theirGuess = 0;
    }
    protected void Page_Load(object sender, EventArgs e)
    {
        Label1.Text = "Guessing game! Guess a number between [0,10) to see if you can get it right!";
        new WebPageSeparated();
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
       try
        {
            theirGuess = Convert.ToInt32(TextBox1.Text);
            if (theirGuess != this.randNum)
            {
                Label1.Text = "Sorry, wrong number.  Please try again!";
            }
            else if(theirGuess == this.randNum)
            {
                Label1.Text = "Correct! A new number has been generated, go ahead and try to do it again!";
                new WebPageSeparated();
            }
        }
        catch (System.FormatException)
        {
            Label1.Text = "Enter a number [1,10)";
        }
    }
}

Solution

  • Several things are wrong with your code:

    You should never create a new instance of your page (new WebPageSeparated()). A new instance is created every time you navigate to the page (by entering its URL in the browser) and whenever you cause a PostBack (e.g. by clicking an asp:button).

    If you want to have some code, which runs only the first time the page is invoked (i.e. not during a PostBack, only when navigating to the page), then you should wrap that code in a if (!IsPostBack) {} block.

    Because a new instance of the page is created for each PostBack, you cannot store any state (the random number) in an instance-field of the page. You have to find another place where you store the state, e.g:

    • in a static field, e.g: private static int randNum
      • note: this is not recommended, since the static field is shared between all instances of your page (doesn't work if multiple users are on your website at the same time)
    • in a session variable, e.g. Session["randNum"] = randomNum.Next(0, 10)
    • in the ViewState of the page, e.g. ViewState["randNum"] = ...
      • this is what I'd recommend for your sample
    • in a database

    With all these points in mind, your Page_Load method would look something like this:

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Random randomNum = new Random();
                randNum = randomNum.Next(0, 10);
                ViewState["randNum"] = randNum;
            }
            else
            {
                randNum = (int) ViewState["randNum"];
            }
            Label1.Text = "Guessing game! Guess a number between [0,10) to see if you can get it right!";
        }
    

    Also, in the case, the user guesses the correct number, you should generate and store a new random number (as done inside the if (!IsPostBack)).


    Finally, some topics you might want to read more about: Page Lifecycle, PostBack, Viewstate, Session-state