Assignment 2
Tic-Tac-Toe (Command Line Game)
In this assignment, you will create a command-line Tic-Tac-Toe game using a structured
modular Python project. The goal is to apply concepts such as classes, generators,
collections, directory management with pathlib, and logging game history into text files.
Project Structure:
Your project folder must be named tic_tac_toe and follow the organization below:
tic_tac_toe/
├── main.py
├── game/
│ ├── __init__.py
│ ├── board.py
│ ├── players.py
│ └── utils.py
└── tools/
├── display.py
└── logger.py
The main game loop must reside inside main.py, while the logic for board handling, players,
and utilities should be inside the game/ folder. All display formatting and message functions,
as well as the logging system, should be placed inside the tools/ folder.
Implementation Requirements
Begin by creating main.py, which will control the overall game flow. Prompt the players to
enter their names (you may assign "Computer" to one player if needed) and display a
welcome message using a function imported from tools/display.py (use alias imports for
clarity).
After the setup, initialize a Board object and two Player objects. The game should then enter
a loop where the following happens:
• Display the current board.
• Prompt the current player for their move.
• Validate and clean the move input.
• Update the board with the move.
• Record the move into a log file using the Logger class from tools/logger.py.
• Check if the current player wins or if the game ends in a draw.
• Alternate turns between the players.
Once a win or draw occurs, the game should end gracefully, announcing the result and
asking the user if they want to restart or exit.
Core Components
In game/board.py, define a Board class that manages the board state. It should provide
methods for displaying the board, placing moves, checking for winners across rows,
columns, diagonals, and checking for a draw when the board is full.
In game/players.py, create a Player class with attributes like name and marker (X or O). This
class should include a method to prompt the player for input (or randomly select a move for
computer players).
In game/utils.py, add functions for validating move positions, cleaning inputs, and creating
generators that yield available moves dynamically.
In tools/display.py, manage all user interface elements, such as printing welcome
messages, displaying the board in a clean format, announcing winners, and prompting
moves. You should avoid direct print statements in main.py except for essential control flow.
In tools/logger.py, create a Logger class responsible for managing the game logs:
• When a game starts, create a folder like tic_tac_toe/game_log/game1/ using pathlib.
• Create a text file log.txt in that folder.
• After every move, log the move with move number, player name, and board position
selected.
• Also, include the board's visual state after each move.
• After the game ends, log the final result (Win or Draw).
Each new game must automatically create a new folder like game2/, game3/, etc., inside
game_log/, without overwriting previous game logs.
Sample Gameplay Example
Please enter Player 1 name: Alice
Please enter Player 2 name: Bob
Welcome, Alice and Bob!
Current Board:
1 | 2 | 3
-----------
4 | 5 | 6
-----------
7 | 8 | 9
Alice's Turn (X):
Enter a position (1-9): 5
...
Bob's Turn (O):
Enter a position (1-9): 1
...
Congratulations, Alice! You win!
Would you like to play again? (yes/no)
A sample log.txt content for this session could look like:
Game 1 Log
Players:
- Alice (X)
- Bob (O)
First move: Alice
Moves:
Move 1: Alice -> Position 5
Move 2: Bob -> Position 1
Move 3: Alice -> Position 9
Board After Move 3:
O | 2 | 3
-----------
4 | X | 6
-----------
7 | 8 | X
Result: Alice wins!
Concepts You Must Apply
• Classes and Objects (Player, Board, Logger)
• Generators for dynamic available moves
• Collections Module (optional: use deque for undo, Counter for simple stats)
• Directory Management with pathlib
• Structured code organization using import module styles
• Logging human-readable move history into structured folders
Important Reminders
• Use pathlib for all directory and file operations, not manual string paths.
• Keep your main.py focused only on controlling game flow — avoid writing direct logic
inside it.
• Create all new folders dynamically using mkdir(parents=True, exist_ok=True) so the
program does not crash if folders already exist.
• After each move, make sure both the console output and the log file are updated.
• Always follow clean modular programming principles: each .py file must have a clear
responsibility.
Submission Instructions
• Upload the full tic_tac_toe/ project folder to a GitHub repository.
• Only working GitHub repositories will be considered for grading.
• Ensure main.py runs correctly without manually executing internal files.
• A basic README.md, in the GitHub repository, explaining how to run the project is
highly recommended.