# Python AI Guessing Game

I made a Python AI Guessing Game. Here’s the code for those who want to copy and paste.

``````import random

Round1Num = 0
Round2Num = 0
Round3Num = 0
Round4Num = 5

Round = 0

while True:
UserNum = input ("Choose a number from 1 to 10: ")
Round = Round + 1
AINum = 0

if (Round == 1):
if (Round1Num == 0):
if (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round1Num = UserNum
AINum = random.randint(1, 10)
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 2):
if not (Round1Num == 0):
if (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round2Num = UserNum
AINum = Round1Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 3):
if not (Round1Num == 0):
if not (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round3Num = UserNum
AINum = Round2Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 4):
if not (Round1Num == 0):
if not (Round2Num == 0):
if not (Round3Num == 0):
if (Round4Num == 0):
Round4Num = UserNum
AINum = Round3Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 5):
if not (Round1Num == 0):
if not (Round2Num == 0):
if not (Round3Num == 0):
if not (Round4Num == 0):
AINum = Round4Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round > 5):
print ("Game Over!")
input ("Press ENTER to reset the game... ")

Round1Num = 0
Round2Num = 0
Round3Num = 0
Round4Num = 0

Round = 0
``````

I worked on this for at least 3 days and then released the code.

Hi @Slate-Technologies. The #ideas category is for sharing ideas to modify the current Python behavior and related stuff (ideas for changing Python). This post might belong to the #users category.

Thanks for sharing your work. Next time, to allow others to be able to easily view and run your code, place it within a code block, like this:

`````````python
```
``````

This preserves indentation and other formatting, which is critically important in Python. I’ve reconstructed what it looks like you presumably intended, and included it below.

Reconstructed code
``````import random

Round1Num = 0
Round2Num = 0
Round3Num = 0
Round4Num = 5

Round = 0

while True:
UserNum = input ("Choose a number from 1 to 10: ")
Round = Round + 1
AINum = 0

if (Round == 1):
if (Round1Num == 0):
if (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round1Num = UserNum
AINum = random.randint(1, 10)
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 2):
if not (Round1Num == 0):
if (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round2Num = UserNum
AINum = Round1Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 3):
if not (Round1Num == 0):
if not (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
Round3Num = UserNum
AINum = Round2Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 4):
if not (Round1Num == 0):
if not (Round2Num == 0):
if not (Round3Num == 0):
if (Round4Num == 0):
Round4Num = UserNum
AINum = Round3Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round == 5):
if not (Round1Num == 0):
if not (Round2Num == 0):
if not (Round3Num == 0):
if not (Round4Num == 0):
AINum = Round4Num
print ("AI thinks your number is " + str(AINum))

if (str(AINum) == UserNum):
print ("AI guessed your number correctly!")

else:
print ("AI did NOT guess your number correctly!")

elif (Round > 5):
print ("Game Over!")
input ("Press ENTER to reset the game... ")

Round1Num = 0
Round2Num = 0
Round3Num = 0
Round4Num = 0

Round = 0
``````

From a high-level perspective, you can make the game more fun and give it some replay value if the "AI’"s strategy wasn’t so easily predictable. Particularly since the number the AI picked is visible, it quickly becomes to obvious a player within the first few rounds (and certainly within the first 5 round game) that the “AI” is just going to guess whatever they chose last, so all they need to do to “win” is pick a different number each time, which isn’t much fun.

