Prevent Impossible States and Check for Draw Conditions with Guard Statements in React

Kyle Shevlin
InstructorKyle Shevlin
Share this video with your friends

Social Share Links

Send Tweet
Published 4 years ago
Updated 3 years ago

We should add some final touches to our tic-tac-toe game. We want to make sure that after a user has won, that it's impossible for them to put the game into a broken state. We can do that by adding a guard to our reducer.

It would also be nice if the board automatically reset in the result of a draw. We can add a checkForDraw function that algorithmically determines if the game is drawn or not and automatically reset the grid data.

Kyle Shevlin: [0:00] I'm going to add to final touches to our Tic Tac Toe game. The first one is I don't want the game to be able get into what should be an impossible state, as is it's possible that if X may win, it's also possible for the turn not to change and the board to fill up. It's not ideal.

[0:20] What I'm going to do is I'm going to add a guard statement and a reducer that prevents that. If the state.status = 'success' and the action.type ≠ 'RESET', what we want our program to do is just return the state. We have that in place.

[0:40] Now, if we get into a win situation where X1 clicking it does nothing, and the only thing I can do in the game is reset.

[0:49] The next nice touch I would like to add is, instead of only checking for a win, I'd like to check for a draw. What if our game gets into a state where it's impossible for someone to win, like this game right here? I would like the game to automatically reset for us. We can do that by checking for a draw.

[1:10] I'll add the logic right here, if (checkForDraw(flatGrid)). We'll pass in the flat grid as well. This is why we flattened it before, so we only have to flatten it once. What I'd like to do is return getInitialState. Reset the whole game for our users.

[1:27] Now, this won't work until I add a checkForDraw() function. Let's come up to where checkForWin() is and add that. Checking for a draw is remarkably simple, so that receives our flatGrid.

[1:40] First off, we can't be in a draw if we've won, so we want to return ! CheckForWin(flatGrid). It's logically impossible to be in a winning state and a drawing state. What we'll do is we'll call flatGrid.filter. We'll pass in the (Boolean) constructor, which will filter out all the null values in our board.

[2:03] If there are any null values, we'll get a length that is shorter than the flatGrid itself. If flatGrid.filter(Boolean) is the same length as flatGrid.length, we know that the board is completely full of values. Let's put our game into a draw state again. Notice that the game reset automatically for us.