A while ago, I’ve posted this article about the implementation of a TicTacToe game in C++. However, the implementation there is quite bad and hard to understand(and also, it seems that there are some bugs).
That’s why I have come up with this article in which I will show you a better implementation of the Tic Tac Toe game. The implementation is much cleaner, there are no bugs and it uses some of the C++ features.
So, without further ado, let’s get into it.
Software architecture
The software architecture is very similar from the previous one. We have the Game class, the Board class, a main.cpp but this time, we added a new header file which is called Misc.h.


This is the whole project. The Misc.h file contains only some definitions of a WinMatrix, the Mark enum and overload for the ostream operator (operator<<) for the Mark enum, for convenience.
Implementation
I’ll say a few words for the actual implementation, so I can explain what I’m doing and why I’m doing it like this. I will only provide information on the “important” stuff here since I don’t think I need to add the full code in the article.
First for the Misc.h:
constexpr std::array<std::array<int, 3>, 8> WinMatrix{{
// horizontal
{0, 1, 2},
{3, 4, 5},
{6, 7, 8},
// vertical
{0, 3, 6},
{1, 4, 7},
{2, 5, 8},
// diagonal
{0, 4, 8},
{2, 4, 6}
}};
The WinMatrix represents all the possible combinations in order for a player to win the Tic Tac Toe game. These are the indexes on the board that represent a win. For e.g. if there is an X mark on positions 0, 1 and 2 then the player with mark X wins the game. You can win Tic Tac Toe, if you have the same mark on a horizontal line, on a vertical line, or on one of the diagonals.
Another example, if there is an O mark on positions 0, 4 and 8 then it means that the player with mark O wins the game. If none of these conditions apply, then it’s a tie.
Now for the Board class:
void Board::draw() const
{
std::stringstream stream;
stream << "- - -\n";
for (auto iter = 1; iter <= MaxMarks; iter++)
{
stream << "| ";
// if there's no Mark yet, show the index of the box
if (board_[iter-1] == Mark::None)
stream << iter;
else
stream << board_[iter-1];
// if it's index 3, 6 or 9, just end the row
if (iter % 3 == 0)
{
stream << "|\n";
stream << "- - -\n";
}
}
// show the board to the screen
std::cout << stream.str();
}
The draw function from the Board class is used to show the user, the state of the board. I also added here some comments, to understand better some of the logic.
The Game class, implements the logic of the actual Tic Tac Toe game also using the Board for data on the state of the game.
void Game::update()
{
auto board = board_.get();
// check against the WinMatrix
for(const auto win : WinMatrix)
{
int xMark = 0, oMark = 0;
for (const auto pos : win)
{
if (board[pos] == Mark::None)
break;
// count the marks on the board
// at positions/indexes from the WinMatrix
board[pos] == Mark::X ? ++xMark : ++oMark;
}
// if any combination taken from the WinMatrix
// is present on the board, then we have a winner
if (xMark == 3) { currentMark_ = Mark::None; winnerMark_ = Mark::X; return; }
if (oMark == 3) { currentMark_ = Mark::None; winnerMark_ = Mark::O; return; }
}
// if there is no space on the board anymore
// there is no winner, it's a tie
if (std::all_of(board.begin(), board.end(),
[](const auto mark){ return mark != Mark::None; }))
{
currentMark_ = Mark::None;
return;
}
// change the turn to the next player
currentMark_ == Mark::X ? currentMark_ = Mark::O : currentMark_ = Mark::X;
}
The update function in the Game class takes care of the state of the game and checks for a winner. Basically, it checks if any of the WinMatrix conditions are met, if there’s any move to be made(or it’s a tie) and it swaps between player turns.
There are also comments in this class for more information.
And finally, in the main.cpp, we just create and instance of the game and run it’s main loop.
int main()
{
// create the game
// and start the main game loop
tictactoe::Game game;
game.run();
}
And this is it for the implementation(at least the main part of it).
Full project
You can find the entire project on my github here and you can have some fun with it. If there is any feedback from you all, would love to see it in the comments below.
In conclusion
This is a much cleaner version of the implementation provided here and I wanted to share it with all of you that are just at the start of your programming career.
Hope you learned something from it :).
Pingback: Tic Tac Toe game in C++ - cppdev