Kontrola výhry v hře piškvorky v JavaScriptu

Nyní je čas napsat kód, který bude určovat výhru a zobrazovat jméno vítěze.

Po zvážení úkolu lze dojít k závěru, že kontrolu výhry bychom měli provádět v každém tahu:

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);
      
      // zde bychom měli kontrolovat výhru nebo remízu
      
      i++;
    });
  }
}

Vytvořme funkci isVictory, která bude jako parametr přijímat pole buněk a vracet true, pokud na hrací ploše došlo k výhře, a false, pokud ne. Této funkce budeme používat následujícím způsobem:

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('jméno vítěze');
      }
      
      i++;
    });
  }
}

Jak ale zjistíme jméno vítěze? Je zřejmé, že jeho jméno je uloženo v každé z vítězných buněk. Vysvětlím: pokud dojde k výhře, znamená to, že některé 3 buňky v horizontálním, vertikálním nebo diagonálním směru obsahují stejnou hodnotu: buď křížek, nebo kolečko.

Je zřejmé, že hodnota kterékoliv z těchto buněk je jménem vítěze. Ale lze jít i jinou, méně zřejmou cestou: protože výhru určujeme v každém tahu, je logické, že vítězem bude hráč, který provedl poslední tah. Jméno tohoto hráče je obsaženo v textu kliknuté buňky:

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); // zobrazíme jméno vítěze
      }
      
      i++;
    });
  }
}

Implementace isVictory

Jak technicky určíme přítomnost výhry na hrací ploše? Pokud vše dobře promyslíme, můžeme dojít k závěru, že na hrací ploše existuje omezené množství trojic buněk.

To znamená, že pro kontrolu výhry lze jednoduše zkontrolovat všechny tyto trojice. Je třeba zkontrolovat, zda trojice mají stejné neprázdné hodnoty (tedy buď křížek, nebo kolečko).

Vytvořme dvourozměrné pole, v každém subpoli kterého budou čísla buněk jedné z trojic:

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],
];

Napišme pomocí tohoto pole určení výhry:

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

Samostatně, bez nahlížení do mého kódu, implementujte výše popsané. Ověřte, jak funguje herní proces.

Задание 2

Zkuste implementovat kontrolu remízy. V následující lekci bude rozbor tohoto místa.