1

The code is for a number guessing game, it is suppose to generate a random number between 1-100 and the user is then suppose to guess the number. It will tell them if it is too high, or too low so they can continue to guess until they get it right (max of 10 guesses though).

I'm having problems(at least I think this is the problem) with setting and dealing with myGuess which is suppose to be the user's guess that they enter. There's no errors (anything underlined) in my code, but when I run it, no matter what number I enter it says your guess is too low in the debugger output. And I feel like it has something to do with the fact that myGuess isn't properly set the way I am thinking it is.

The class I created is suppose to be written so it can be used in any user interface, so I can't use any GUI controls, which is why I'm struggling.

Code for class I created:

namespace NumberGuessingGame
{
    public class GuessingGame
    {

        int myGuess;
        int guessesLeft = 0;
        int gamesPlayed;
        int gamesWon;
        int gamesLost;

        public GuessingGame()
        {            
        }
        public GuessingGame(int inputGuess)
        {
            myGuess = inputGuess;
        }
        public int Guess
        {
            get
            {
                return myGuess;
            }
            set
            {
                myGuess = value;
            }
        }
        public void checkGuess()
        {
            Random rand = new Random();
            int number = rand.Next(1, 100);

            if (guessesLeft > 10)
            {
                Console.WriteLine("you lose!");
                gamesLost++;
                gamesPlayed++;
            }
            else if (myGuess > number)
            {
                Console.WriteLine("your guess is too high, try again.");
                guessesLeft++;
            }
            else if (myGuess < number)
            {
                Console.WriteLine("your guess is too low, try again.");
                guessesLeft++;
            }
            else
            {
                Console.WriteLine("you win!");
                gamesPlayed++;
                gamesWon++;
            }
        }
    }
}

Code for the form class:

namespace NumberGuessingGame
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();           
        }

        int inputGuess = Convert.ToInt32(txtGuess.Text);
        GuessingGame myGuess = new GuessingGame(inputGuess); 

        private void btnCheck_Click(object sender, EventArgs e)
        {           
            myGuess.checkGuess();
        }
    }
}

The error I am getting now is

Error   1   A field initializer cannot reference the non-static field, method, or property 'NumberGuessingGame.frmMain.txtGuess'    

and

Error   2   A field initializer cannot reference the non-static field, method, or property 'NumberGuessingGame.frmMain.inputGuess'
3
  • 2
    Where do you pass in the user input? You instantiate GuessingGame with the default constructor and I don't see where you set myGuess.Guess. Commented Sep 21, 2015 at 1:09
  • Random rand = new Random(); int number = rand.Next(1, 100); This two lines will spoil your game because every moment user will try to guess it will generate new value. Commented Sep 21, 2015 at 3:22
  • @CodingFeles I noticed that happening. Where should I move the Random rand = new Random(); int number = rand.Next(1, 100); in order for that not to happen? Commented Sep 21, 2015 at 3:25

3 Answers 3

1

Disclaimer: Author has updated the question, so my answer only reference second error. Although first error has same cause.

Your error

Error 2 A field initializer cannot reference the non-static field, method, or property 'NumberGuessingGame.frmMain.inputGuess'

is in this line:

int inputGuess = Convert.ToInt32(txtGuess.Text);

That means that you try to assign to field (variable stored in class) non-constant value(apart from object creation).

To avoid this, assign it in your button click handler.

But there are few more issues:

  1. Your user input should not go as constructor parameter, because each guess will lead to creating new object. You need to add it as parameter to your checkGuess.
  2. You should not generate random number each time user try to guess.
  3. You have counter of lost games, so you need a way to reset your game. Maybe you should add another button for new game, but I will suggest to reset game each time you end it.

Here is version of your game class with my suggestions:

public class GuessingGame
{

    int guessesLeft = 0;
    int gamesPlayed = 0;
    int gamesWon = 0;
    int gamesLost = 0;
    int myGuess = 0;

    Random rand;
    int number = 0;

