1

I've created a number game where it asks the user if they want to play again and then the loop continues. My program uses import random but I want to know how I'd generate new random numbers without having to make variables each time. (I'm a beginner and I don't know what solution to use pls help)

My code works for the most part it's just that when the loop restarts the same number from the last playthrough repeats so the player ends up getting the same results. Here's my code:

`

import random
random_number_one = random.randint (0, 100)

username = input("Greetings, what is your name? ")
start_game = input("Welcome to the number game, {0}!  Would you like to play a game? (Type 'Yes/No') ".format(username))

while True:
  if start_game == 'Yes' or start_game == 'yes' :
    print("Let's begin!")
    print(random_number_one)
    user_guess = input("Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: ")
    if user_guess == 'H' or user_guess == 'h' :
        print("You guessed higher. Let's see: ")
        import random
        random_number_two = random.randint (0, 100)
        print(random_number_two)
        if random_number_two > random_number_one :
          print("You are correct! It was higher!")
          play_again_h = input("Would you like to play again? ('Yes'/'No') ")
          if play_again_h == 'Yes' or play_again_h == 'yes' :
            continue
          else:
            break 
        else:
          play_again = input("You were wrong, it was lower. Would you like to play again? ('Yes'/'No')  ")
          if play_again == 'Yes' or play_again == 'yes' :
            continue
          else:
            break
           
    elif user_guess == 'L' or user_guess == 'l':
      print("You guessed lower. Let's see: ")
      print(random_number_two)
      if random_number_two < random_number_one :
        print("You are correct! It was lower!")
        play_again_l = input("Would you like to play again? ('Yes'/'No') ")
        if play_again_l == 'Yes' or play_again_l == 'yes' :
         continue
        else:
         break
      else:
        play_again_2 = input("You were wrong, it was higher. Would you like to play again? ('Yes'/'No')  ")
        if play_again_2 == 'Yes' or play_again_2 == 'yes' :
          continue
        else:
          break
    else:
       print("Invalid response. You Lose.")
       break

  elif start_game == 'No' or start_game == 'no':
    print("Okay, maybe next time.")
    break
  else:
    print("Invalid response. You Lose.")
    break




`

2 Answers2

2

You have to initialize the random number generator with a seed. See here: https://stackoverflow.com/a/22639752/11492317 and also: https://stackoverflow.com/a/27276198/11492317

