I think I see one bug. You don't check that the user's input for slotChoiceslotChoice
is valid. If the input is outside the range 0..8, the program overruns the array.
I don't like the global GRID_SIZE
GRID_SIZE
constant. I would make a structstruct
(or a classclass
) that holds gameGridgameGrid
and the size. Then pass a reference to the structstruct
(a constconst
reference when possible) to the functions that currently have a gameGridgameGrid
parameter.Later, if you want to make the program more object-oriented, you can make most of the current functions into member functions of the class. Since you are new to C++, I would treat that as a separate project.
Consider putting currentTurn
currentTurn
in the struct also.I think getting the slotChoice
slotChoice
input and validating it is a good bit of work to move to a new function. I would move this:cin >> slotChoice; while (!isEmpty(gameGrid[slotChoice])) { cout << "Slot occupied. Please select another slot > "; cin >> slotChoice; }
(Small point) I like to read things in their natural order. I'd rather see the "stuff" for player 1 come before the "stuff" for player 2. So I'd use a bool
bool
namedisP1
and rearrange several conditional statements.In the "Check Winner" section of the while
while
loop, you could save the return value fromcheckWon()
in a local boolbool
variable. Then you wouldn't need to call the function again to decide if the game was a draw.I see some code duplication, especially in the code that generates output.
I made the parameter "const"const
. I changed the cascading "else if"else if
statements to three independent "if"if
statements. I think that reflects the underlying logic a bit better; the three win conditions aren't mutually exclusive.
You could simplify the logic in function
rowWon()
. If you checkisEmpty(firstInRow)
, you don't need to also checkisEmpty(secondInRow)
andisEmpty(thirdInRow)
. (The later comparisons with firstInRow will exclude cases where the other cells in the row are empty.)columnWon()
anddiagonalWon()
could get the same simplification.There's a lot of code duplication (and conceptual duplication) between RowWon()
RowWon()
, columnWon()columnWon()
, and diagonalWon()diagonalWon()
. At the core of each is a complicated if statement that examines 3 cells and returns a bool result. But all of those ifif
statements are essentially the same. That decision could go in a a separate function -- pass it the 3 cell values. The other part of each function involves deciding which 3 cells to test; those decisions are different for each win condition.