Simple C++ program to check win in TicTacToe Given a string of size 9 that represents a tic tac toe board, determine if X or O has won, or if the board is in an invalid state. Any other character aside from x, X, o, O represents an empty spot on the board.

Input: 012345678

Board:

0 1 2
3 4 5
6 7 8


TicTacToe.cpp

#include "tictactoe.h"
#include &lt;algorithm&gt;
#include &lt;cmath&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

using std::string;
using std::vector;

const int kBoardSize = 9;
const int kBoardLength = std::sqrt(kBoardSize);

TicTacToeState CheckTicTacToeBoard(std::string board) {
  if (board.size() != kBoardSize) {
    return TicTacToeState::InvalidInput;
  }

  std::transform(board.begin(), board.end(), board.begin(), ::tolower);
  size_t numberOfO = std::count(board.begin(), board.end(), 'o');
  size_t numberOfX = std::count(board.begin(), board.end(), 'x');

  if (numberOfO &gt; numberOfX || numberOfX &gt; numberOfO + 1) {
    return TicTacToeState::UnreachableState;
  }

  bool xWon = winDetection(board, 'x');
  bool oWon = winDetection(board, 'o');

  if (xWon &amp;&amp; oWon) {
    return TicTacToeState::UnreachableState;
  } else if (xWon) {
    return TicTacToeState::Xwins;
  } else if (oWon) {
    return TicTacToeState::Owins;
  }
  return TicTacToeState::NoWinner;
}

bool winDetection(string board, char marker) {
  bool rowWin = false, colWin = false, rightDiagWin = true, leftDiagWin = true;

  for (int i{0}, rightDiagIndex{0}, leftDiagIndex{kBoardLength - 1};
       i &lt; kBoardLength; ++i, rightDiagIndex += (kBoardLength + 1),
                         leftDiagIndex += (kBoardLength - 1)) {
    bool row = true, col = true;

    int rowIndex = kBoardLength * i, colIndex = i;
    for (int j{0}; j &lt; kBoardLength; ++j) {
      col &amp;= (board[colIndex] == marker);
      row &amp;= (board[rowIndex] == marker);

      rowIndex++;
      colIndex += kBoardLength;
    }

    colWin |= col;
    rowWin |= row;

    rightDiagWin &amp;= board[rightDiagIndex] == marker;
    leftDiagWin &amp;= board[leftDiagIndex] == marker;
  }

  return (rowWin || colWin || rightDiagWin || leftDiagWin);
}



TicTacToe.h

#pragma once

#include &lt;string&gt;

enum TicTacToeState { UnreachableState, Xwins, Owins, NoWinner, InvalidInput };

TicTacToeState CheckTicTacToeBoard(std::string board);

bool winDetection(std::string board, char marker);
Computing a square-root is unnecessary; further, it only works when kBoardSize is a perfect square. Prefer

const int kBoardLength = 3;
const int kBoardSize = kBoardLength * kBoardLength;

Your test for unreachability is not complete. You verify that O has made no more moves than X, but you really need to check that the winner made the last move. If X won, then should have numberOfX = numberOfO + 1; if O won then should have numberOfO = numberOfX. It should be clear how to add these checks to your CheckTicTacToeBoard method.
A more overarching tension in this code is: should the board size really be a constant? The code is written so abstractly as to support any board size. But then the board size is fixed to a constant. I would choose one of the following directions to proceed in:


Commit to a board size of 9. In this case, I would recommend hard-coding the win conditions in winDetection. There are only 8 ways to win, so the resulting code would be a lot cleaner.
Allow arbitrary board sizes. In this case, you should accept a boardLength argument. Further, you will have to refine the notion of an UnreachableState. For example, in 5-by-5 tic tac toe, the following state is unreachable, your code would return Xwins:

x x x x x
o . o . o
x x x x x
o . o . o
o o x o o