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 <algorithm>
#include <cmath>
#include <string>
#include <vector>
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 > numberOfX || numberOfX > numberOfO + 1) {
return TicTacToeState::UnreachableState;
}
bool xWon = winDetection(board, 'x');
bool oWon = winDetection(board, 'o');
if (xWon && 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 < kBoardLength; ++i, rightDiagIndex += (kBoardLength + 1),
leftDiagIndex += (kBoardLength - 1)) {
bool row = true, col = true;
int rowIndex = kBoardLength * i, colIndex = i;
for (int j{0}; j < kBoardLength; ++j) {
col &= (board[colIndex] == marker);
row &= (board[rowIndex] == marker);
rowIndex++;
colIndex += kBoardLength;
}
colWin |= col;
rowWin |= row;
rightDiagWin &= board[rightDiagIndex] == marker;
leftDiagWin &= board[leftDiagIndex] == marker;
}
return (rowWin || colWin || rightDiagWin || leftDiagWin);
}
TicTacToe.h
#pragma once
#include <string>
enum TicTacToeState { UnreachableState, Xwins, Owins, NoWinner, InvalidInput };
TicTacToeState CheckTicTacToeBoard(std::string board);
bool winDetection(std::string board, char marker);