Skip to main content
edited tags
Link
200_success
  • 144.2k
  • 22
  • 188
  • 473
Source Link
n3a9
  • 41
  • 1
  • 4

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 <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);