Scalable grid with input for 'Tic Tac Toe' - In C++

For one of my assignments for my programming module, I have been given the task of creating a 'Tic Tac Toe' game in C++ with many additional improvements and features added to the base to show my range of skills and my creativity. For this program, I have created a function that will display a grid of any size, where the row length is always equal to the column length, and can take in input that will also adapt to the size of the grid.

Displaying A Grid Filled With Values

 This is a screenshot of the 'DisplayGrid' function. It is responsible for displaying a grid that is been filled in with what the players have inputted previously and will let the players decide their next move. Each line has been commented to explain what they do and what the next lines will be doing. In a quick summary, the function starts off by initialising a variable called 'currentColour', which will store the colour of the current player's symbol to apply to the cell. It then loops through the rows and columns of the grid using the 'gridSize' variable, allowing this function to work with any grid size. Before each column is looped through in a row, the first value of that row will be added to a 'rowString'. The 'rowString' variable stores that entire row, being added to at the end of each loop of the columns and then outputted to the console before starting on a new row. A check is done to see which player the current cell is assigned to, assigning the player's colour to the 'currentColour' variable from earlier.  It then adds to the 'rowString' the symbol that is being held in the current cell and concatenating 'currentColour' to it and a reset colour so that the rest of the console stays the default white colour. Empty space is added based on the 'cellWidth' variable, which is determined during the setting up function at the start of this program by getting the length of characters in the total number of grid cells. It repeats this same logic with each column, ignoring the first column since we already used some logic for it, but at the end of each iteration a 'separatorString' gets a string added to it, which essentially increases the length of the row separator so that it scales with the number of columns present and keeps the grid looking nice and clean. A separator character is also added after each cell to keep them clean and organised as well. Then after a row has finished being looped through, it outputs this the to console and starts again on a new row until the last. After these process have been complete, the output should look something like this:

This is obviously a small 3x3 grid, the default for a game of Tic Tac Toe, but with my scalable solution I can apply this to a 4x4 grid, 5x5 grid, or even a 10x10 grid:


Of course, this sounds very silly since you would not actually be able to win with a 10x10 grid versus anyone, but it was more of a test to see if I could find a solution to this silly idea. In the final product of my program I might add some special rules for bigger grid sizes, maybe just having the player find a way to get a 3 line match to make it fair and could be similar to a game of 'Connect 4'. This would definitely scale up the difficulty because there would a lot more ways to get a line match and much hard to block a match if played badly.

As I am writing this, I have also realised that there are some ways that I could improve the efficiency of this function. One improvement would be to when the first value of each row is added to the string and the separator string is initialised. I do not need this as I could just have an if statement in the column loop to check if the current column is the first column, where it can stop adding a separator before the cell as it will not need it. This is also applied to the input function that will be explained later in this post, and will be shown the updated version in this post to demonstrate how it is more efficient. This could definitely get some more optimisations if I prioritised it more over the actual development of it's features, but the program has not been completed and I will definitely spot some more later down the line.

User Input To Fill In Cells Of A Grid

Getting user input is very straight forward from here. All that needs to be done is create a grid that shows what value to input to fill in a certain cell on the grid. Then check for input from the user and validate it to make sure that it is a valid within the grid range and that it isn't a cell that has already been filled in.

This is a screenshot of the 'DisplayInput' function. The purpose of this function is to display a grid that shows the range of value that can be entered to fill a cell based on the number of cells in the grid. It is not a complex function and uses similar lines of code to the 'DisplayGrid' function. The only difference is that it does not need to check for player colours and instead of adding the value of the grid cell to the 'rowString', it adds the input value of the grid cell that corresponds to the Tic Tac Toe grid from before. The calculation that is being performed to get the input value of each cell is straight forward; it takes the current column index and adds one to it since it will start from 0 in the loop. We then use the fact that the for loop will start at 0 to add the previous rows via multiplying the row index by the 'gridSize' variable, which . This gives a very accurate grid full of number inputs based on their cell position and an adaptable system that can give values for different grid sizes reliably.
To get actual input from the user, another function is used to perform validation checks on the input and send messages to the console indicating that the validation checks have either passed or failed.
All this function does is use a 'do while' loop to make sure that any invalid inputs will result in letting the user retry with another input until they finally perform a valid input. The conditions I have set to check for valid inputs are: if the 'cin' object has not failed, the input is a number, and the number is within the range of 0 to the 'gridSize' squared. This then allows the function 'FillCell' to be called, which takes in the row and column of the cell to be filled in. The calculation for finding the row is simply the input minus 1, since it needs to be put into a range that starts from 0 for indexing, and is then divided by the 'gridSize' to find how many rows have been completed. Since this is casted into an integer data type, it will not include any decimals. To get the column we take the input and minus 1 again, then perform modulo to find out how many columns have been crossed in the row to reach this input value. It is a pretty straight forward function and will take these values to check if the cell has been filled in, setting the current cell to the current player's symbol if it is empty.

One big improvement that could be made to this input grid, mainly applicable to the Tic Tac Toe game, is to highlight or strikeout the input values that will always result in a "That cell is filled, please try again" to give clarity to the user on which options they truly have instead of them having to try certain inputs. This would definitely benefit those with bad vision and can not easily match the input value with the correct cell.

And that is pretty much it for this small portion of my project. It's capabilities of adapting to whatever size grid we ask for can create many opportunities for unique versions of the game. My knowledge skills in programming with the C++ language have definitely been developed further and I am more confident in completing solutions in this language for increasingly complex tasks I may find myself doing in the future.

A GitHub will be made available in a later post when the full program has been fully developed.