This is my new version of my Tic Tac Toe game written in C++. I tried to follow community advice by separating I/O from the game logic and view (MCV). The code works great, and I am looking to see if I followed the model control view design pattern correctly.TicTacToe.h#ifndef TICTACTOE#define TICTACTOE#include<string>class TicTacToe{    std::string boardInfo;    char player1;    char player2;public:    TicTacToe();    ~TicTacToe();    void markBoard(const size_t &, const char&);    void setPlayerMark(const char &);    char getMark(const int &);    char checkWin(const int&);    char positionValue(const size_t&);};#endif TicTacToe.cpp#include TicTacToe.hTicTacToe::TicTacToe(){    boardInfo = 123456789;    player1 = 'X';    player2 = 'O';}TicTacToe::~TicTacToe(){}void TicTacToe::markBoard(const size_t & boardIndex, const char &playerMark) {    boardInfo[boardIndex - 1] = playerMark;}// 'X' or 'O' = game win, 'C' = catsgame, and 'N' = no winchar TicTacToe::checkWin(const int &turnCount) {    //winning solutions involving middle square    for (size_t i = 0, k = 8; i <= 3 && k >= 5; i++, k--) {        if (boardInfo[4] == boardInfo[i] && boardInfo[i] == boardInfo[k]) {            return boardInfo[4];        }    }    //remaining winning solutions    if (boardInfo[2] == boardInfo[1] && boardInfo[1] == boardInfo[0]) { return boardInfo[2]; }    if (boardInfo[2] == boardInfo[5] && boardInfo[5] == boardInfo[8]) { return boardInfo[2]; }    if (boardInfo[6] == boardInfo[3] && boardInfo[3] == boardInfo[1]) { return boardInfo[6]; }    if (boardInfo[6] == boardInfo[7] && boardInfo[7] == boardInfo[8]) { return boardInfo[6]; }    //catsgame    int totalTurns = 9; //total possible turns    if (turnCount > totalTurns) { return 'C'; }    return 'N';}void TicTacToe::setPlayerMark(const char &mark) {    player1 = mark;    //the other player will always receives opposite mark    switch (mark) {    case 'X': player2 = 'O';        break;    case 'x': player2 = 'o';        break;    case 'O': player2 = 'X';        break;    case 'o': player2 = 'x';        break;    }}char TicTacToe::positionValue(const size_t &index) {    return boardInfo[index];}char TicTacToe::getMark(const int &player) {    if (player == 1) {        return player1;    }    if (player == 2) {        return player2;    }    return 'N';}Game.h#ifndef GAME#define GAME#include <iostream>#include <limits>#include TicTacToe.hclass Game{    TicTacToe board1;public:    Game();    ~Game();    void drawBoard();    void turn(int &, TicTacToe &);    void setMarks();    void run();};#endifGame.cpp#include Game.hGame::Game(){}Game::~Game(){}void Game::drawBoard() {    std::cout <<   << board1.positionValue(0) <<  | <<   << board1.positionValue(1) <<  | <<   << board1.positionValue(2) << \n;    std::cout << ___|___|___ \n;    std::cout <<   << board1.positionValue(3) <<  | <<   << board1.positionValue(4) <<  | <<   << board1.positionValue(5) << \n;    std::cout << ___|___|___ \n;    std::cout <<   << board1.positionValue(6) <<  | <<   << board1.positionValue(7) <<  | <<   << board1.positionValue(8) << \n;    std::cout <<    |   |   ;}void Game::turn(int &turnCount, TicTacToe &board1) {    char mark;    size_t spaceChoice;    if (turnCount % 2) {        mark = board1.getMark(1); //player 1's mark        turnCount++;        std::cout << \nPlayer 1's turn\nChoose space to mark: ;    }    else {        mark = board1.getMark(2); //player 2's mark        turnCount++;        std::cout << \nPlayer 2's turn\nChoose space to mark: ;    }    bool inputpass = false; //used to check if the input is passed, failed, or not marked    while (!inputpass) {        //tests input type        if (std::cin >> spaceChoice) {            //checks domain            if (spaceChoice > 0 && spaceChoice < 10) {                char check = board1.positionValue(spaceChoice-1); //used to check if space has been marked                if (check != 'X' && check != 'x' && check != 'O' && check != 'o') {                    board1.markBoard(spaceChoice, mark);                    inputpass = true;                }                else {                    std::cout << \nSPACE ALREADY MARKED\nTry again: ;                }            }            else {                std::cout << \nINNCORRECT SPACE\nTry agian: ;            }        }        //if the input type fails        else {            std::cout << \nINCORRECT INPUT TYPE\nTry agian:;            std::cin.clear(); //clears input fail state            std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');        }    }}void Game::setMarks() {    char tempMark;    bool inputPass = false;    while (!inputPass) {        if (std::cin >> tempMark) {            if (tempMark == 'X' || tempMark == 'x' || tempMark == 'O' || tempMark == 'o') {                board1.setPlayerMark(tempMark);                inputPass = true;            }            else {            std::cout << MARK MUST BE X OR O\nTry again: ;            }        }        else {            std::cout << INCCORECT INPUT TYPE\nTry again: ;        }    } }void Game::run() {    std::cout << Enter wether player 1 is 'X' or 'O': ;    setMarks();    char gameWin = 'N';     int turnCount = 1;    drawBoard();    while (gameWin != 'X' && gameWin != 'x' && gameWin != 'O' && gameWin != 'o' && gameWin != 'C') {        turn(turnCount, board1);        gameWin = board1.checkWin(turnCount);        drawBoard();    }    if (gameWin != 'C') {        std::cout << ((board1.getMark(1) == gameWin) ? \nThe winner is: Player 1! : \nThe winner is: Player 2!);    }    else        std::cout << \nCATS GAME!;}main.cpp#include <iostream>#include Game.hvoid pause();int main() {    Game game1;    game1.run();    pause();} void pause() {    char end;    std::cout << \nPress any key followed by ENTER to continue...;    std::cin >> end;}
Tic Tac Toe C++ MVC design
c++;object oriented;mvc;tic tac toe
Good that you got around the #pragma once problem.My IDE generates #ifndef TICTACTOE_H_#define TICTACTOE_H_#endif /* TICTACTOE_H_ */I thing that's a little more unique, possibly better.MAGIC NUMBERS:You still have a lot of magic numbers in your code:    for (size_t i = 0, k = 8; i <= 3 && k >= 5; i++, k--) {        if (boardInfo[4] == boardInfo[i] && boardInfo[i] == boardInfo[k]) {            return boardInfo[4];        }    }    //remaining winning solutions    if (boardInfo[2] == boardInfo[1] && boardInfo[1] == boardInfo[0]) {        return boardInfo[2];    }    if (boardInfo[2] == boardInfo[5] && boardInfo[5] == boardInfo[8]) {        return boardInfo[2];    }    if (boardInfo[6] == boardInfo[3] && boardInfo[3] == boardInfo[1]) {        return boardInfo[6];    }    if (boardInfo[6] == boardInfo[7] && boardInfo[7] == boardInfo[8]) {        return boardInfo[6];    }    //catsgame    int totalTurns = 9; //total possible turns    if (turnCount > totalTurns) { return 'C'; }In the public section of TicTacToe.h you should defineconst int MAX_TURNS  = 9;There are coding standards that apply to symbolic constant names, this link is one, but there are others. It doesn't do as much good where it is defined in checkWin().Code which may lead to possible problems:Your switch statement doesn't have a default case, generally switch statements should contain a default case which handles all cases not specified and can be used to provide error messages.    switch (mark) {    case 'X': player2 = 'O';        break;    case 'x': player2 = 'o';        break;    case 'O': player2 = 'X';        break;    case 'o': player2 = 'x';        break;    default:        std::cerr << Please provide the correct input << std::endl;        break;    }Variable Names:What are i and k in the following code?    for (size_t i = 0, k = 8; i <= 3 && k >= 5; i++, k--) {        if (boardInfo[4] == boardInfo[i] && boardInfo[i] == boardInfo[k]) {            return boardInfo[4];        }    }Fix the Typos:Game.cpp:  wether => whether, agian => again.Model View Controller:Generally a MVC design pattern has a set of classes for the Model, a set of classes for the view and a set of classes for the control. The classes in this implement contain elements of all 3.What you really need to do is separate the logic of the game from the display mechanism. An example, Game contains both game control and display. The reason for this is that it allows your model classes to be reused on different operating systems using different display mechanisms (console text as you are now or graphics).Amoung other things your controller should contain the code whether or not to play another game (remove pause() from Main.cpp, add playAnotherGame() to a controller class.The controller class should call both the model and view classes. The view classes should only handle formatting the output, the model should have all the internal game functionality.Let the Compiler do more work for you:In Game.h you have Game(); and ~Game(); and in Game.cpp you haveGame::Game(){}Game::~Game(){}Since you are not doing anything special in either the constructor or distructoryou can use the default constructor and distructor if you are using C++11 or C++14.This allows you to declare/define your constructors only in your header file, and let the C++ compiler generate the proper constructors and destructors. The less code you have to write, the less error prone it is.In C++11 or C++14 class Game{    TicTacToe board1;public:    Game() = default;    ~Game() = default;};Functions in Main.cpp:If you reverse the order of pause() and main() in Main.cpp you don't need the function prototype of void pause(); prior to main(). Having main() as the last function in the file is fairly common for this reason.In the past on certain operating systems, pause(); has been a system call. I would avoid it's use, although the system call did return int so the signature is different. It also isn't the most descriptive name you could give this function.