(You wrote, you're a beginner, so I give you some hints for cut a few things short...)

import random
#import time  #redundant


def get_random(exclude: int = None):
    next_random = exclude
    while next_random is exclude:
        next_random = random.randint(0, 100)
    return next_random


#random.seed(time.time())
random.seed()  # uses system time!
username = input("Greetings, what is your name? ")
start_game = None
while start_game is None:
    start_game = input("Welcome to the number game, {0}!  Would you like to play a game? (Type 'Yes'/'No') ".format(username))
    if start_game.lower() in ("yes", "y", ""):
        print("Let's begin!")
        number_for_guess = get_random()
        running = True
    elif start_game.lower() == "no":
        print("Ok, bye!")
        running = False
    else:
        start_game = None

while running:
    print(number_for_guess)
    next_number = get_random(exclude=number_for_guess)
    user_guess = ""
    while user_guess.lower() not in list("lh"):
        user_guess = input("Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: ")
    if user_guess.lower() == "h":
        print("You guessed higher. Let's see: ")
        print(next_number)
        if next_number > number_for_guess:
            print("You are correct! It was higher!")
        else:
            print("You were wrong, it was lower.", end=" ")
    else:
        print("You guessed lower. Let's see: ")
        print(next_number)
        if next_number < number_for_guess:
            print("You are correct! It was lower!")
        else:
            print("You were wrong, it was higher.", end=" ")
    play_again = "-"
    while play_again.lower() not in ("yes", "y", "", "no"):
        play_again = input("Would you like to play again? ('Yes'/'No') ")
        if play_again.lower() == "no":
            running = False
print("Well played, bye!")
Andreas
  • 159
  • 1
  • 7
  • 1
    You don't need to call seed(). When you omit the call, the current system time will be used. If randomness sources are provided by the operating system, they will be used instead of the system time (see the os.urandom() function for details on availability). The random module creates one instance of Random class (seed call inside __init__) and exports its methods as module-level functions. Check the source: cpython/blob/3.11/Lib/random.py – Adam Dec 27 '22 at 21:02
  • 1
    @Adam, yes, you are right, at least my Ubuntu machine indeed always generates new random numbers, even without calling seed(). In Python, parameter `a` to `seed()` may be omitted and the system time is used instead (https://docs.python.org/3/library/random.html). Class `Random` delegates `seed()` to its super class and ends into system calls. So the behavior is platform dependent and "may" result in repeating numbers. ISO-C99 (7.20.2.1): "If rand is called before any calls to srand have been made, the same sequence shall be generated as when srand is first called with a seed value of 1." – Andreas Dec 27 '22 at 22:16
  • 1
    No, it's not platform dependent. Docs linked by you clearly specifies used algorithm: Almost all module functions depend on the basic function random(), which generates a random float uniformly in the semi-open range [0.0, 1.0). **Python uses the Mersenne Twister as the core generator.** It produces 53-bit precision floats and has a period of 2**19937-1. **The underlying implementation in C is both fast and threadsafe**; You can also check the implementation here: https://github.com/python/cpython/blob/main/Modules/_randommodule.c There is no call to system random function. – Adam Dec 28 '22 at 09:38
  • 1
    @Adam, yes, the algorithm is specified, but not its initialization. This is platform and implementation dependent (as you can see in your linked code). This finally leds us to the original question of this issue. I would think it is better style to keep the call explicit, that way the result is certain. – Andreas Dec 28 '22 at 09:50
  • 1
    How can it be unspecified? From the seed function docs: _the current system time is used. If randomness sources are provided by the operating system, they are used instead of the system time_ There are two possibilities: system time or OS randomness sources - this is only OS specific. The problem with the code from the question is that randint (line 2) is called on the top of the file instead inside the while loop (line 9-10), which results in the same start number (only first) each time game restarts. – Adam Dec 28 '22 at 10:05
  • 1
    It is dependent, since a call to seed with the same start conditions (e.g. time) leads to different results. Probably I really misinterpreted the question and the safely initial randomness may be guaranteed for all Python versions on all machines and in all ecosystems. If I have to guarantee that, I'll better be safe than sorry. – Andreas Dec 28 '22 at 10:38
  • Thank you @Adam your answer was the easiest to understand and it got my code to work! Thanks :D (Also thank you to everyone else that helped!) – kerropileaaf Dec 28 '22 at 15:36
1

You are creating random_number_one only once, when the program starts.

import random
random_number_one = random.randint (0, 100)

username = input("Greetings, what is your name? ")
start_game = input("Welcome to the number game, {0}!  Would you like to play a game? (Type 'Yes/No') ".format(username))

while True:
  if start_game == 'Yes' or start_game == 'yes' :
    print("Let's begin!")
    print(random_number_one)
...

So this number is used all the time:

Greetings, what is your name? a
Welcome to the number game, a!  Would you like to play a game? (Type 'Yes/No') Yes
Let's begin!
8
Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: H
You guessed higher. Let's see: 
86
You are correct! It was higher!
Would you like to play again? ('Yes'/'No') Yes
Let's begin!
8
Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: H
You guessed higher. Let's see: 
82
You are correct! It was higher!
Would you like to play again? ('Yes'/'No') 

You have to create new random number each time the while loop repeats:

import random

username = input("Greetings, what is your name? ")
start_game = input("Welcome to the number game, {0}!  Would you like to play a game? (Type 'Yes/No') ".format(username))

while True:
  if start_game == 'Yes' or start_game == 'yes' :
    print("Let's begin!")
    random_number_one = random.randint (0, 100)  # <-- MOVED HERE
    print(random_number_one)
...

Then it will work as you except:

Greetings, what is your name? a
Welcome to the number game, a!  Would you like to play a game? (Type 'Yes/No') Yes
Let's begin!
96
Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: H
You guessed higher. Let's see: 
7
You were wrong, it was lower. Would you like to play again? ('Yes'/'No')  Yes
Let's begin!
67
Do you think the next number will be higher or lower? Type 'H' for Higher and 'L' for Lower: L
You guessed lower. Let's see: 
7
You are correct! It was lower!
Would you like to play again? ('Yes'/'No') 

Some other small things:

Looks like you missed randint call within the lower option:

...
elif user_guess == 'L' or user_guess == 'l':
  print("You guessed lower. Let's see: ")
  random_number_two = random.randint (0, 100) # missing in your code
  print(random_number_two)
  if random_number_two < random_number_one :
    print("You are correct! It was lower!")
...

You don't need to import random module each time you want to use function from it:

...
if user_guess == 'H' or user_guess == 'h' :
    print("You guessed higher. Let's see: ")
    import random  # line not needed
    random_number_two = random.randint (0, 100)
    print(random_number_two)
...

You may change the line:

if user_guess == 'H' or user_guess == 'h':

into:

if user_guess.lower() == 'h':

or:

if user_guess in ('H', 'h'):

Try to split your code into smaller parts with functions.

Adam
  • 639
  • 9
  • 22