Regular Expressions are complicated. The syntax can be very messy and it's all too easy to make mistakes. I am fairly inexperienced with them and so I decided to get some practice during one of my projects. I built a Tic Tac Toe game that uses a Regular Expression to identify the winner. Here I will discuss how I achieved this and if someone has a cleaner solution (as I'm sure there are many!) please comment below.

## The problem

Imagine the following setup. We have built a 3x3 grid as a table in HTML. The grid squares have id's numbered as such:

```
|1|2|3|
|4|5|6|
|7|8|9|
```

Clicking on a square fills it with an X or O depending on who's turn it is. We need a way of determining if the play that has just been made, won that player the game.

For the sake of this discussion the game is being played by 2 people, each clicking on squares in turn.

## The solution

Before the game starts we define two empty strings to track each player's moves and an array of the free grid squares.

```
let xLocations = '';
let oLocations = '';
let empty = ['1', '2', '3', '4', '5', '6', '7', '8', '9'];
```

When a player clicks on a square we add that square's id to the relevant string. For example, if the first move of the game is X clicking the center square, then `xLocations`

becomes equal to the string `'5'`

. We also remove that id from the `empty`

array.

Next we define every winning combination in Tic Tac Toe.

```
const winners = ['123', '456', '789', '147',
'258', '369', '159', '357'];
```

After each play, we need to check if the locations string matches any of these winning combinations. However there are several complicating factors:

- The play '321' is technically the same as '123' as the order played is irrelevant.
- The length of the location string will not be constant, eg '17382' is a valid winner as it contains '123'.

Therefore we need to test if a given location string contains any of the winning combinations. My solution is as follows. Every time a square is clicked we run the following function and pass in either `xLocations`

or `oLocations`

depending on whether X or O just played.

```
const checkWinner = (locations) => {
if (locations.length < 3) return;
for (let i = 0; i < winners.length; i++) {
let regexStr = winners[i].split('').join('|');
let regex = new RegExp(regexStr, 'g');
if (regex.test(locations)) {
if (locations.match(regex).length === 3) return 'win';
}
}
if (empty.length === 0) return 'draw';
};
```

Let's break this down.

Firstly, as a minimum of 3 plays is required to win, we can discard any `locations`

strings shorter than 3. We then loop over the `winners`

array and create a Regular Expression for each value in turn. For the first value this would look like the following:

```
// winners[0] = '123'
let regexStr = winners[0].split('').join('|');
// regexStr = '1|2|3|'
let regex = new RegExp(regexStr, 'g');
// regex = /1|2|3/g
```

This can be used to test if `locations`

contains any of those three numbers. Therefore all we need to do is test for strings that match it exactly 3 times.

```
if (regex.test(locations)) {
if (locations.match(regex).length === 3) return 'win';
}
```

Finally if the line `if (empty.length === 0) return 'draw';`

runs true it means that the grid is full and there is no winner.

And that's it! If you have any questions or improvements feel free to comment them below.

## Top comments (1)

I'm working on a tictactoe game. I want to use RegEx to check if someone is winning. make him want you spell