Simple Tic Tac Toe game in C++

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 :).

1 thought on “Simple Tic Tac Toe game in C++”

  1. Pingback: Tic Tac Toe game in C++ - cppdev

Leave a Reply

%d bloggers like this: