Random.Range() - Which parameters to give?

In the video, it is said to use:

random.range(min, max+1);

However, since min and max are set to guess, we do not want the program to be able to propose once again the same guess. Therefore, min and max should be excluded, no?

Shouldn’t it be:

random.range(min+1, max);

The only case in which is poses problem is in the initial guess because we want the program to be able to guess 1 and 1000, but this can be fixed by defining min as 0 and max as 1001.
Or did I get it all wrong???

Hello @Benjamin_Mattei,

Random.Range() provides you with a value between two values, however;

If you provide two floats for the min and max values then either value could returned, as both are inclusive.

If you provide two ints for the min and max values then only the min value is inclusive, the max is exclusive.

So, for the first guess of the game, 1(min) and 1001(max) would give you the chance of having a returned value between 1(inclusive) and 1000.

2 Likes

Hello Rob,

Thanks for the clarification. I had missed the different behavior between int and float inputs.
I agree with you for the initial guess, but it would not work the same way afterwards no?
Initially, taking your comment into account, you would have

Random.range(min, max);

then the computer takes a guess. Right now, the code says we should reinitiate

min = guess; // if the user clicks “Higher”

and

max = guess; // if the user clicks “Lower”

Which means the next guess will include the previous guess in the range of values possible. I believe then it should be:

min = guess+1; // if the user clicks “Higher”

and

max = guess - 1; // if the user clicks “Lower”

no?

Hey @Benjamin_Mattei,

It’s been a while since I’ve looked at the specific lecture, could you post up your code from the NumberWizard / Main file for me? Looking at what you’ve posted above I would agree with the +1 min because you’ve already stated that the guess was incorrect. Then the +1 on max would be required in order to ensure the upper most maximum value could be used, but pop the code up so we can see if there is anything else in play also :slight_smile:

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using System.Collections;

public class NumberWizard : MonoBehaviour {

    // Use this for initialization
    int max;
    int min;
    int guess;
    public int maxGuessesAllowed = 6;
    public Text guesstext;

    void Start () {
	StartGame();
    }

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

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

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

    void NextGuess(){
	if (min==max-1) {
		guesstext.text = "Cheater!";
	} else {
		guess = Random.Range(min,max);
		maxGuessesAllowed=maxGuessesAllowed-1;
		if (maxGuessesAllowed==0) {
			SceneManager.LoadScene("Win");
		}
		guesstext.text = guess.ToString();
	}
    }
}

So, let’s run through what’s happening then…

We will say that I choose 925 as my number, Start() is called.


Start()

  • min = 1
  • max = 1000
  • NextGuess() is called

NextGuess()

  • min(1) doesn’t equal max(1000)
  • guess = random number between 1 (inclusive) and 1000 (exclusive)

Notes on NextGuess() at this point;

  • 1000 cannot be returned as a possibility because max is exclusive
  • validation of guesses taken could be improved

for the sake of argument we will assume guess now equals 356

  • guesstext.text is updated

I indicate that my number is higher and click the relevant button, GuessHigher() is called;


GuessHigher()

  • min = 356+1, thus min = 357
  • max remains unchanged, thus max = 1000
  • NextGuess() is called

NextGuess()

  • min (357) doesn’t equal max (1000)
  • guess = random number between 357 (inclusive) and 1000 (exclusive)

Notes on NextGuess() at this point;

  • 1000 cannot be returned as a possibility because max is exclusive

for the sake of argument we will assume guess now equals 926

  • guesstext.text is updated

I indicate that my number is lower and click the relevant button, GuessLower() is called;


GuessLower()

  • min remains unchanged, thus min = 357
  • max = 926 - 1, thus max = 925
  • NextGuess() is called

NextGuess()

  • min (357) doesn’t equal max (925)
  • guess = random number between 357 (inclusive) and 925 (exclusive)

Notes on NextGuess() at this point;

  • 926 could not have been returned as a possibility because max is exclusive
  • 925 can now no longer either be returned for the same reason
  • the game can no longer guess my number

