Ristinollan voiton tarkistus JavaScriptillä

Nyt on aika kirjoittaa koodi, joka tunnistaa voiton ja näyttää voittajan nimen.

Kun pohtii tehtävää, voi päätellä, että voiton tarkistus tulisi suorittaa jokaisella siirrolla:

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);
      
      // tässä meidän tulisi tarkistaa voitto tai tasapeli
      
      i++;
    });
  }
}

Tehdään funktio isVictory, joka parametrina vastaanottaa solujen taulukon ja palauttaa true, jos kentällä on voitto, ja false, jos ei ole. Me käytämme tätä funktiota seuraavalla tavalla:

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('voittajan nimi');
      }
      
      i++;
    });
  }
}

Kuinka saamme selville voittajan nimen? Ilmeisesti, hänen nimensä tallentuu jokaiseen voittoon johtaneeseen soluun. Selitän: jos meillä on voitto, niin tämä tarkoittaa, että tietyt 3 solua vaaka-, pysty- tai diagonaalisuunnassa sisältävät saman arvon: joko ristin tai nollan.

Ilmeisesti minkä tahansa näistä soluista arvo on voittajan nimi. Mutta voidaan mennä toisella, vähemmän ilmeisellä tavalla: koska määritämme voiton olemassaolon jokaisella siirrolla, on loogista, että voittaja on pelaaja, joka teki viimeisen siirron. Tämän pelaajan nimi sisältyy klikatun solun tekstiin:

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); // näytetään voittajan nimi
      }
      
      i++;
    });
  }
}

isVictory-funktion toteutus

Kuinka teknisesti määritämme voiton olemassaolon kentällä? Jos pohtii kaiken huolellisesti, voidaan päätellä, että kentällä on rajoitettu määrä solukolmikoita.

Eli voiton tarkistamiseksi voidaan yksinkertaisesti tarkistaa kaikki nämä kolmikot. On tarkistettava, että kolmikoilla on samat ei-tyhjät arvot (eli siellä on joko risti tai nolla).

Tehdään kaksiulotteinen taulukko, jossa jokainen alitaulukko sisältää yhden kolmikon solujen numerot:

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

Kirjoitetaan tämän taulukon avulla voiton määrittely:

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

Toteuta itsenäisesti, katsomatta koodiini, kuvailtu. Tarkista, kuinka peliprosessi toimii.

Задание 2

Yritä toteuttaa tasapelin tarkistus. Seuraavassa oppitunnissa käsitellään tätä kohtaa.