    public GuessingGame()
    {
       rand = new Random();
       number = rand.Next(1, 100);
    }

    public int Guess
    {
        get
        {
            return myGuess;
        }
        set
        {
            myGuess = value;
        }
    }

    // Reset game method. You can call it from form too.
    public void ResetGame()
    {
        number = rand.Next(1, 100);
        guessesLeft = 0;
    }

    public void checkGuess(int newGuess)
    {
        myGuess = newGuess;

        if (guessesLeft > 10)
        {
            Console.WriteLine("you lose!");
            gamesLost++;
            gamesPlayed++;
            ResetGame();
        }
        else if (myGuess > number)
        {
            Console.WriteLine("your guess is too high, try again.");
            guessesLeft++;
        }
        else if (myGuess < number)
        {
            Console.WriteLine("your guess is too low, try again.");
            guessesLeft++;
        }
        else
        {
            Console.WriteLine("you win!");
            gamesPlayed++;
            gamesWon++;
            ResetGame();
        }
    }
}

And your form will look like this:

public partial class frmMain : Form
{
    public frmMain()
    {
        InitializeComponent();           
    }

    GuessingGame myGuess = new GuessingGame(); 

    private void btnCheck_Click(object sender, EventArgs e)
    {      
        // I suggest to add here textbox text validation
        // so user couldn't input anything apart number.
        int inputGuess = Convert.ToInt32(txtGuess.Text);     
        myGuess.checkGuess(inputGuess);
    }
}

In details about error:

These lines from code you provided in question will be executed in the moment your form are created:

int inputGuess = Convert.ToInt32(txtGuess.Text);
GuessingGame myGuess = new GuessingGame(inputGuess); 

First line is unappropriate(compiler tells us about it with error). But with second line your GuessingGame won't get actual user input. In order to get user input we need to process it after some event which will happen after user write it down in textbox. That's why you should do such things in event handlers methods.

Sign up to request clarification or add additional context in comments.

1 Comment

@Alex you're welcome! Note: I've deleted my comments, because there are no useful information for solution itself. So they wouldn't cause confusion to anyone looking for answer.
1

When you are creating a default constructor

GuessingGame myGuess = new GuessingGame();

the value for int myGuess; is always 0 and thus it always shows you "your guess is too low!" You need to assign the value to the myGuess variable inside your Class.

I believe the variable can be set from the user input. So it could be done something like this

int UserGuessed = Convert.ToInt32(TextBoxName.Text);
GuessingGame myGuess = new GuessingGame(UserGuessed);

8 Comments

My guess is that user input is outside the scope of the assignment and will be covered in a follow-up assignment.
(same goes for the string to int type conversion)
in that case you can directly assign the value in the constructor. GuessingGame myGuess = new GuessingGame(11);
Yeah, and I am thinking the names of the variables should be switched around so that myGuess is the local variable in checkGuess() number is the member variable in GuessingGame... but whatever.
When I do this I get an error saying "A field initializer cannot reference the non-static field, method, or property". If i keep it in the same spot that is. Any ideas how to fix this?
|
0

myGuess which is set in your second constructor is never initialized and will default to 0. The checkGuess() method is picking a number between 1 and 100 and will never get 0.

Try and change the line from:

GuessingGame myGuess = new GuessingGame();

GuessingGame myGuess = new GuessingGame(new Random().Next(1,100));

5 Comments

I thought the point was to accept user input? This is just passing a random number into the constructor and comparing it to another random number. OP needs to capture user input.
This is wrong. it should be new GuessingGame(int.Parse(textbox.Text)); where textbox is where user puts the number!
@Alex you still need it. the current number you are passing is random generated. the result you are observing is two random numbers generated and checked against each other. not against user input!
I've seen this type of program written by students at a nearby community college (one of our operational guys was taking a class). Initially, the program does not take user input but later iterations do.
@M.kazem Akhgary you won't get appropriate values when you use such constuction in field initializer. Because your textbox.Text is empty. It would be right if it used in another place. See my answer for details.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.