for the sake of argument we will assume guess now equals 622

  • guesstext.text is updated

I indicate that my number is higher and click the relevant button, GuessHigher() is called;


GuessHigher()

  • min = 622+1, thus min = 623
  • max remains unchanged, thus max = 925
  • NextGuess() is called

NextGuess()

  • min (623) doesn’t equal max (925)
  • guess = random number between 623 (inclusive) and 925 (exclusive)

Notes on NextGuess() at this point;

  • 925 cannot be returned as a possibility because max is exclusive
  • the game cannot win and will eventually run out of guesses

for the sake of argument we will assume guess now equals 778

  • guesstext.text is updated

This is just one example of a run through the game using the logic from your code, as you can see, it unfortunately breaks.

Because max will always been exclusive you would probably be better of adding 1 to it at the beginning, e.g. max = 1001, this would give you an actual initial range between 1 and 1000.

Your +1 on the min appears to work and prevents the same number coming up again.

Your -1 on the max within GuessLower() is a problem and also unnecessary, as that number cannot be returned again as max is exclusive.

It would be worth spending some time going through something similar to the above yourself for a variety of combination, for example, higher, higher, higher, higher, higher, then lower, lower, lower, lower, lower - then a mixture. Test to see that you can actually return a number in the correct range.

The cheater test, can this be achieved? Perhaps with more allowed guesses?

The test for whether the number of allowed guesses have been taken could be improved. For example;

  • the variable name maxGuessesAllowed suggests it is a constant, e.g. a number that won’t change but is then decreased through the game play, it may read better if it were called guessesRemaining, it’s a minor detail but something that may help you going forward.
  • within NextGuess() you currently create a new guess, reduce the number of guesses, check if they have run out, if so load another scene - if that was the case then you just create the guess for nothing. Tweaking your if statement logic there may help with this. Equally, you could consider calling a method to test how many guesses are remaining from the GuessHigher() and GuessLower() methods, before running the existing code, that would then map it to the user input more directly and that method would be the one responsible for loading the “Win” scene.

Hope the above helps, sorry its a bit of a textual mess, layout features are limited on the forum but I’ve tried to be fairly consistent and space things out a bit.

2 Likes

Thanks, it’s actually very clear to me :slight_smile:

1 Like

You are more than welcome @Benjamin_Mattei :slight_smile:

Very helpful bit of info @Rob - I’d noticed the difference between the inclusive/exclusive in the API text and the Mono tooltip, but hadn’t twigged that it was down to using the float or int versions of the method.

1 Like

Glad that the above was of use to you @Baiswith :slight_smile:

If you initialize:
min = 0
max = 1001

and the have NextGuess() pick the next random number using
guess = Random.Range(min+1,max)

This will allow for the user to choose 1 or 1000 as their number, as well this will avoid the computer guessing the same number more than once.

Hi,
I believe there is a logic error in the example given in the video for this section which is what caused Benjamin’s confusion.

Here is code similar to that shown in the video:
http://pastebin.com/wwbdAsLX

The guess was changed so it gets its value from Random.Range() now. In that call the instructor adds 1 to max as he passes it in:
guess = Random.Range(min, max + 1);

In the Start method, he no longer adds 1 to the max, so…

Lets assume:
min = 1
max = 1000
and random guess generated is 500

player says their guess is lower, triggering the GuessLower() method. Max gets set to guess.

min = 1
max = 500

we then make our next guess using
guess = Random.Range(min, max + 1);

guess = Random.Range(1, 501); basically

501 is excluded but 500 is not. 500 could be guessed again.

I’m sure there are other solutions but here is how i handled it:
http://pastebin.com/Jb7JdX1D

I think i’ve caught the edge cases going up and down as well as updated NextGuess() to not guess if the limit is hit but please let me know if i’ve made any mistakes.

Privacy & Terms