0
\$\begingroup\$

I'm building a number guessing game in Unity. The computer has 10 chances to guess the number the player is thinking of. The player interacts by pressing Higher or Lower or Correct Guess.

The basic game works fine, as long as the player is honest. I'm now trying to make the game watertight and prevent any user error or dishonesty about their number. I created some test conditions to check if the random number generator has produced a number already used before, or to check if the player is pressing Higher or Lower beyond the max and min guess range.

The problem can be demonstrated well by constantly pressing Lower to the point where the final guess is the number 1. Pressing Lower again results in the game freezing. It also happens if the number you are thinking of is displayed and you press Higher or Lower towards a range of numbers which have already been eliminated as possibilities. I am thinking this is due to the game getting stuck in my while loop in MakeGuess().

I think the problem lies in the following test condition in MakeGuess() but any tweaks I make seem to have no effect:

// check if number has been guessed before
if (newGuess == guess && (newGuess > max || newGuess < min)) {

I've uploaded my current playable build to GameBucket.io here: https://gamebucket.io/game/07cc2b61-493b-46ae-a446-aeaa98ffac0e

All the game logic is handled in the NumberWizard script which is attached to the NumberWizard GameObject in the main Game scene:

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class NumberWizard : MonoBehaviour
{
    int max;
    int min;
    int newGuess;
    public int guess;
    public int maxGuessesAllowed = 10;

    public Text text;
    public Text guessesRemaining;

    // Use this for initialization
    void Start()
    {
        StartGame();
    }

    void StartGame()
    {
        max = 1000;
        min = 1;

        MakeGuess();
        UpdateDisplay();
    }

    public void GuessHigher()
    {
        min = guess;
        NextGuess();
    }

    public void GuessLower()
    {
        max = guess;
        NextGuess();
    }

    public void GuessCorrect()
    {
        StartGame();
        SceneManager.LoadScene("Lose");
    }

    void NextGuess()
    {
        if (maxGuessesAllowed <= 0) SceneManager.LoadScene("Win");

        MakeGuess();
        maxGuessesAllowed -= 1;
        UpdateDisplay();
    }

    void UpdateDisplay()
    {
        text.text = guess.ToString() + " ?";
        guessesRemaining.text = maxGuessesAllowed.ToString();
    }

    void MakeGuess()
    {
        //guess = (max + min) / 2; // old guessing method

        bool validGuess = false;

        while (validGuess == false)
        {
            newGuess = GenerateNumber();

            // check if number has been guessed before
            if (newGuess == guess && (newGuess > max || newGuess < min))
            {
                Debug.Log("Number has been guessed before and is already at either range limit.");
                SceneManager.LoadScene("Lose2");
            }
            else if(newGuess == guess)
            {
                newGuess = GenerateNumber();
                Debug.Log("Number has been guessed before but is not at range limit.");
            }
            else
            {
                validGuess = true;
                guess = newGuess;
                Debug.Log("Number has not been guessed before.");
            }

            Debug.Log("Min: " + min);
            Debug.Log("Max: " + max);
            Debug.Log("====================");
        }
    }

    int GenerateNumber() {
        int result = Random.Range(min, max + 1); return result;
    }
}

Any help with the code

\$\endgroup\$
1
\$\begingroup\$

The problem isn't with the MakeGuess part of what you're doing, it's changing the value of min or max in GuessHigher or GuessLower.

This can be done by adding an if statement to each of these:

public void GuessHigher()
{
    if (guess > min)
    {
        min = guess;
        NextGuess();
    }
}

public void GuessLower()
{
    if (guess < max)
    {
        max = guess;
        NextGuess();
    }
}

This will also give you the chance to add an Else statement to give you a bit of cover to a cheating player since if the AI has guessed 1 and the player says it is lower, they are cheating / lying.

\$\endgroup\$
  • \$\begingroup\$ That's awesome. I knew it should have been something simpler like this, thanks. I added the bit you suggested to stop players cheating: public void GuessHigher() { if (max > guess) { min = guess; NextGuess(); } else if (max <= guess) { SceneManager.LoadScene("Lose2"); } } public void GuessLower() { if (min < guess) { max = guess; NextGuess(); } else if (min >= guess) { SceneManager.LoadScene("Lose2"); } } \$\endgroup\$ – Profplum Oct 11 '17 at 15:28
  • \$\begingroup\$ One more issue I'm having is with the player being able to keep the game going forever by clicking between Higher and Lower constantly. My debug log says that the min value is set to, say, 429 and the max value is set to 430. Can you suggest a way to prevent this from being possible? Would I have to create a variable to hold the last guess in order to be able to compare with it? Or is there a more elegant way of doing this? \$\endgroup\$ – Profplum Oct 11 '17 at 15:35
  • \$\begingroup\$ @HenryPitman The only thing I would say about that is to run a check to see if the two are more than 1 apart. If they're not, then the correct number must be one or the other. \$\endgroup\$ – Stephen Oct 12 '17 at 10:30
  • \$\begingroup\$ Thanks so much, man. You saved me so. I was getting so frustrated. I changed my GuessHigher() and GuessLower() methods to: public void GuessHigher() { if (max <= guess || guess + 1 == max) { SceneManager.LoadScene("Lose2"); } else if (max > guess) ... public void GuessLower() { if (min >= guess || guess - 1 == min) { SceneManager.LoadScene("Lose2"); } else if (min < guess) ... \$\endgroup\$ – Profplum Oct 12 '17 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.