Skip to main content
add missing hypen
Source Link

You can start by making those inlinein-line functions methods. For example, currentStep (the click handler) can be a method that accepts a click event argument:

You can start by making those inline functions methods. For example, currentStep (the click handler) can be a method that accepts a click event argument:

You can start by making those in-line functions methods. For example, currentStep (the click handler) can be a method that accepts a click event argument:

check content of clickEvent.target instead of `this`
Source Link
currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!thisclickEvent.target.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
var ceil = document.getElementsByClassName("game-item"),
  reset = document.getElementById("reset-game"),
  message = document.getElementById("message"),
  stepCount = 0,
  winCombinations = [
    [1, 2, 3],
    [1, 4, 7],
    [1, 5, 9],
    [2, 5, 8],
    [3, 6, 9],
    [3, 5, 7],
    [4, 5, 6],
    [7, 8, 9]
  ],
  dataX = [],
  dataO = [];

class Player {

  constructor(name) {
    this.name = name;
  }
}


class Game {

  constructor() {
    this.playerX = new Player("X");
    this.playerO = new Player("O");
    this.currentPlayer = this.playerX.name;

    console.log(this.currentPlayer);
  }

  addX() {
    this.boundCurrentStep = this.currentStep.bind(this);
    for (var i = 0; i < ceil.length; i++) {
      ceil[i].addEventListener("click", this.boundCurrentStep);
    }
  }
  changePlayer() {
    this.currentPlayer = this.currentPlayer === 'X' ? "O" : "X";
  }


  checkWin(arr, number) {

    for (var w = 0, wLen = winCombinations.length; w < wLen; w++) {
      var someWinArr = winCombinations[w],
        count = 0;
      if (someWinArr.indexOf(number) !== -1) {
        for (var k = 0, kLen = someWinArr.length; k < kLen; k++) {
          if (arr.indexOf(someWinArr[k]) !== -1) {
            count++;
            if (count === 3) {
              return true;
            }
          }
        }
        count = 0;
      }
    }
  }
  currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!thisclickEvent.target.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
  reset() {
    reset.addEventListener("click", function() {
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].innerText = "";
      }
      dataO = [];
      dataX = [];
      this.currentPlayer = "X";
      stepCount = 0;
      message.innerText = "The player " + this.currentPlayer;
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].classList.remove("x", "o");
         ceil[i].addEventListener("click", this.boundCurrentStep);
      }
    }.bind(this));
  }
}

const game = new Game();
game.addX();
game.reset();
* {
  box-sizing: border-box;
  outline: none;
}

.game-title {
  display: block;
  margin-bottom: 30px;
  font-size: 35px;
  font-weight: bold;
  text-align: center;
}

.game {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  width: 152px;
  margin: 0 auto 50px;
  border: 1px solid #000;
}

.game-item {
  position: relative;
  width: 50px;
  height: 50px;
  line-height: 48px;
  border: 1px solid #000;
  cursor: pointer;
  text-align: center;
  font-size: 30px;
  font-weight: bold;
  transition: all linear 0.3s;
}

.game-item:hover {
  background-color: #ccc;
}

.game-item.o {
  background-color: #abfdab;
}

.game-item.x {
  background-color: #f99;
}

#reset-game {
  display: block;
  margin: 0 auto;
  border: 1px solid #000;
  border-radius: 20px;
  background-color: #fff;
  padding: 10px 20px;
  cursor: pointer;
  transition: all linear 0.3s;
}

#reset-game:hover {
  background-color: #ccc;
}
<span class="game-title" id="message">The player X</span>
<div class="game">
  <div class="game-item" data-ceil="1"></div>
  <div class="game-item" data-ceil="2"></div>
  <div class="game-item" data-ceil="3"></div>
  <div class="game-item" data-ceil="4"></div>
  <div class="game-item" data-ceil="5"></div>
  <div class="game-item" data-ceil="6"></div>
  <div class="game-item" data-ceil="7"></div>
  <div class="game-item" data-ceil="8"></div>
  <div class="game-item" data-ceil="9"></div>
</div>
<button id="reset-game">Clear</button>
currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!this.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
var ceil = document.getElementsByClassName("game-item"),
  reset = document.getElementById("reset-game"),
  message = document.getElementById("message"),
  stepCount = 0,
  winCombinations = [
    [1, 2, 3],
    [1, 4, 7],
    [1, 5, 9],
    [2, 5, 8],
    [3, 6, 9],
    [3, 5, 7],
    [4, 5, 6],
    [7, 8, 9]
  ],
  dataX = [],
  dataO = [];

