Simple C++ program to check win in TicTacToe
$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);
c++ tic-tac-toe
New contributor
$endgroup$
add a comment |
$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);
c++ tic-tac-toe
New contributor
$endgroup$
add a comment |
$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);
c++ tic-tac-toe
New contributor
$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
c++ tic-tac-toe
New contributor
New contributor
edited 2 hours ago
200_success
130k16153417
130k16153417
New contributor
asked 2 hours ago
n3a9n3a9
62
62
New contributor
New contributor
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
$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:
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 anUnreachableState
. 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
$endgroup$
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
$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:
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 anUnreachableState
. 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
$endgroup$
add a comment |
$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:
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 anUnreachableState
. 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
$endgroup$
add a comment |
$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:
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 anUnreachableState
. 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
$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:
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 anUnreachableState
. 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
answered 5 mins ago
Benjamin KuykendallBenjamin Kuykendall
31014
31014
add a comment |
add a comment |
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.
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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