Need help understanding React Tic Tac Toe "Winner" function

Need help understanding React Tic Tac Toe "Winner" function
0

#1

Can someone please help me understand the “Winner” helper function from the React Tic Tac Toe tutorial?

This is taken from the official React tutorial. The problem I have is understand the for loop. Thanks.

function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

#2

Hello.

First, calculateWinner() function, declares a multidimensional array ‘lines’, that holds all the winning combinations.

Second, a ‘for’ loop iterate through all the combinations, and adds the board’s squares indexes in constants ‘a’, ‘b’ and ‘c’.

Finally, and ‘if’ conditional statement will compare the current combination of the iteration with the board’s clicked squares combinations, and if there is a match, it returns the current combination, otherwise it returns null.

This is my first time on this forum. Hope I could help you.


#3

It didn’t help :frowning:

But I did managed to figure out while I was showering. The test is on the value or the props. If the value of a, b, c are the same, return the value of a (either X or O).

Thanks.


#4

I was confused at first too, but breaking it down everything makes sense.

See fiddle with detailed explanation: https://jsfiddle.net/nh_codes/tyck2j64/


#5
function calculateWinner(squares) {
  const lines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];
  for (let i = 0; i < lines.length; i++) {
    const [a, b, c] = lines[i];
    if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
      return squares[a];
    }
  }
  return null;
}

understand what the logical operators are doing.

const [a, b, c] = lines[i];

lets us only look at winning combination lines while we start comparing Square’s values.
Square’s values can only be 'X' , 'O' , or null.
if the value can be converted to false (if the value is null) the if statement returns false.

if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
  return squares[a];
}

&& is checking for null values;
( why is && used twice ¯\_(ツ)_/¯ );
=== is comparing the values of [a] , [b] , and [c] to see if they are all 'X''s or all 'O''s;
return squares[a] can only be 'X' or 'O' after passing the if statement.


#6

but what i don’t understand is why in this line

if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {

why square[a] has to be by itself. isn’t

if (squares[a] === squares[b] && squares[a] === squares[c]) {

sufficient?


#7

No. The squares[a] by itself is checking if there is a value in that particular square and the remainder of the condition makes sure they are all the same type (either X or O).

What if a was not an X or O, b was not an X or O, and c was not an X or O? If you just tested the following condition, it would evaluate to true when you do not want it to.

squares[a] === squares[b] && squares[a] === squares[c]

#8

but isn’t null a falsy value?


#9

Yes, null is a falsy value, which is why if a, b, or c is null, the original if you questioned (below) would evaluate to false. This is exactly why you must have the separate squares[a] in the expression.

if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {

If a, b, and c are all null values, you do not want to return squares[a]. The if statement would look like:

if (null && null === null && null === null) {

The above reduces further to:

if (false && true && true) { // this will evaluate to false

However, if we did not include the extra squares[a] at the beginning you would be left with:

if (true && true) { // this evaluates to true, but none of the squares are Xs or Os which is a problem.