My first JS program - Tic Tac Toe game











up vote
2
down vote

favorite












I just completed some beginner web-dev courses (cs:50 and such) and wanted to try my skills.



The CSS centering - ugh I just gave up on that, I wanted to make it responsive and the letters centered perfectly, but whatever...



So overall, how is this coded? is there a better way to code this?






let turn = true;
let children;
let winnerFound = false;

document.addEventListener('DOMContentLoaded', load);

function load() {
children = document.getElementsByClassName("child");
for (let i = 0; i < children.length; i++) {
children[i].addEventListener("click", function () {
clicked(i);
});
}
document.getElementById("clear").addEventListener("click", function () {
clearBoard();
}
);
updateTurn();
}

function clearBoard() {
for (let i = 0; i < children.length; i++) {
children[i].innerHTML = '';
children[i].classList.remove('animate');
}
turn = true;
winnerFound = false;
updateTurn();
}

//text at the top
function updateTurn() {
if (turn)
document.getElementById("turn").innerHTML = "X";
else
document.getElementById("turn").innerHTML = "O";
}

function clicked(i) {
if (winnerFound)
return;
if (children[i].childElementCount !== 0)
return;
const div = document.createElement('div');
if (turn) {
div.textContent = 'X';
}
else {
div.textContent = 'O';
}
children[i].appendChild(div);
children[i].classList.add('animate');
turn = !turn;
checkWinner();
updateTurn();
}

function checkWinner() {
//check rows
for (let x = 0; x < 9; x += 3) {
if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
alert(childContent(x) + " won!");
winnerFound = true;
}
}
//check columns
for (let x = 0; x < 3; x += 1) {
if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
alert(childContent(x)+ " won!");
winnerFound = true;
}
}
//check diagonals
if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
alert(childContent(0)+ " won!");
winnerFound = true;
}
if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
alert(childContent(2)+ " won!");
winnerFound = true;
}
}

function childContent(i) {
if (children[i].childElementCount === 0) {
return i;
}
return children[i].getElementsByTagName('div')[0].innerHTML;
}

 body {
background: lightgray;
text-align: center;
vertical-align: middle;
}

.child:hover {
background-color: darkgrey;
}

.parent {
display: inline-flex;
flex-wrap: wrap;
width: 400px;
}

.child {
flex: 1 0 calc(33% - 10px);
margin: 5px;
height: 80px;
background-color: grey;
}

.animate {
animation: changeColor 0.5s forwards;
}

@keyframes changeColor {
0% {
background-color: darkgrey;
}
100% {
background-color: khaki;
font-size: 60px;
}
}

<div>
<h1>Tic Tac Toe</h1>
<h2>It is now the turn of: <span id="turn"></span></h2>
<button id="clear">CLEAR</button>
</div>
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>












share|improve this question







New contributor