A more sophisticated strategy (say, remembering the player’s choices over multiple rounds, and guessing a number with a probability based on the frequency the player previously entered that number) would greatly improve this. But perhaps better yet, reverse the game and have the computer pick a number and have the player try to guess it, based on hints given by the computer (e.g. “higher”/“lower”, “warmer”/“colder”, etc. You can even write a bot to try to implement the optimal strategy to win the game in the fewest average number of guesses.

In any case, perhaps its intentional to somewhat obfuscate what the AI is doing, so it isn’t quite as easy for a player to beat it just by glancing at the code, but the code can be made far shorter, less complicated and easier to understand, change and improve using some simple but very useful techniques. In general, if you notice your program has a lot of nested layers, lines that aren’t actually necessary (e.g. `if` statements that will always evaluate `True`) or repeating patterns of similar or identical code, its a good sign that you should probably restructure it.

For example, you have nested if statements many layers deep:

``````if (Round == 1):
if (Round1Num == 0):
if (Round2Num == 0):
if (Round3Num == 0):
if (Round4Num == 0):
``````

Since you don’t do anything unless all the levels evaluate true, this can be simplified to:

``````if Round == 1 and Round1Num == 0 and Round2Num == 0 and Round3Num == 0 and Round4Num == 0:
Round1Num = UserNum
``````

It still looks a little redundant, though. Instead of checking each number equals zero, you can use a ternary conditional to check that they all equal 0 (and each other) all at once:

``````if Round == 1 and Round1Num == Round2Num == Round3Num == Round4Num == 0:
Round1Num = UserNum
``````

But wait—if `Round == 1`, we know `Round1Num` and friends must all equal zero, because we set them so right before. Likewise, in the succeeding rounds, the rounds that have passed must not equal zero (so long as the user didn’t enter zero themself, which you should check for at input time). So, for each round, this check doesn’t actually do anything, because it is always true, and thus we can simplify this `if` statement to just

``````if Round == 1:
Round1Num = UserNum
``````

Just in case you do want to check that your program is operating correctly and the various round numbers are indeed what you expect them to be, use an `assert` statement:

``````if Round == 1:
assert Round1Num == Round2Num == Round3Num == Round4Num == 0
``````

This separates your business logic from your correctness checks, and if the check isn’t true, your program immediately halts with an `AssertionError` giving the exact line that failed, rather than simply silently skips the block.

In any case, what’s more, now that you’ve simplified your logic, you might notice that each round’s number is only used once, in the round after the user enters it. As such, you don’t need four different variables, one for each round, but only one—called, say, `user_num_previous`. That’s one fourth the variables to keep track of and reset.

With that further simplification, the code blocks for rounds one through five all look identical (aside the `AINum` guess line being random instead of the previous number). Whenever you see code that looks similar or identical, your first thought should be to avoid this duplication by putting your code inside a loop (or a function). A literal translation of your logic into a nested `while` loop would look like this:

``````user_num_previous = 0
Round = 0
while True:
if Round <= 5:
# Print game over message, etc
Round = 0
Round = Round + 1
if Round == 1:
AINum = random.randint(1, 10)
else:
AINum = user_num_previous
# [...] Existing logic to get and check user's number, and print results
user_num_previous = UserNum

``````

That said, we can simplify this further. Since we’re just iterating to 5 and then repeating every time, we can just nest a `for` loop with a `range()` inside the `while` loop instead of manually incrementing and keeping track of our counter variable `Round`, while the outer `while` loop runs the game again after the user presses `Enter`. This gives us:

``````user_num_previous = 0
while True:
for Round in range(5):
if Round == 1:
AINum = random.randint(1, 10)
else:
AINum = user_num_previous
# [...] Existing logic to get and check user's number, and print results
user_num_previous = UserNum

# Print game over message, etc
``````

Furthermore, if we move resetting the user number inside the outer `while` look, we don’t need to check the `Round` number at all. Instead, we can just check if `user_num_previous` is not `0`—in fact, since `0` evaluates as true, while any non-zero integer evaluates as true, we can just check `if user_num_previous`. On top of that, `result = var1 or var2` sets `result` equal to `var1` if `var1` evaluates true, otherwise it sets it equal to `var2`. We can use this to set `AINum` equal to `user_num_previous` if it isn’t the default `0` (i.e. if the user entered a number in previous round), otherwise `random.randint(1, 10)`. Therefore, we have:

``````while True:
user_num_previous = 0
for __ in range(5):
AINum = user_num_previous or random.randint(1, 10)
# [...] Existing logic to get and check user's number, and print results
user_num_previous = UserNum

# Print game over message, etc
``````

(Note that we don’t need `Round` anymore, so we set the loop variable equal to the dummy `__`)

There are a couple final improvements we can make to shorten this by a few more lines. `AINum = 0` doesn’t do anything, since we reassign it (both in the above and the original) before we ever use it, so it can just be removed. Also, there’s no need to `print()` a “Game Over!” message then add another line for `input()`; just include `Game Over!` in the same string, separated by a line break (`\n`), i.e.:

``````input("Game Over!\nPress ENTER to reset the game... ")
``````

In total, with these changes, we’ve shortened our program from around 100 lines to only a mere 15, including blank lines, while behaving exactly the same as the above. This makes it much simpler to read, understand and modify, which is pretty much always a good thing.

There’s a few other things we should do to our existing lines, that don’t make it any more complex or significantly change the behavior, but do make our code cleaner, more correct and more idiomatic. In particular:

• Instead of converting our guessed `int` to a `str` and comparing it that way, it is more idiomatic and reliable to convert our user’s input string to an integer; then, you’ll automatically get an error if the user enters something other than an integer number, which you can then handle appropriately. I.e.:

``````user_num = int(input("Choose a number from 1 to 10: "))
if user_num == ai_num:
# Etc
``````
• The `print()` function automatically concatenates its arguments into strings with a space betwen them, so instead of doing:

``````print ("AI thinks your number is " + str(AINum))
``````

you can just do

``````print("AI thinks your number is", AINum)
``````

Better yet, you can (and should) use format strings (f-strings) when building strings, as they are shorter, cleaner and faster than other approaches. Just put an `f` in front of the opening quote (`"`), and insert your variables inside braces (`{}`):

``````print (f"AI thinks your number is {AINum}")
``````
• The canonical value used in Python to mean a non-valid or initial value is `None`, which is tested for with `is` rather than `==`, so instead of

``````user_num_previous = 0
if user_num_previous == 0: ...
``````

you should use:

``````user_num_previous = None
if user_num_previous is None: ...
``````
• Finally, some Pythonic style notes. There’s no space between the function name and the opening paren in function calls, i.e.:

``````print("Hello World!")
``````

not

``````print ("Hello World!")
``````

and by standard convention, UpperCamelCase names are for classes, while regular variables use snake_case names, i.e.

``````ai_num = random.randint(1, 10)
``````

not

``````AINum = random.randint(1, 10)
``````

I strongly advise going through the steps here and trying to modify your code yourself following the guidance, which is helpful so you can learn yourself. You should be able to get it down to only 15 lines with the techniques shown, with whitespace included (13 lines without).

However, once you’ve given it your best shot, here is what the result should look like:

Final result
``````import random

while True:
user_num_previous = None
for __ in range(5):
user_num = int(input("Choose a number from 1 to 10: "))
ai_num = user_num_previous or random.randint(1, 10)
print(f"AI thinks your number is {ai_num}")
if user_num == ai_num:
else:
print("AI did NOT guess your number correctly!")
user_num_previous = user_num

input("Game Over!\nPress ENTER to reset the game... ")
``````

Once you’ve done this, here are some things other things you can add further improve the game, and learn more basic Python in the process:

• Have the program keep track of its score versus the user’s and display it at the end of each game
• If the player enters something that is not an integer, use a `try`-`except` block to catch the `ValueError` and give them an opportunity to try again (another nested `while` loop is useful here)
• Similarly, if the number is not in the indicated range (1-10), do the same as the above
• At the beginning, ask the user how many rounds they want to play
• At the end, ask the user if they want to play again or not
1 Like