An Advanced Tic-Tac-Toe variant implemented in C++ that introduces a strategic twist: each player can have up to three symbols on the board at once. When placing a fourth symbol, the oldest one is evicted in FIFO order—unless that fourth placement wins the game immediately.
Tic-Tac-Flow/
├── include/ # Header files (.h)
│ ├── Board.h # Board class declaration
│ ├── Player.h # Player class declaration
│ └── Game.h # Game class declaration
├── src/ # Source files (.cpp)
│ ├── main.cpp # Entry point, invokes Game
│ ├── Board.cpp # Board class definitions
│ ├── Player.cpp # Player class definitions
│ └── Game.cpp # Game class definitions
├── obj/ # Build artifacts (ignored by Git)
├── bin/ # Executable output (ignored by Git)
├── Makefile # Build automation script
├── .gitignore # Specifies files to ignore in Git
├── LICENSE # (Optional) License information
└── README.md # Project overview and instructions
- C++17 (or later) compiler (e.g. g++ from MinGW-W64, MSYS2, or Linux toolchains)
- make (or
mingw32-makeon Windows)
-
Clone the repository:
git clone <your-repo-url> cd Tic-Tac-Flow
-
Build the executable:
-
On Windows (MinGW):
mingw32-make
-
On Linux/macOS:
make
-
-
Run the game:
./bin/TicTacFlow # or bin\TicTacFlow.exe on Windows
- Two players: X (starts first) vs. O.
- Standard 3×3 grid.
- Each player may have at most 3 symbols on the board concurrently.
- Placing a 4th symbol removes the oldest placement (FIFO), unless that 4th symbol creates a winning line—in which case the game ends immediately.
- Win by getting three in a row, column, or diagonal.
Location: include/Player.h, src/Player.cpp
Responsible for tracking a player’s identity, symbol, and move queue.
-
Members:
std::string Name— Player’s display name.int Id— Auto-assigned ID (1 for X, 2 for O).char Symbol— Player symbol ('X' or 'O').std::queue<std::pair<int,int>> Moves— Queue storing up to four moves for FIFO eviction.
-
Methods:
Player(std::string name)— Constructor: sets name, assignsId, andSymbol.addMove(int r, int c)— Enqueues a new move position.hasMoreThanThreeMoves() const— Returnstruewhen a fourth move awaits eviction.getOldestMove() const— Retrieves the oldest move (front of queue).removeOldestMove()— Pops the oldest move after eviction.- Accessors:
getName(),getSymbol(),getMoves().
Location: include/Board.h, src/Board.cpp
Encapsulates the 3×3 grid, symbol placement, and win detection logic.
-
Members:
char Grid[3][3]— 2D array storing' ','X', or'O'.
-
Methods:
Board()— Initializes all cells to' '.display()— Prints the current grid tostdout.isCellEmpty(int r, int c)— Checks if a given cell is vacant.placeSymbol(int r, int c, char symbol)— Marks a cell.removeSymbol(int r, int c)— Clears a cell (used for FIFO eviction).checkWin(char symbol) const— Returnstrueifsymbolhas three in a row (rows, columns, diagonals).
Location: include/Game.h, src/Game.cpp
Orchestrates the game loop, user I/O, turn switching, and win announcements.
-
Members:
Player PlayerX— First player (X).Player PlayerY— Second player (O).Board GameBoard— Game grid.bool isXTurn— Tracks whose turn it is.bool GameOver— Indicates when a win ends the loop.
-
Methods:
static printGameIntro()— Prints welcome message and rules.play()— Main loop: prompts moves, processes logic, and switches turns untilGameOver.processMove(Player &p)— Reads/validates input, places symbol, checks for win, handles eviction, and displays board.announceWinner(const Player &p) const— Prints the final winner message.switchTurn()— TogglesisXTurn.
-
Directories:
obj/for compiled.ofilesbin/for the final executable
-
Flags:
-Wall -Wextra -std=c++17 -Iincludefor compiling- Linker:
-Wl,-subsystem,console -Wl,-entry,mainCRTStartupto ensure console entry point
-
Targets:
all(default): builds the executableclean: removesobj/andbin/
- Current: Invalid inputs or states often call
std::terminate(), risking abrupt exits. - Planned: Add exceptions or input loops to validate bounds (
0≤r,c≤2) and data type correctness before placing moves.
- Draw/Stalemate Detection: Introduce move-count limits or cycle detection for perpetual no-win scenarios.
- Exception Safety: Replace
std::terminate()with exception throwing or error codes in invalid states.
- Configurable Board Size: Generalize to N×N boards with M-in-a-row win conditions.
- AI Opponent: Implement minimax or heuristic-based single-player mode.
- Graphical/UI Frontend: Create a GUI version using SDL, Qt, or a web frontend.
Enjoy playing Tic-Tac-Flow!