John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    2
    down vote

    favorite












    I just completed some beginner web-dev courses (cs:50 and such) and wanted to try my skills.



    The CSS centering - ugh I just gave up on that, I wanted to make it responsive and the letters centered perfectly, but whatever...



    So overall, how is this coded? is there a better way to code this?






    let turn = true;
    let children;
    let winnerFound = false;

    document.addEventListener('DOMContentLoaded', load);

    function load() {
    children = document.getElementsByClassName("child");
    for (let i = 0; i < children.length; i++) {
    children[i].addEventListener("click", function () {
    clicked(i);
    });
    }
    document.getElementById("clear").addEventListener("click", function () {
    clearBoard();
    }
    );
    updateTurn();
    }

    function clearBoard() {
    for (let i = 0; i < children.length; i++) {
    children[i].innerHTML = '';
    children[i].classList.remove('animate');
    }
    turn = true;
    winnerFound = false;
    updateTurn();
    }

    //text at the top
    function updateTurn() {
    if (turn)
    document.getElementById("turn").innerHTML = "X";
    else
    document.getElementById("turn").innerHTML = "O";
    }

    function clicked(i) {
    if (winnerFound)
    return;
    if (children[i].childElementCount !== 0)
    return;
    const div = document.createElement('div');
    if (turn) {
    div.textContent = 'X';
    }
    else {
    div.textContent = 'O';
    }
    children[i].appendChild(div);
    children[i].classList.add('animate');
    turn = !turn;
    checkWinner();
    updateTurn();
    }

    function checkWinner() {
    //check rows
    for (let x = 0; x < 9; x += 3) {
    if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
    alert(childContent(x) + " won!");
    winnerFound = true;
    }
    }
    //check columns
    for (let x = 0; x < 3; x += 1) {
    if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
    alert(childContent(x)+ " won!");
    winnerFound = true;
    }
    }
    //check diagonals
    if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
    alert(childContent(0)+ " won!");
    winnerFound = true;
    }
    if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
    alert(childContent(2)+ " won!");
    winnerFound = true;
    }
    }

    function childContent(i) {
    if (children[i].childElementCount === 0) {
    return i;
    }
    return children[i].getElementsByTagName('div')[0].innerHTML;
    }

     body {
    background: lightgray;
    text-align: center;
    vertical-align: middle;
    }

    .child:hover {
    background-color: darkgrey;
    }

    .parent {
    display: inline-flex;
    flex-wrap: wrap;
    width: 400px;
    }

    .child {
    flex: 1 0 calc(33% - 10px);
    margin: 5px;
    height: 80px;
    background-color: grey;
    }

    .animate {
    animation: changeColor 0.5s forwards;
    }

    @keyframes changeColor {
    0% {
    background-color: darkgrey;
    }
    100% {
    background-color: khaki;
    font-size: 60px;
    }
    }

    <div>
    <h1>Tic Tac Toe</h1>
    <h2>It is now the turn of: <span id="turn"></span></h2>
    <button id="clear">CLEAR</button>
    </div>
    <div class="parent">
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    <div class="child"></div>
    </div>












    share|improve this question







    New contributor




    John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      2
      down vote

      favorite









      up vote
      2
      down vote

      favorite











      I just completed some beginner web-dev courses (cs:50 and such) and wanted to try my skills.



      The CSS centering - ugh I just gave up on that, I wanted to make it responsive and the letters centered perfectly, but whatever...



      So overall, how is this coded? is there a better way to code this?






      let turn = true;
      let children;
      let winnerFound = false;

      document.addEventListener('DOMContentLoaded', load);

      function load() {
      children = document.getElementsByClassName("child");
      for (let i = 0; i < children.length; i++) {
      children[i].addEventListener("click", function () {
      clicked(i);
      });
      }
      document.getElementById("clear").addEventListener("click", function () {
      clearBoard();
      }
      );
      updateTurn();
      }

      function clearBoard() {
      for (let i = 0; i < children.length; i++) {
      children[i].innerHTML = '';
      children[i].classList.remove('animate');
      }
      turn = true;
      winnerFound = false;
      updateTurn();
      }

      //text at the top
      function updateTurn() {
      if (turn)
      document.getElementById("turn").innerHTML = "X";
      else
      document.getElementById("turn").innerHTML = "O";
      }

      function clicked(i) {
      if (winnerFound)
      return;
      if (children[i].childElementCount !== 0)
      return;
      const div = document.createElement('div');
      if (turn) {
      div.textContent = 'X';
      }
      else {
      div.textContent = 'O';
      }
      children[i].appendChild(div);
      children[i].classList.add('animate');
      turn = !turn;
      checkWinner();
      updateTurn();
      }

      function checkWinner() {
      //check rows
      for (let x = 0; x < 9; x += 3) {
      if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
      alert(childContent(x) + " won!");
      winnerFound = true;
      }
      }
      //check columns
      for (let x = 0; x < 3; x += 1) {
      if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
      alert(childContent(x)+ " won!");
      winnerFound = true;
      }
      }
      //check diagonals
      if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
      alert(childContent(0)+ " won!");
      winnerFound = true;
      }
      if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
      alert(childContent(2)+ " won!");
      winnerFound = true;
      }
      }

      function childContent(i) {
      if (children[i].childElementCount === 0) {
      return i;
      }
      return children[i].getElementsByTagName('div')[0].innerHTML;
      }

       body {
      background: lightgray;
      text-align: center;
      vertical-align: middle;
      }

      .child:hover {
      background-color: darkgrey;
      }

      .parent {
      display: inline-flex;
      flex-wrap: wrap;
      width: 400px;
      }

      .child {
      flex: 1 0 calc(33% - 10px);
      margin: 5px;
      height: 80px;
      background-color: grey;
      }

      .animate {
      animation: changeColor 0.5s forwards;
      }

      @keyframes changeColor {
      0% {
      background-color: darkgrey;
      }
      100% {
      background-color: khaki;
      font-size: 60px;
      }
      }

      <div>
      <h1>Tic Tac Toe</h1>
      <h2>It is now the turn of: <span id="turn"></span></h2>
      <button id="clear">CLEAR</button>
      </div>
      <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      </div>












      share|improve this question







      New contributor




      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I just completed some beginner web-dev courses (cs:50 and such) and wanted to try my skills.



      The CSS centering - ugh I just gave up on that, I wanted to make it responsive and the letters centered perfectly, but whatever...



      So overall, how is this coded? is there a better way to code this?






      let turn = true;
      let children;
      let winnerFound = false;

      document.addEventListener('DOMContentLoaded', load);

      function load() {
      children = document.getElementsByClassName("child");
      for (let i = 0; i < children.length; i++) {
      children[i].addEventListener("click", function () {
      clicked(i);
      });
      }
      document.getElementById("clear").addEventListener("click", function () {
      clearBoard();
      }
      );
      updateTurn();
      }

      function clearBoard() {
      for (let i = 0; i < children.length; i++) {
      children[i].innerHTML = '';
      children[i].classList.remove('animate');
      }
      turn = true;
      winnerFound = false;
      updateTurn();
      }

      //text at the top
      function updateTurn() {
      if (turn)
      document.getElementById("turn").innerHTML = "X";
      else
      document.getElementById("turn").innerHTML = "O";
      }

      function clicked(i) {
      if (winnerFound)
      return;
      if (children[i].childElementCount !== 0)
      return;
      const div = document.createElement('div');
      if (turn) {
      div.textContent = 'X';
      }
      else {
      div.textContent = 'O';
      }
      children[i].appendChild(div);
      children[i].classList.add('animate');
      turn = !turn;
      checkWinner();
      updateTurn();
      }

      function checkWinner() {
      //check rows
      for (let x = 0; x < 9; x += 3) {
      if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
      alert(childContent(x) + " won!");
      winnerFound = true;
      }
      }
      //check columns
      for (let x = 0; x < 3; x += 1) {
      if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
      alert(childContent(x)+ " won!");
      winnerFound = true;
      }
      }
      //check diagonals
      if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
      alert(childContent(0)+ " won!");
      winnerFound = true;
      }
      if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
      alert(childContent(2)+ " won!");
      winnerFound = true;
      }
      }

      function childContent(i) {
      if (children[i].childElementCount === 0) {
      return i;
      }
      return children[i].getElementsByTagName('div')[0].innerHTML;
      }

       body {
      background: lightgray;
      text-align: center;
      vertical-align: middle;
      }

      .child:hover {
      background-color: darkgrey;
      }

      .parent {
      display: inline-flex;
      flex-wrap: wrap;
      width: 400px;
      }

      .child {
      flex: 1 0 calc(33% - 10px);
      margin: 5px;
      height: 80px;
      background-color: grey;
      }

      .animate {
      animation: changeColor 0.5s forwards;
      }

      @keyframes changeColor {
      0% {
      background-color: darkgrey;
      }
      100% {
      background-color: khaki;
      font-size: 60px;
      }
      }

      <div>
      <h1>Tic Tac Toe</h1>
      <h2>It is now the turn of: <span id="turn"></span></h2>
      <button id="clear">CLEAR</button>
      </div>
      <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      </div>








      let turn = true;
      let children;
      let winnerFound = false;

      document.addEventListener('DOMContentLoaded', load);

      function load() {
      children = document.getElementsByClassName("child");
      for (let i = 0; i < children.length; i++) {
      children[i].addEventListener("click", function () {
      clicked(i);
      });
      }
      document.getElementById("clear").addEventListener("click", function () {
      clearBoard();
      }
      );
      updateTurn();
      }

      function clearBoard() {
      for (let i = 0; i < children.length; i++) {
      children[i].innerHTML = '';
      children[i].classList.remove('animate');
      }
      turn = true;
      winnerFound = false;
      updateTurn();
      }

      //text at the top
      function updateTurn() {
      if (turn)
      document.getElementById("turn").innerHTML = "X";
      else
      document.getElementById("turn").innerHTML = "O";
      }

      function clicked(i) {
      if (winnerFound)
      return;
      if (children[i].childElementCount !== 0)
      return;
      const div = document.createElement('div');
      if (turn) {
      div.textContent = 'X';
      }
      else {
      div.textContent = 'O';
      }
      children[i].appendChild(div);
      children[i].classList.add('animate');
      turn = !turn;
      checkWinner();
      updateTurn();
      }

      function checkWinner() {
      //check rows
      for (let x = 0; x < 9; x += 3) {
      if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
      alert(childContent(x) + " won!");
      winnerFound = true;
      }
      }
      //check columns
      for (let x = 0; x < 3; x += 1) {
      if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
      alert(childContent(x)+ " won!");
      winnerFound = true;
      }
      }
      //check diagonals
      if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
      alert(childContent(0)+ " won!");
      winnerFound = true;
      }
      if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
      alert(childContent(2)+ " won!");
      winnerFound = true;
      }
      }

      function childContent(i) {
      if (children[i].childElementCount === 0) {
      return i;
      }
      return children[i].getElementsByTagName('div')[0].innerHTML;
      }

       body {
      background: lightgray;
      text-align: center;
      vertical-align: middle;
      }

      .child:hover {
      background-color: darkgrey;
      }

      .parent {
      display: inline-flex;
      flex-wrap: wrap;
      width: 400px;
      }

      .child {
      flex: 1 0 calc(33% - 10px);
      margin: 5px;
      height: 80px;
      background-color: grey;
      }

      .animate {
      animation: changeColor 0.5s forwards;
      }

      @keyframes changeColor {
      0% {
      background-color: darkgrey;
      }
      100% {
      background-color: khaki;
      font-size: 60px;
      }
      }

      <div>
      <h1>Tic Tac Toe</h1>
      <h2>It is now the turn of: <span id="turn"></span></h2>
      <button id="clear">CLEAR</button>
      </div>
      <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      </div>





      let turn = true;
      let children;
      let winnerFound = false;

      document.addEventListener('DOMContentLoaded', load);

      function load() {
      children = document.getElementsByClassName("child");
      for (let i = 0; i < children.length; i++) {
      children[i].addEventListener("click", function () {
      clicked(i);
      });
      }
      document.getElementById("clear").addEventListener("click", function () {
      clearBoard();
      }
      );
      updateTurn();
      }

      function clearBoard() {
      for (let i = 0; i < children.length; i++) {
      children[i].innerHTML = '';
      children[i].classList.remove('animate');
      }
      turn = true;
      winnerFound = false;
      updateTurn();
      }

      //text at the top
      function updateTurn() {
      if (turn)
      document.getElementById("turn").innerHTML = "X";
      else
      document.getElementById("turn").innerHTML = "O";
      }

      function clicked(i) {
      if (winnerFound)
      return;
      if (children[i].childElementCount !== 0)
      return;
      const div = document.createElement('div');
      if (turn) {
      div.textContent = 'X';
      }
      else {
      div.textContent = 'O';
      }
      children[i].appendChild(div);
      children[i].classList.add('animate');
      turn = !turn;
      checkWinner();
      updateTurn();
      }

      function checkWinner() {
      //check rows
      for (let x = 0; x < 9; x += 3) {
      if (childContent(x) === childContent(x + 1) && childContent(x) === childContent(x + 2)) {
      alert(childContent(x) + " won!");
      winnerFound = true;
      }
      }
      //check columns
      for (let x = 0; x < 3; x += 1) {
      if (childContent(x) === childContent(x + 3) && childContent(x) === childContent(x + 6)) {
      alert(childContent(x)+ " won!");
      winnerFound = true;
      }
      }
      //check diagonals
      if (childContent(0) === childContent(4) && childContent(0) === childContent(8)) {
      alert(childContent(0)+ " won!");
      winnerFound = true;
      }
      if (childContent(2) === childContent(4) && childContent(2) === childContent(6)) {
      alert(childContent(2)+ " won!");
      winnerFound = true;
      }
      }

      function childContent(i) {
      if (children[i].childElementCount === 0) {
      return i;
      }
      return children[i].getElementsByTagName('div')[0].innerHTML;
      }

       body {
      background: lightgray;
      text-align: center;
      vertical-align: middle;
      }

      .child:hover {
      background-color: darkgrey;
      }

      .parent {
      display: inline-flex;
      flex-wrap: wrap;
      width: 400px;
      }

      .child {
      flex: 1 0 calc(33% - 10px);
      margin: 5px;
      height: 80px;
      background-color: grey;
      }

      .animate {
      animation: changeColor 0.5s forwards;
      }

      @keyframes changeColor {
      0% {
      background-color: darkgrey;
      }
      100% {
      background-color: khaki;
      font-size: 60px;
      }
      }

      <div>
      <h1>Tic Tac Toe</h1>
      <h2>It is now the turn of: <span id="turn"></span></h2>
      <button id="clear">CLEAR</button>
      </div>
      <div class="parent">
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      <div class="child"></div>
      </div>






      javascript beginner css






      share|improve this question







      New contributor




      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 11 hours ago









      John Mc

      111




      111




      New contributor




      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      John Mc is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          0
          down vote













          Review



          Not bad for a beginner and welcome to the world of programing.



          As you are new to coding I will just focus on one aspect of your code. The naming (which is very poor). There are many other things that I had to resist changing, but did not want to overwhelm you with the technicalities of client side Javascript, CSS, DOM, and markup.



          Naming




          • Naming is very important, it gives meaning to code, data, and how it relates to the abstract concepts that make up a project. Bad naming will result in hard to read code, ambiguity and bugs.

          • Good naming is not easy and takes time to learn by experience and example. (Read other peoples code and pay attention to how they name things).

          • Good naming does not name what something is, but what it represents in the current context of the code.

          • Good naming means you don't have to fill your code with comments to explain what can not be deduced from the code. Though you have done well in your comments :)


          Some specific name examples.



          You have the variable children. Yes it is a list of children, that can be worked out by looking at how you declare its content, but in a bigger project there will be many children. The name does not represent what abstractly it holds, and that is board positions. If I ask What are the positions in a game of Tic Tac Toe?, you know what that means, as opposed to What are the children in a game of Tic Tac Toe? whaa! I have renamed children to positions



          You have done the same in the CSS and markup. The classes .child, .parent .animate have no connection to the abstraction of Tic Tac Toe. Better name may be .child is .position, .parent is .board, .animate is .playerMoved



          Most of the function names are good with the exception of childContent and clicked. Better names could be childContent as getPositonContent (as you use this function a lot in checkWinner a better name is getPos so that the code is not cluttered with a long name) and clicked as playerMove



          Refactoring your code.



          The rewrite is mostly just renaming the many poor names you used. There are also a few minor code changes. BTW the names I picked may not be what you would have used to represent the various abstracts, they are just examples.





          • turnDisplay created in load so you dont have to query the DOM each time.


          • playerMove gets the position element rather than the index.

          • The listener for clear is passed the function directly rather than use the indirect call addEventListener("click", function() { clearBoard() })

          • Changed some innerHTML references to textContent





          let turn = true;
          let positions, turnDisplay;
          let winnerFound = false;


          document.addEventListener('DOMContentLoaded', load);

          function load() {
          positions = document.getElementsByClassName("position");
          turnDisplay = document.getElementById("turnDisplay");
          for (let i = 0; i < positions.length; i++) {
          positions[i].addEventListener("click", function() {
          playerMove(positions[i])
          });
          }
          document.getElementById("clear").addEventListener("click", clearBoard);
          displayTurn();
          }

          function clearBoard() {
          for (let i = 0; i < positions.length; i++) {
          positions[i].innerHTML = '';
          positions[i].classList.remove('playerMoved');
          }
          turn = true;
          winnerFound = false;
          displayTurn();
          }

          function displayTurn() {
          if (turn) {
          turnDisplay.textContent = "X";
          } else {
          turnDisplay.textContent = "O";
          }
          }

          function playerMove(position) {
          if (winnerFound) {
          return
          }
          if (position.childElementCount !== 0) {
          return
          }
          const mark = document.createElement('div');
          if (turn) {
          mark.textContent = 'X'
          } else {
          mark.textContent = 'O'
          }
          position.appendChild(mark);
          position.classList.add('playerMoved');
          turn = !turn;
          checkWinner();
          displayTurn();
          }

          function checkWinner() {
          for (let x = 0; x < 9; x += 3) {
          if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
          alert(getPos(x) + " won!");
          winnerFound = true;
          }
          }
          for (let x = 0; x < 3; x += 1) {
          if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
          alert(getPos(x) + " won!");
          winnerFound = true;
          }
          }
          if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
          alert(getPos(0) + " won!");
          winnerFound = true;
          }
          if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
          alert(getPos(2) + " won!");
          winnerFound = true;
          }
          }

          function getPos(index) {
          if (positions[index].childElementCount === 0) {
          return index
          }
          return positions[index].textContent;
          }

          body {
          background: lightgray;
          text-align: center;
          vertical-align: middle;
          }

          .position:hover {
          background-color: darkgrey;
          }

          .board {
          display: inline-flex;
          flex-wrap: wrap;
          width: 400px;
          }

          .position {
          flex: 1 0 calc(33% - 10px);
          margin: 5px;
          height: 80px;
          background-color: grey;
          }

          .playerMoved {
          animation: changeColor 0.5s forwards;
          }

          @keyframes changeColor {
          0% {
          background-color: darkgrey;
          }
          100% {
          background-color: khaki;
          font-size: 60px;
          }
          }

          <div>
          <h1>Tic Tac Toe</h1>
          <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
          <button id="clear">CLEAR</button>
          </div>
          <div class="board">
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          <div class="position"></div>
          </div>





          Note: the above example is just concerned with naming, and does not represent an ideal code example. The idea was to keep as close to the OP's original code as possible.






          share|improve this answer





















            Your Answer





            StackExchange.ifUsing("editor", function () {
            return StackExchange.using("mathjaxEditing", function () {
            StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
            StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
            });
            });
            }, "mathjax-editing");

            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "196"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });






            John Mc is a new contributor. Be nice, and check out our Code of Conduct.










             

            draft saved


            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207842%2fmy-first-js-program-tic-tac-toe-game%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote













            Review



            Not bad for a beginner and welcome to the world of programing.



            As you are new to coding I will just focus on one aspect of your code. The naming (which is very poor). There are many other things that I had to resist changing, but did not want to overwhelm you with the technicalities of client side Javascript, CSS, DOM, and markup.



            Naming




            • Naming is very important, it gives meaning to code, data, and how it relates to the abstract concepts that make up a project. Bad naming will result in hard to read code, ambiguity and bugs.

            • Good naming is not easy and takes time to learn by experience and example. (Read other peoples code and pay attention to how they name things).

            • Good naming does not name what something is, but what it represents in the current context of the code.

            • Good naming means you don't have to fill your code with comments to explain what can not be deduced from the code. Though you have done well in your comments :)


            Some specific name examples.



            You have the variable children. Yes it is a list of children, that can be worked out by looking at how you declare its content, but in a bigger project there will be many children. The name does not represent what abstractly it holds, and that is board positions. If I ask What are the positions in a game of Tic Tac Toe?, you know what that means, as opposed to What are the children in a game of Tic Tac Toe? whaa! I have renamed children to positions



            You have done the same in the CSS and markup. The classes .child, .parent .animate have no connection to the abstraction of Tic Tac Toe. Better name may be .child is .position, .parent is .board, .animate is .playerMoved



            Most of the function names are good with the exception of childContent and clicked. Better names could be childContent as getPositonContent (as you use this function a lot in checkWinner a better name is getPos so that the code is not cluttered with a long name) and clicked as playerMove



            Refactoring your code.



            The rewrite is mostly just renaming the many poor names you used. There are also a few minor code changes. BTW the names I picked may not be what you would have used to represent the various abstracts, they are just examples.





            • turnDisplay created in load so you dont have to query the DOM each time.


            • playerMove gets the position element rather than the index.

            • The listener for clear is passed the function directly rather than use the indirect call addEventListener("click", function() { clearBoard() })

            • Changed some innerHTML references to textContent





            let turn = true;
            let positions, turnDisplay;
            let winnerFound = false;


            document.addEventListener('DOMContentLoaded', load);

            function load() {
            positions = document.getElementsByClassName("position");
            turnDisplay = document.getElementById("turnDisplay");
            for (let i = 0; i < positions.length; i++) {
            positions[i].addEventListener("click", function() {
            playerMove(positions[i])
            });
            }
            document.getElementById("clear").addEventListener("click", clearBoard);
            displayTurn();
            }

            function clearBoard() {
            for (let i = 0; i < positions.length; i++) {
            positions[i].innerHTML = '';
            positions[i].classList.remove('playerMoved');
            }
            turn = true;
            winnerFound = false;
            displayTurn();
            }

            function displayTurn() {
            if (turn) {
            turnDisplay.textContent = "X";
            } else {
            turnDisplay.textContent = "O";
            }
            }

            function playerMove(position) {
            if (winnerFound) {
            return
            }
            if (position.childElementCount !== 0) {
            return
            }
            const mark = document.createElement('div');
            if (turn) {
            mark.textContent = 'X'
            } else {
            mark.textContent = 'O'
            }
            position.appendChild(mark);
            position.classList.add('playerMoved');
            turn = !turn;
            checkWinner();
            displayTurn();
            }

            function checkWinner() {
            for (let x = 0; x < 9; x += 3) {
            if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
            alert(getPos(x) + " won!");
            winnerFound = true;
            }
            }
            for (let x = 0; x < 3; x += 1) {
            if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
            alert(getPos(x) + " won!");
            winnerFound = true;
            }
            }
            if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
            alert(getPos(0) + " won!");
            winnerFound = true;
            }
            if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
            alert(getPos(2) + " won!");
            winnerFound = true;
            }
            }

            function getPos(index) {
            if (positions[index].childElementCount === 0) {
            return index
            }
            return positions[index].textContent;
            }

            body {
            background: lightgray;
            text-align: center;
            vertical-align: middle;
            }

            .position:hover {
            background-color: darkgrey;
            }

            .board {
            display: inline-flex;
            flex-wrap: wrap;
            width: 400px;
            }

            .position {
            flex: 1 0 calc(33% - 10px);
            margin: 5px;
            height: 80px;
            background-color: grey;
            }

            .playerMoved {
            animation: changeColor 0.5s forwards;
            }

            @keyframes changeColor {
            0% {
            background-color: darkgrey;
            }
            100% {
            background-color: khaki;
            font-size: 60px;
            }
            }

            <div>
            <h1>Tic Tac Toe</h1>
            <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
            <button id="clear">CLEAR</button>
            </div>
            <div class="board">
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            <div class="position"></div>
            </div>





            Note: the above example is just concerned with naming, and does not represent an ideal code example. The idea was to keep as close to the OP's original code as possible.






            share|improve this answer

























              up vote
              0
              down vote













              Review



              Not bad for a beginner and welcome to the world of programing.



              As you are new to coding I will just focus on one aspect of your code. The naming (which is very poor). There are many other things that I had to resist changing, but did not want to overwhelm you with the technicalities of client side Javascript, CSS, DOM, and markup.



              Naming




              • Naming is very important, it gives meaning to code, data, and how it relates to the abstract concepts that make up a project. Bad naming will result in hard to read code, ambiguity and bugs.

              • Good naming is not easy and takes time to learn by experience and example. (Read other peoples code and pay attention to how they name things).

              • Good naming does not name what something is, but what it represents in the current context of the code.

              • Good naming means you don't have to fill your code with comments to explain what can not be deduced from the code. Though you have done well in your comments :)


              Some specific name examples.



              You have the variable children. Yes it is a list of children, that can be worked out by looking at how you declare its content, but in a bigger project there will be many children. The name does not represent what abstractly it holds, and that is board positions. If I ask What are the positions in a game of Tic Tac Toe?, you know what that means, as opposed to What are the children in a game of Tic Tac Toe? whaa! I have renamed children to positions



              You have done the same in the CSS and markup. The classes .child, .parent .animate have no connection to the abstraction of Tic Tac Toe. Better name may be .child is .position, .parent is .board, .animate is .playerMoved



              Most of the function names are good with the exception of childContent and clicked. Better names could be childContent as getPositonContent (as you use this function a lot in checkWinner a better name is getPos so that the code is not cluttered with a long name) and clicked as playerMove



              Refactoring your code.



              The rewrite is mostly just renaming the many poor names you used. There are also a few minor code changes. BTW the names I picked may not be what you would have used to represent the various abstracts, they are just examples.





              • turnDisplay created in load so you dont have to query the DOM each time.


              • playerMove gets the position element rather than the index.

              • The listener for clear is passed the function directly rather than use the indirect call addEventListener("click", function() { clearBoard() })

              • Changed some innerHTML references to textContent





              let turn = true;
              let positions, turnDisplay;
              let winnerFound = false;


              document.addEventListener('DOMContentLoaded', load);

              function load() {
              positions = document.getElementsByClassName("position");
              turnDisplay = document.getElementById("turnDisplay");
              for (let i = 0; i < positions.length; i++) {
              positions[i].addEventListener("click", function() {
              playerMove(positions[i])
              });
              }
              document.getElementById("clear").addEventListener("click", clearBoard);
              displayTurn();
              }

              function clearBoard() {
              for (let i = 0; i < positions.length; i++) {
              positions[i].innerHTML = '';
              positions[i].classList.remove('playerMoved');
              }
              turn = true;
              winnerFound = false;
              displayTurn();
              }

              function displayTurn() {
              if (turn) {
              turnDisplay.textContent = "X";
              } else {
              turnDisplay.textContent = "O";
              }
              }

              function playerMove(position) {
              if (winnerFound) {
              return
              }
              if (position.childElementCount !== 0) {
              return
              }
              const mark = document.createElement('div');
              if (turn) {
              mark.textContent = 'X'
              } else {
              mark.textContent = 'O'
              }
              position.appendChild(mark);
              position.classList.add('playerMoved');
              turn = !turn;
              checkWinner();
              displayTurn();
              }

              function checkWinner() {
              for (let x = 0; x < 9; x += 3) {
              if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
              alert(getPos(x) + " won!");
              winnerFound = true;
              }
              }
              for (let x = 0; x < 3; x += 1) {
              if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
              alert(getPos(x) + " won!");
              winnerFound = true;
              }
              }
              if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
              alert(getPos(0) + " won!");
              winnerFound = true;
              }
              if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
              alert(getPos(2) + " won!");
              winnerFound = true;
              }
              }

              function getPos(index) {
              if (positions[index].childElementCount === 0) {
              return index
              }
              return positions[index].textContent;
              }

              body {
              background: lightgray;
              text-align: center;
              vertical-align: middle;
              }

              .position:hover {
              background-color: darkgrey;
              }

              .board {
              display: inline-flex;
              flex-wrap: wrap;
              width: 400px;
              }

              .position {
              flex: 1 0 calc(33% - 10px);
              margin: 5px;
              height: 80px;
              background-color: grey;
              }

              .playerMoved {
              animation: changeColor 0.5s forwards;
              }

              @keyframes changeColor {
              0% {
              background-color: darkgrey;
              }
              100% {
              background-color: khaki;
              font-size: 60px;
              }
              }

              <div>
              <h1>Tic Tac Toe</h1>
              <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
              <button id="clear">CLEAR</button>
              </div>
              <div class="board">
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              <div class="position"></div>
              </div>





              Note: the above example is just concerned with naming, and does not represent an ideal code example. The idea was to keep as close to the OP's original code as possible.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                Review



                Not bad for a beginner and welcome to the world of programing.



                As you are new to coding I will just focus on one aspect of your code. The naming (which is very poor). There are many other things that I had to resist changing, but did not want to overwhelm you with the technicalities of client side Javascript, CSS, DOM, and markup.



                Naming




                • Naming is very important, it gives meaning to code, data, and how it relates to the abstract concepts that make up a project. Bad naming will result in hard to read code, ambiguity and bugs.

                • Good naming is not easy and takes time to learn by experience and example. (Read other peoples code and pay attention to how they name things).

                • Good naming does not name what something is, but what it represents in the current context of the code.

                • Good naming means you don't have to fill your code with comments to explain what can not be deduced from the code. Though you have done well in your comments :)


                Some specific name examples.



                You have the variable children. Yes it is a list of children, that can be worked out by looking at how you declare its content, but in a bigger project there will be many children. The name does not represent what abstractly it holds, and that is board positions. If I ask What are the positions in a game of Tic Tac Toe?, you know what that means, as opposed to What are the children in a game of Tic Tac Toe? whaa! I have renamed children to positions



                You have done the same in the CSS and markup. The classes .child, .parent .animate have no connection to the abstraction of Tic Tac Toe. Better name may be .child is .position, .parent is .board, .animate is .playerMoved



                Most of the function names are good with the exception of childContent and clicked. Better names could be childContent as getPositonContent (as you use this function a lot in checkWinner a better name is getPos so that the code is not cluttered with a long name) and clicked as playerMove



                Refactoring your code.



                The rewrite is mostly just renaming the many poor names you used. There are also a few minor code changes. BTW the names I picked may not be what you would have used to represent the various abstracts, they are just examples.





                • turnDisplay created in load so you dont have to query the DOM each time.


                • playerMove gets the position element rather than the index.

                • The listener for clear is passed the function directly rather than use the indirect call addEventListener("click", function() { clearBoard() })

                • Changed some innerHTML references to textContent





                let turn = true;
                let positions, turnDisplay;
                let winnerFound = false;


                document.addEventListener('DOMContentLoaded', load);

                function load() {
                positions = document.getElementsByClassName("position");
                turnDisplay = document.getElementById("turnDisplay");
                for (let i = 0; i < positions.length; i++) {
                positions[i].addEventListener("click", function() {
                playerMove(positions[i])
                });
                }
                document.getElementById("clear").addEventListener("click", clearBoard);
                displayTurn();
                }

                function clearBoard() {
                for (let i = 0; i < positions.length; i++) {
                positions[i].innerHTML = '';
                positions[i].classList.remove('playerMoved');
                }
                turn = true;
                winnerFound = false;
                displayTurn();
                }

                function displayTurn() {
                if (turn) {
                turnDisplay.textContent = "X";
                } else {
                turnDisplay.textContent = "O";
                }
                }

                function playerMove(position) {
                if (winnerFound) {
                return
                }
                if (position.childElementCount !== 0) {
                return
                }
                const mark = document.createElement('div');
                if (turn) {
                mark.textContent = 'X'
                } else {
                mark.textContent = 'O'
                }
                position.appendChild(mark);
                position.classList.add('playerMoved');
                turn = !turn;
                checkWinner();
                displayTurn();
                }

                function checkWinner() {
                for (let x = 0; x < 9; x += 3) {
                if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                for (let x = 0; x < 3; x += 1) {
                if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
                alert(getPos(0) + " won!");
                winnerFound = true;
                }
                if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
                alert(getPos(2) + " won!");
                winnerFound = true;
                }
                }

                function getPos(index) {
                if (positions[index].childElementCount === 0) {
                return index
                }
                return positions[index].textContent;
                }

                body {
                background: lightgray;
                text-align: center;
                vertical-align: middle;
                }

                .position:hover {
                background-color: darkgrey;
                }

                .board {
                display: inline-flex;
                flex-wrap: wrap;
                width: 400px;
                }

                .position {
                flex: 1 0 calc(33% - 10px);
                margin: 5px;
                height: 80px;
                background-color: grey;
                }

                .playerMoved {
                animation: changeColor 0.5s forwards;
                }

                @keyframes changeColor {
                0% {
                background-color: darkgrey;
                }
                100% {
                background-color: khaki;
                font-size: 60px;
                }
                }

                <div>
                <h1>Tic Tac Toe</h1>
                <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
                <button id="clear">CLEAR</button>
                </div>
                <div class="board">
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                </div>





                Note: the above example is just concerned with naming, and does not represent an ideal code example. The idea was to keep as close to the OP's original code as possible.






                share|improve this answer












                Review



                Not bad for a beginner and welcome to the world of programing.



                As you are new to coding I will just focus on one aspect of your code. The naming (which is very poor). There are many other things that I had to resist changing, but did not want to overwhelm you with the technicalities of client side Javascript, CSS, DOM, and markup.



                Naming




                • Naming is very important, it gives meaning to code, data, and how it relates to the abstract concepts that make up a project. Bad naming will result in hard to read code, ambiguity and bugs.

                • Good naming is not easy and takes time to learn by experience and example. (Read other peoples code and pay attention to how they name things).

                • Good naming does not name what something is, but what it represents in the current context of the code.

                • Good naming means you don't have to fill your code with comments to explain what can not be deduced from the code. Though you have done well in your comments :)


                Some specific name examples.



                You have the variable children. Yes it is a list of children, that can be worked out by looking at how you declare its content, but in a bigger project there will be many children. The name does not represent what abstractly it holds, and that is board positions. If I ask What are the positions in a game of Tic Tac Toe?, you know what that means, as opposed to What are the children in a game of Tic Tac Toe? whaa! I have renamed children to positions



                You have done the same in the CSS and markup. The classes .child, .parent .animate have no connection to the abstraction of Tic Tac Toe. Better name may be .child is .position, .parent is .board, .animate is .playerMoved



                Most of the function names are good with the exception of childContent and clicked. Better names could be childContent as getPositonContent (as you use this function a lot in checkWinner a better name is getPos so that the code is not cluttered with a long name) and clicked as playerMove



                Refactoring your code.



                The rewrite is mostly just renaming the many poor names you used. There are also a few minor code changes. BTW the names I picked may not be what you would have used to represent the various abstracts, they are just examples.





                • turnDisplay created in load so you dont have to query the DOM each time.


                • playerMove gets the position element rather than the index.

                • The listener for clear is passed the function directly rather than use the indirect call addEventListener("click", function() { clearBoard() })

                • Changed some innerHTML references to textContent





                let turn = true;
                let positions, turnDisplay;
                let winnerFound = false;


                document.addEventListener('DOMContentLoaded', load);

                function load() {
                positions = document.getElementsByClassName("position");
                turnDisplay = document.getElementById("turnDisplay");
                for (let i = 0; i < positions.length; i++) {
                positions[i].addEventListener("click", function() {
                playerMove(positions[i])
                });
                }
                document.getElementById("clear").addEventListener("click", clearBoard);
                displayTurn();
                }

                function clearBoard() {
                for (let i = 0; i < positions.length; i++) {
                positions[i].innerHTML = '';
                positions[i].classList.remove('playerMoved');
                }
                turn = true;
                winnerFound = false;
                displayTurn();
                }

                function displayTurn() {
                if (turn) {
                turnDisplay.textContent = "X";
                } else {
                turnDisplay.textContent = "O";
                }
                }

                function playerMove(position) {
                if (winnerFound) {
                return
                }
                if (position.childElementCount !== 0) {
                return
                }
                const mark = document.createElement('div');
                if (turn) {
                mark.textContent = 'X'
                } else {
                mark.textContent = 'O'
                }
                position.appendChild(mark);
                position.classList.add('playerMoved');
                turn = !turn;
                checkWinner();
                displayTurn();
                }

                function checkWinner() {
                for (let x = 0; x < 9; x += 3) {
                if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                for (let x = 0; x < 3; x += 1) {
                if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
                alert(getPos(0) + " won!");
                winnerFound = true;
                }
                if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
                alert(getPos(2) + " won!");
                winnerFound = true;
                }
                }

                function getPos(index) {
                if (positions[index].childElementCount === 0) {
                return index
                }
                return positions[index].textContent;
                }

                body {
                background: lightgray;
                text-align: center;
                vertical-align: middle;
                }

                .position:hover {
                background-color: darkgrey;
                }

                .board {
                display: inline-flex;
                flex-wrap: wrap;
                width: 400px;
                }

                .position {
                flex: 1 0 calc(33% - 10px);
                margin: 5px;
                height: 80px;
                background-color: grey;
                }

                .playerMoved {
                animation: changeColor 0.5s forwards;
                }

                @keyframes changeColor {
                0% {
                background-color: darkgrey;
                }
                100% {
                background-color: khaki;
                font-size: 60px;
                }
                }

                <div>
                <h1>Tic Tac Toe</h1>
                <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
                <button id="clear">CLEAR</button>
                </div>
                <div class="board">
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                </div>





                Note: the above example is just concerned with naming, and does not represent an ideal code example. The idea was to keep as close to the OP's original code as possible.






                let turn = true;
                let positions, turnDisplay;
                let winnerFound = false;


                document.addEventListener('DOMContentLoaded', load);

                function load() {
                positions = document.getElementsByClassName("position");
                turnDisplay = document.getElementById("turnDisplay");
                for (let i = 0; i < positions.length; i++) {
                positions[i].addEventListener("click", function() {
                playerMove(positions[i])
                });
                }
                document.getElementById("clear").addEventListener("click", clearBoard);
                displayTurn();
                }

                function clearBoard() {
                for (let i = 0; i < positions.length; i++) {
                positions[i].innerHTML = '';
                positions[i].classList.remove('playerMoved');
                }
                turn = true;
                winnerFound = false;
                displayTurn();
                }

                function displayTurn() {
                if (turn) {
                turnDisplay.textContent = "X";
                } else {
                turnDisplay.textContent = "O";
                }
                }

                function playerMove(position) {
                if (winnerFound) {
                return
                }
                if (position.childElementCount !== 0) {
                return
                }
                const mark = document.createElement('div');
                if (turn) {
                mark.textContent = 'X'
                } else {
                mark.textContent = 'O'
                }
                position.appendChild(mark);
                position.classList.add('playerMoved');
                turn = !turn;
                checkWinner();
                displayTurn();
                }

                function checkWinner() {
                for (let x = 0; x < 9; x += 3) {
                if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                for (let x = 0; x < 3; x += 1) {
                if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
                alert(getPos(0) + " won!");
                winnerFound = true;
                }
                if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
                alert(getPos(2) + " won!");
                winnerFound = true;
                }
                }

                function getPos(index) {
                if (positions[index].childElementCount === 0) {
                return index
                }
                return positions[index].textContent;
                }

                body {
                background: lightgray;
                text-align: center;
                vertical-align: middle;
                }

                .position:hover {
                background-color: darkgrey;
                }

                .board {
                display: inline-flex;
                flex-wrap: wrap;
                width: 400px;
                }

                .position {
                flex: 1 0 calc(33% - 10px);
                margin: 5px;
                height: 80px;
                background-color: grey;
                }

                .playerMoved {
                animation: changeColor 0.5s forwards;
                }

                @keyframes changeColor {
                0% {
                background-color: darkgrey;
                }
                100% {
                background-color: khaki;
                font-size: 60px;
                }
                }

                <div>
                <h1>Tic Tac Toe</h1>
                <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
                <button id="clear">CLEAR</button>
                </div>
                <div class="board">
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                </div>





                let turn = true;
                let positions, turnDisplay;
                let winnerFound = false;


                document.addEventListener('DOMContentLoaded', load);

                function load() {
                positions = document.getElementsByClassName("position");
                turnDisplay = document.getElementById("turnDisplay");
                for (let i = 0; i < positions.length; i++) {
                positions[i].addEventListener("click", function() {
                playerMove(positions[i])
                });
                }
                document.getElementById("clear").addEventListener("click", clearBoard);
                displayTurn();
                }

                function clearBoard() {
                for (let i = 0; i < positions.length; i++) {
                positions[i].innerHTML = '';
                positions[i].classList.remove('playerMoved');
                }
                turn = true;
                winnerFound = false;
                displayTurn();
                }

                function displayTurn() {
                if (turn) {
                turnDisplay.textContent = "X";
                } else {
                turnDisplay.textContent = "O";
                }
                }

                function playerMove(position) {
                if (winnerFound) {
                return
                }
                if (position.childElementCount !== 0) {
                return
                }
                const mark = document.createElement('div');
                if (turn) {
                mark.textContent = 'X'
                } else {
                mark.textContent = 'O'
                }
                position.appendChild(mark);
                position.classList.add('playerMoved');
                turn = !turn;
                checkWinner();
                displayTurn();
                }

                function checkWinner() {
                for (let x = 0; x < 9; x += 3) {
                if (getPos(x) === getPos(x + 1) && getPos(x) === getPos(x + 2)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                for (let x = 0; x < 3; x += 1) {
                if (getPos(x) === getPos(x + 3) && getPos(x) === getPos(x + 6)) {
                alert(getPos(x) + " won!");
                winnerFound = true;
                }
                }
                if (getPos(0) === getPos(4) && getPos(0) === getPos(8)) {
                alert(getPos(0) + " won!");
                winnerFound = true;
                }
                if (getPos(2) === getPos(4) && getPos(2) === getPos(6)) {
                alert(getPos(2) + " won!");
                winnerFound = true;
                }
                }

                function getPos(index) {
                if (positions[index].childElementCount === 0) {
                return index
                }
                return positions[index].textContent;
                }

                body {
                background: lightgray;
                text-align: center;
                vertical-align: middle;
                }

                .position:hover {
                background-color: darkgrey;
                }

                .board {
                display: inline-flex;
                flex-wrap: wrap;
                width: 400px;
                }

                .position {
                flex: 1 0 calc(33% - 10px);
                margin: 5px;
                height: 80px;
                background-color: grey;
                }

                .playerMoved {
                animation: changeColor 0.5s forwards;
                }

                @keyframes changeColor {
                0% {
                background-color: darkgrey;
                }
                100% {
                background-color: khaki;
                font-size: 60px;
                }
                }

                <div>
                <h1>Tic Tac Toe</h1>
                <h2>It is now the turn of: <span id="turnDisplay"></span></h2>
                <button id="clear">CLEAR</button>
                </div>
                <div class="board">
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                <div class="position"></div>
                </div>






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered 3 hours ago









                Blindman67

                6,4041521




                6,4041521






















                    John Mc is a new contributor. Be nice, and check out our Code of Conduct.










                     

                    draft saved


                    draft discarded


















                    John Mc is a new contributor. Be nice, and check out our Code of Conduct.













                    John Mc is a new contributor. Be nice, and check out our Code of Conduct.












                    John Mc is a new contributor. Be nice, and check out our Code of Conduct.















                     


                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f207842%2fmy-first-js-program-tic-tac-toe-game%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Costa Masnaga

                    Fotorealismo

                    Sidney Franklin