class Player {

  constructor(name) {
    this.name = name;
  }
}


class Game {

  constructor() {
    this.playerX = new Player("X");
    this.playerO = new Player("O");
    this.currentPlayer = this.playerX.name;

    console.log(this.currentPlayer);
  }

  addX() {
    this.boundCurrentStep = this.currentStep.bind(this);
    for (var i = 0; i < ceil.length; i++) {
      ceil[i].addEventListener("click", this.boundCurrentStep);
    }
  }
  changePlayer() {
    this.currentPlayer = this.currentPlayer === 'X' ? "O" : "X";
  }


  checkWin(arr, number) {

    for (var w = 0, wLen = winCombinations.length; w < wLen; w++) {
      var someWinArr = winCombinations[w],
        count = 0;
      if (someWinArr.indexOf(number) !== -1) {
        for (var k = 0, kLen = someWinArr.length; k < kLen; k++) {
          if (arr.indexOf(someWinArr[k]) !== -1) {
            count++;
            if (count === 3) {
              return true;
            }
          }
        }
        count = 0;
      }
    }
  }
  currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!this.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
  reset() {
    reset.addEventListener("click", function() {
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].innerText = "";
      }
      dataO = [];
      dataX = [];
      this.currentPlayer = "X";
      stepCount = 0;
      message.innerText = "The player " + this.currentPlayer;
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].classList.remove("x", "o");
         ceil[i].addEventListener("click", this.boundCurrentStep);
      }
    }.bind(this));
  }
}

const game = new Game();
game.addX();
game.reset();
* {
  box-sizing: border-box;
  outline: none;
}

.game-title {
  display: block;
  margin-bottom: 30px;
  font-size: 35px;
  font-weight: bold;
  text-align: center;
}

.game {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  width: 152px;
  margin: 0 auto 50px;
  border: 1px solid #000;
}

.game-item {
  position: relative;
  width: 50px;
  height: 50px;
  line-height: 48px;
  border: 1px solid #000;
  cursor: pointer;
  text-align: center;
  font-size: 30px;
  font-weight: bold;
  transition: all linear 0.3s;
}

.game-item:hover {
  background-color: #ccc;
}

.game-item.o {
  background-color: #abfdab;
}

.game-item.x {
  background-color: #f99;
}

#reset-game {
  display: block;
  margin: 0 auto;
  border: 1px solid #000;
  border-radius: 20px;
  background-color: #fff;
  padding: 10px 20px;
  cursor: pointer;
  transition: all linear 0.3s;
}

#reset-game:hover {
  background-color: #ccc;
}
<span class="game-title" id="message">The player X</span>
<div class="game">
  <div class="game-item" data-ceil="1"></div>
  <div class="game-item" data-ceil="2"></div>
  <div class="game-item" data-ceil="3"></div>
  <div class="game-item" data-ceil="4"></div>
  <div class="game-item" data-ceil="5"></div>
  <div class="game-item" data-ceil="6"></div>
  <div class="game-item" data-ceil="7"></div>
  <div class="game-item" data-ceil="8"></div>
  <div class="game-item" data-ceil="9"></div>
</div>
<button id="reset-game">Clear</button>
currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!clickEvent.target.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
var ceil = document.getElementsByClassName("game-item"),
  reset = document.getElementById("reset-game"),
  message = document.getElementById("message"),
  stepCount = 0,
  winCombinations = [
    [1, 2, 3],
    [1, 4, 7],
    [1, 5, 9],
    [2, 5, 8],
    [3, 6, 9],
    [3, 5, 7],
    [4, 5, 6],
    [7, 8, 9]
  ],
  dataX = [],
  dataO = [];

class Player {

  constructor(name) {
    this.name = name;
  }
}


class Game {

  constructor() {
    this.playerX = new Player("X");
    this.playerO = new Player("O");
    this.currentPlayer = this.playerX.name;

    console.log(this.currentPlayer);
  }

  addX() {
    this.boundCurrentStep = this.currentStep.bind(this);
    for (var i = 0; i < ceil.length; i++) {
      ceil[i].addEventListener("click", this.boundCurrentStep);
    }
  }
  changePlayer() {
    this.currentPlayer = this.currentPlayer === 'X' ? "O" : "X";
  }


