As part of my journey to learn Python (for real this time), I’m finally getting down to working on projects. Everyone always comments on the importance of projects to solidify all that theoretical knowledge we learned.
So I listened.
To get started, no need for anything too drastically complicated. Something fun and that shows practical applications of primitive datatypes like dictionaries and lists are a good first experience.
I got started with this simple Tic-Tac-Toe coding project, with the help of this awesome tutorial.
The basic ideas behind it are:
- We create a board using a dictionary.
- Each square is accessed through the keyboard’s number pad.
- We create a function to print the updated board at any point.
- Using a for loop, we ask two players (X and O) to take alternating turns until either one of them wins or there is a tie.
- Finally, we ask the players if they want to play again, in which case we wipe the board and the game begins once more.
As you can see in the tutorial, the author explains everything super clearly. No need to repeat everything he laid down before. Instead, I wanted to share some of the changes I made, and why I made them.
To begin with, here is the original code in its entirety, as coded by James Shah:
Pretty awesome, huh?
I thought there was a margin for improvement in a couple of things, though — hopefully, it makes sense to you too. Let’s get to it!
Wrong inputs counted for total turn count
Notice that, if one of the players tries to mark a square that already has something, he’ll be asked to try again. Good enough. But that wrong turn will still increase the count.
Let’s imagine that each player types a wrong input in one match. Then, the game would abruptly end before all squares were completed. Not very nice.
To solve that, I created a while loop. Instead of keeping track of the number of turns using for i in range(10)
, I used the already existing variable count to keep tabs on the number of total rounds.
This way, if the player inputs an invalid square, it won’t count as a turn.
The first lines of the function game()
will then look like this:
Exit option
Maybe the player doesn’t really understand how to play Tic-Tac-Toe and is getting frustrated. Then, it’s nice to give him or her the option to exit mid-game.
To do that, I needed to create an extra if-else layer, in order to avoid any issues with the program trying to check for an “exit” dictionary key.
The first lines of game()
now look like this:
Invalid input
If the users type anything other than number’s, the program encounters an error. We can avoid that and make the experience a bit nicer, by informing the users about the issue and giving them the chance to try again. Or, if they prefer, the option to exit the game, as seen previously.
This is a simple fix: we just need to add an elif statement after checking for an exit request.
Adjust the number of rounds
In the original code from the tutorial, I encountered an issue in the case of ties. After 9 turns had been played and nobody won, the program lets the users know it was a tie. But then, it goes on to ask player O to choose a key.
That was a simple issue of the range being a bit high. Adjusting it to range(9)
solves it.
Similarly, in case you made the changes discussed above and now have a while loop (instead of the for loop), pay attention to the condition. It should be strictly smaller than 9 — not smaller or equal.
In other words, it should be while count < 9
Avoiding repetition
Lastly, I found that the code to check the winning condition was a bit long and required too much repetition. So instead I use one single if statement.
I’ll be honest here and say that I don’t know if that goes against best practices, or if experienced coders would prefer the original method shown in the tutorial. If you know, I’d love to hear your thoughts!
Here is what it looks like for me:
That’s it!
Below you can see how the entire code looks like, along with a few comments explaining those changes.
I’m sure there are way more elegant ways to write this project. If you have any suggestions or ideas, please drop a comment so we can improve it together 🙂