1

So I've created this number guessing game. And it works fine up until the play_again function is needed. I have looked around trying to figure out how I can restart the program. I have tested this in my PyCharm IDE and it just exits with exit code 0. What is the best way to actually restart the program so it generates a new number in my rand variable?

import os
from random import random

import sys


class Game:
    """
    rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounding to the nearest integer
    guessed is declared as false in order to keep the while loop running until the number is guessed
    """
    rand = round(random() * 100, 0)
    guessed = False
    print("Guess the number [0 - 100]")

    # This function handles the number guessing and number formatting
    def run_game(self):

        # Assigns the 'answer' variable by grabbing user input from console
        answer = input()

        # Checks if the input from the console is a number, and if not, asks the user to enter a valid number
        if answer.isdigit():

            n = int(answer)

            # Checks the input given against the random number generated
            while not self.guessed:
                if n > int(self.rand):
                    print("Number is less than " + str(n))
                    self.run_game()
                elif n < int(self.rand):
                    print("Number is greater than " + str(n))
                    self.run_game()
                else:
                    print("You have guessed the correct number!")
                    self.guessed = True
                    self.play_again()
        else:
            print("Please enter a number")
            self.run_game()
            return

    def play_again(self):

        reply = input("Play again? (y/n)")

        if reply.lower() == "y":
            python = sys.executable
            os.execl(python, python, *sys.argv)
        elif reply.lower() == "n":
            print("Thanks for playing!")
        else:
            self.play_again()


if __name__ == "__main__":
    game = Game()
    game.run_game()
0

2 Answers 2

3

Solution

There are several errors in your code. The most common being is that you are using recursion as a looping construct. Don't do this. It's a great way to introduce bugs, not to mention if your "loop" runs to many times, you'll hit the recursion limit. Just use a while loop:

def run_game(self):
    while True:
        answer = input()
        if answer.isdigit():
            n = int(answer)
            if n > int(self.rand):
                print("Number is less than " + str(n))
            elif n < int(self.rand):
                print("Number is greater than " + str(n))
            else:
                print("You have guessed the correct number!")
                reply = self.play_again()
                if reply is False:
                    break
        else:
            print("Please enter a number")

Note a modified player to return a boolean indicating whether the user wants to play again. As I said above, you made the same mistake in player. Don't use a recursion as a loop, use an explicit while loop:

def play_again(self):
    while True:
        reply = input("Play again? (y/n)")
        if reply.lower() == "y":
            return True
        elif reply.lower() == "n":
            return False
        else:
            print("Enter 'y' or 'n'")

Improvements

On an unrelated side note, I see no reason to use a class here. There's no global state you need to keep track of or any data you're trying to encapsulate. This can be implemented much cleaner using just functions:

def run_game():
    rand = randint(1, 100)
    while True:
        answer = input()
        if answer.isdigit():
            n = int(answer)
            if n > rand:
                print("Number is less than " + str(n))
            elif n < rand:
                print("Number is greater than " + str(n))
            else:
                print("You have guessed the correct number!")
                if not play_again():
                    break
        else:
            print("Please enter a number")


def play_again():
    while True:
        reply = input("Play again? (y/n)")
        if reply.lower() == "y":
            return True
        elif reply.lower() == "n":
            return False
        else:
            print("Enter 'y' or 'n'")


if __name__ == "__main__":
    print("Guess the number [0 - 100]")
    run_game()

Here are some other improvements I made:

  • I used ranint() instead of randomm(). Since you have a specific range, just use randint().
  • I removed the calls to int() as those are no longer needed.
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot! If you wish to see the code that works for me you can see it here: github.com/Waldxn/NumberGuess/blob/master/script.py
Nice, @Waldxn. that looks good. But as I mentioned in my answer, I believe your code could be implemented more succinctly using just plain functions :-)
I will actually keep that in mind. I've got to go for the night, but will definitely change it to just Functions. I didn't state this, but I am learning Python AFTER learning Java over the past year, hence the classes :)
2

That's a pretty bad way to restart the game, you should avoid running exec when possible.

One other way to do it would be to return False or True based on user input, and keep running the game while the function returns True:

import os
from random import random

import sys


class Game:
    """
    rand is declared by grabbing a number between 0 and 1, multiplying it by 100, and rounding to the nearest integer
    guessed is declared as false in order to keep the while loop running until the number is guessed
    """
    rand = round(random() * 100, 0)
    guessed = False
    print("Guess the number [0 - 100]")

    # This function handles the number guessing and number formatting
    def run_game(self):

        # Assigns the 'answer' variable by grabbing user input from console
        answer = input()

        # Checks if the input from the console is a number, and if not, asks the user to enter a valid number
        if answer.isdigit():

            n = int(answer)

            # Checks the input given against the random number generated
            while not self.guessed:
                if n > int(self.rand):
                    print("Number is less than " + str(n))
                    self.run_game()
                elif n < int(self.rand):
                    print("Number is greater than " + str(n))
                    self.run_game()
                else:
                    print("You have guessed the correct number!")
                    self.guessed = True
                    return self.play_again()  # Here we run play_again and return its result
        else:
            print("Please enter a number")
            self.run_game()
            return

    def play_again(self):

        reply = input("Play again? (y/n)")

        if reply.lower() == "y":
            return False  # Game isn't finished
        elif reply.lower() == "n":
            print("Thanks for playing!")
            return False  # Game is finished
        else:
            return self.play_again()


if __name__ == "__main__":
    game = Game()
    game_is_finished = False
    while not game_is_finished:
        game_is_finished = game.run_game()

1 Comment

Sorry but this didn't work. Thanks for your time though.

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.