  checkWin(arr, number) {

    for (var w = 0, wLen = winCombinations.length; w < wLen; w++) {
      var someWinArr = winCombinations[w],
        count = 0;
      if (someWinArr.indexOf(number) !== -1) {
        for (var k = 0, kLen = someWinArr.length; k < kLen; k++) {
          if (arr.indexOf(someWinArr[k]) !== -1) {
            count++;
            if (count === 3) {
              return true;
            }
          }
        }
        count = 0;
      }
    }
  }
  currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!clickEvent.target.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }
  reset() {
    reset.addEventListener("click", function() {
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].innerText = "";
      }
      dataO = [];
      dataX = [];
      this.currentPlayer = "X";
      stepCount = 0;
      message.innerText = "The player " + this.currentPlayer;
      for (var i = 0; i < ceil.length; i++) {
        ceil[i].classList.remove("x", "o");
         ceil[i].addEventListener("click", this.boundCurrentStep);
      }
    }.bind(this));
  }
}

const game = new Game();
game.addX();
game.reset();
* {
  box-sizing: border-box;
  outline: none;
}

.game-title {
  display: block;
  margin-bottom: 30px;
  font-size: 35px;
  font-weight: bold;
  text-align: center;
}

.game {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  width: 152px;
  margin: 0 auto 50px;
  border: 1px solid #000;
}

.game-item {
  position: relative;
  width: 50px;
  height: 50px;
  line-height: 48px;
  border: 1px solid #000;
  cursor: pointer;
  text-align: center;
  font-size: 30px;
  font-weight: bold;
  transition: all linear 0.3s;
}

.game-item:hover {
  background-color: #ccc;
}

.game-item.o {
  background-color: #abfdab;
}

.game-item.x {
  background-color: #f99;
}

#reset-game {
  display: block;
  margin: 0 auto;
  border: 1px solid #000;
  border-radius: 20px;
  background-color: #fff;
  padding: 10px 20px;
  cursor: pointer;
  transition: all linear 0.3s;
}

#reset-game:hover {
  background-color: #ccc;
}
<span class="game-title" id="message">The player X</span>
<div class="game">
  <div class="game-item" data-ceil="1"></div>
  <div class="game-item" data-ceil="2"></div>
  <div class="game-item" data-ceil="3"></div>
  <div class="game-item" data-ceil="4"></div>
  <div class="game-item" data-ceil="5"></div>
  <div class="game-item" data-ceil="6"></div>
  <div class="game-item" data-ceil="7"></div>
  <div class="game-item" data-ceil="8"></div>
  <div class="game-item" data-ceil="9"></div>
</div>
<button id="reset-game">Clear</button>
update explanation
Source Link

So in currentStep the this argument will refer to the current Game instance. Replace z with this and then any place this was previously used to access the div element, refer to clickEvent.target. Also, call changePlayer and checkWin on `this, since we will be converting those to methods as well (see below).

currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!this.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }

Then when the game is over, use removeEventListener() passing the function bound to the method currentStep() back in the add method (i.e. this.boundCurrentStep).

So in currentStep the this argument will refer to the current Game instance. Replace z with this and then any place this was previously used to access the div element, refer to clickEvent.target.

Then when the game is over, use removeEventListener() passing this.boundCurrentStep.

So in currentStep the this argument will refer to the current Game instance. Replace z with this and then any place this was previously used to access the div element, refer to clickEvent.target. Also, call changePlayer and checkWin on `this, since we will be converting those to methods as well (see below).

currentStep(clickEvent) {
    var num = +clickEvent.target.getAttribute("data-ceil");
    if (!this.textContent) {
      clickEvent.target.innerText = this.currentPlayer;

      this.currentPlayer === "X" ?
        dataX.push(num) && clickEvent.target.classList.add("x") :
        dataO.push(num) && clickEvent.target.classList.add("o");
      if (
        (dataO.length > 2 || dataX.length > 2) &&
        (this.checkWin(dataO, num) || this.checkWin(dataX, num))
      ) {
        for (var i = 0; i < ceil.length; i++) {
          ceil[i].removeEventListener("click", this.boundCurrentStep);
        }
        return (message.innerText = "Win player " + this.currentPlayer);
      }

      this.changePlayer();
      stepCount++;
      (stepCount == 9) ? (message.innerText = 'Tie') : (message.innerText = 'The player ' + this.currentPlayer);
    }
  }

Then when the game is over, use removeEventListener() passing the function bound to the method currentStep() back in the add method (i.e. this.boundCurrentStep).

Source Link
Loading