Simple C++ program to check win in TicTacToe












1












$begingroup$


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










share|improve this question









New contributor




n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$

















    1












    $begingroup$


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










    share|improve this question









    New contributor




    n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.







    $endgroup$















      1












      1








      1


      1



      $begingroup$


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










      share|improve this question









      New contributor




      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.







      $endgroup$




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







      c++ tic-tac-toe






      share|improve this question









      New contributor




      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited 2 hours ago









      200_success

      130k16153417




      130k16153417






      New contributor




      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 2 hours ago









      n3a9n3a9

      62




      62




      New contributor




      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      n3a9 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes


















          0












          $begingroup$

          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;


          A more overarching tension is 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:




          1. 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.


          2. 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 4-by-4 tic tac toe, the following state is unreachable, but not detected by your code:



          x x x x
          o o o o
          x x x x
          o o o o




          share









          $endgroup$













            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            n3a9 is a new contributor. Be nice, and check out our Code of Conduct.










            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214737%2fsimple-c-program-to-check-win-in-tictactoe%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            0












            $begingroup$

            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;


            A more overarching tension is 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:




            1. 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.


            2. 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 4-by-4 tic tac toe, the following state is unreachable, but not detected by your code:



            x x x x
            o o o o
            x x x x
            o o o o




            share









            $endgroup$


















              0












              $begingroup$

              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;


              A more overarching tension is 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:




              1. 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.


              2. 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 4-by-4 tic tac toe, the following state is unreachable, but not detected by your code:



              x x x x
              o o o o
              x x x x
              o o o o




              share









              $endgroup$
















                0












                0








                0





                $begingroup$

                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;


                A more overarching tension is 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:




                1. 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.


                2. 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 4-by-4 tic tac toe, the following state is unreachable, but not detected by your code:



                x x x x
                o o o o
                x x x x
                o o o o




                share









                $endgroup$



                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;


                A more overarching tension is 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:




                1. 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.


                2. 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 4-by-4 tic tac toe, the following state is unreachable, but not detected by your code:



                x x x x
                o o o o
                x x x x
                o o o o





                share











                share


                share










                answered 5 mins ago









                Benjamin KuykendallBenjamin Kuykendall

                31014




                31014






















                    n3a9 is a new contributor. Be nice, and check out our Code of Conduct.










                    draft saved

                    draft discarded


















                    n3a9 is a new contributor. Be nice, and check out our Code of Conduct.













                    n3a9 is a new contributor. Be nice, and check out our Code of Conduct.












                    n3a9 is a new contributor. Be nice, and check out our Code of Conduct.
















                    Thanks for contributing an answer to Code Review Stack Exchange!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    Use MathJax to format equations. MathJax reference.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f214737%2fsimple-c-program-to-check-win-in-tictactoe%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                    is 'sed' thread safe

                    How to make a Squid Proxy server?