Model the Game
00:12 By modeling the domain of the game with a mutable object, you’ll end up with modular and composable code that’s easier to test, maintain, debug, and reason about, amongst several other advantages.
00:35 Many modern code editors will give you the option to create a virtual environment for your project automatically. So if you want to, you can do that, but if your editor doesn’t, then you can make the virtual environment manually.
Next, scaffold the basic structure of files and folders in your new project, remembering to use underscores instead of dashes for the Python package in the
src/ subfolder. This skeleton of folders and files is available in the course materials if you don’t want to create everything manually. All of the files in the tree seen on-screen should be empty at this point. You’ll successively fill them with content and add more files as you go through the course.
You specify the required build tools, which Python will download and install if necessary, along with some metadata for the project. Adding the
pyproject.toml file to the library lets you build and install it as a Python package into the active virtual environment.
Even though there’s no Python code in the library yet, installing it now with the
--editable flag will let the Python interpreter import the functions and classes that you’ll be adding shortly straight from your project.
03:00 Otherwise, every time you made a change in your source code and wanted to test it, you’d have to remember to build and install the library into the virtual environment again. Now you have a general structure for the project, you can start implementing some code.
03:16 By the end of this step, you’ll have all the essential pieces of a tic-tac-toe game in place, including the game logic and state validation, so you’ll be ready to combine them in an abstract game engine at the start of the game.
03:29 Each tic-tac-toe player gets assigned one of two symbols, either cross (X) or naught (O), which they use to mark locations on the game board. Since there are only two symbols belonging to a fixed set of discrete values, you can define them with an enumerated type or enum.
Using enums is preferable over constants due to their enhanced type safety, common namespace, and programmatic access to their members. Create a new Python module called
models in the
The two singleton instances of the
Mark class, enum members
NAUGHT, represent the player’s symbols. They’re defined as an extension of
StrEnum, which was added to the standard library in Python 3.11.
StrEnum are strings, which means that you can use them almost anywhere that a regular string is expected. Once you assign a given mark to the first player, the second player must be assigned the only remaining and unassigned mark.
05:10 The body of the property is a single line of code that uses a conditional expression to determine the correct mark. The quotation marks around the return type in the property signature are mandatory to make a forward declaration and avoid an error due to an unresolved name.
Adding the special
__future__ import, which must appear at the beginning of the file, enables lazy evaluation of type hints. You’ll use this pattern later to avoid the circular reference problem when importing cross-referencing modules.
07:02 You now have a way to represent the available markings that players will leave on the board to advance the game. In the next section of the course, you’ll implement an abstract game board with well-defined locations for those markings.
Become a Member to join the conversation.