Verificação de vitória no jogo da velha em JavaScript

Agora chegou a hora de escrever o código que determinará a vitória e exibirá o nome do vencedor.

Após pensar na tarefa, pode-se perceber que a verificação de vitória deve ser executada a cada jogada:

javascriptfunction init(selector) {
  let cells = document.querySelectorAll('#field td');
  let i = 0;
  
  for (let cell of cells) {
    cell.addEventListener('click', function step() {
      this.textContent = ['X', 'O'][i % 2];
      this.removeEventListener('click', step);
      
      // aqui devemos verificar vitória ou empate
      
      i++;
    });
  }
}

Vamos criar a função isVictory, que receberá um array de células como parâmetro e retornará true se houver uma vitória no tabuleiro, e false caso contrário. Usaremos esta função da seguinte forma:

javascriptfunction start(cells) {
  let i = 0;
  
  for (let cell of cells) {
    cell.addEventListener('click', function step() {
      this.textContent = ['X', 'O'][i % 2];
      this.removeEventListener('click', step);
      
      if (isVictory(cells)) {
        alert('nome do vencedor');
      }
      
      i++;
    });
  }
}

Como podemos saber o nome do vencedor? Obviamente, seu nome está armazenado em cada uma das células vencedoras. Explicando: se houver uma vitória, isso significa que algumas 3 células na horizontal, vertical ou diagonal contêm o mesmo valor: seja um X ou um O.

Obviamente, o valor de qualquer uma dessas células é o nome do vencedor. Mas podemos seguir outro caminho, menos óbvio: como determinamos a vitória a cada jogada, é lógico que o vencedor será o jogador que fez o último movimento. O nome desse jogador está contido no texto da célula clicada:

javascriptfunction start(cells) {
  let i = 0;
  
  for (let cell of cells) {
    cell.addEventListener('click', function step() {
      this.textContent = ['X', 'O'][i % 2];
      this.removeEventListener('click', step);
      
      if (isVictory(cells)) {
        alert(this.textContent); // exibe o nome do vencedor
      }
      
      i++;
    });
  }
}

Implementação da isVictory

Como determinamos tecnicamente a presença de uma vitória no tabuleiro? Se pensarmos bem, podemos concluir que há um número limitado de combinações de três células no tabuleiro.

Ou seja, para verificar a vitória, podemos simplesmente verificar todas essas combinações. É necessário verificar se as combinações têm valores idênticos e não vazios (ou seja, contêm X ou O).

Vamos criar um array bidimensional, onde cada subarray contém os números das células de uma das combinações:

javascriptlet combs = [
  [0, 1, 2],
  [3, 4, 5],
  [6, 7, 8],
  [0, 3, 6],
  [1, 4, 7],
  [2, 5, 8],
  [0, 4, 8],
  [2, 4, 6],
];

Vamos escrever a detecção de vitória usando este array:

javascriptfunction isVictory(cells) {
  let combs = [
    [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 comb of combs) {
    if (
      cells[comb[0]].textContent == cells[comb[1]].textContent &&
      cells[comb[1]].textContent == cells[comb[2]].textContent &&
      cells[comb[0]].textContent != ''
    ) {
      return true;
    }
  }
  
  return false;
}
Задание 1

Implemente de forma independente, sem olhar o meu código, o que foi descrito. Verifique como o processo do jogo funciona.

Задание 2

Tente implementar a verificação de empate. A resolução deste ponto será apresentada na próxima lição.