I have the code below for a 3x3 tic-tac-toe game. It works perfectly fine, but there are things I don't understand.
The objective of the function is to return:
function isSolved(board) {
board = board.join('-').replace(/,/g,'');
if(/222|2...2...2|2....2....2|2..2..2/.test(board)) return 2;
if(/111|1...1...1|1....1....1|1..1..1/.test(board)) return 1;
if(/0/.test(board)) return -1;
return 0;
}
var result = isSolved([[0, 0, 1],[0, 1, 2],[2, 1, 0]]); //board is 3 dimensional array.
console.log(result); // -1
I don't understand a part of the regex in the if
statement, i.e 1....1....1
, since the maximum input the board can take is 9; but here it seems to be 11. Why is that?
The code is absolutely fine, but I don't understand what's happening. Could you explain?
The regex looks at 11 characters because board
has been joined with two extra -
characters:
board = board.join('-')
Presumably, the original board
is a 2D array, and the commas introduced by this join (as the nested arrays are stringified in the process), are removed with:
.replace(/,/g,'');
So an original board like this:
[
[1, 0, 1],
[2, 2, 0],
[0, 0, 0]
]
...is turned into a string with .join("-")
:
"1,0,1-2,2,0-0,0,0"
...and finally cleaned of the commas:
"101-220-000".
The additional separator makes it easier to find some patterns without raising false positives. For instance, when there is a match with 222
, one can be sure that they will be in one row, and a match with 1..1..1
will likewise detect the three possible vertical 3-in-a-rows without false positives as it can only have a match that starts at position 0, 1 or 2. The 1....1....1
is 11 characters long and can only match at position 0 for one of the diagonals. Finally, 1..1..1
can also only match at one position, i.e. position 2, as otherwise one of the hyphens would conflict with a 1
in the pattern. A match represents the opposite diagonal.
One could merge two regexes into one (saving some execution time), by using a back reference, and use some logic to join all possibilities in one expression:
function isSolved(board) {
board = board.join('-').replace(/,/g,'');
var match = board.search(/([12])(\1|...\1...|....\1....|..\1..)\1/);
return +(board[match] || board.includes("0") && -1);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With