Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

tic tac toe game

Trying to get it so that when I click on an X or an O on the grid it doesn't get overwritten with an opposite value. So if I put X on the grid and click that same space an O will not take it's place.

This my code.

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Tic Tac Toe</title>
    <link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
    <link rel="stylesheet" href="css/normalize.css">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="board" id="board">
  <header>
    <h1>Tic Tac Toe</h1>
    <ul>
      <li class="players" id="player1">
        <svg xmlns="http://www.w3.org/2000/svg" width="42" height="42" viewBox="0 0 42 42" version="1.1"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-200.000000, -60.000000)" fill="#000000"><g transform="translate(200.000000, 60.000000)"><path d="M21 36.6L21 36.6C29.6 36.6 36.6 29.6 36.6 21 36.6 12.4 29.6 5.4 21 5.4 12.4 5.4 5.4 12.4 5.4 21 5.4 29.6 12.4 36.6 21 36.6L21 36.6ZM21 42L21 42C9.4 42 0 32.6 0 21 0 9.4 9.4 0 21 0 32.6 0 42 9.4 42 21 42 32.6 32.6 42 21 42L21 42Z"/></g></g></g></svg>
      </li>
      <li class="players " id="player2">
        <svg xmlns="http://www.w3.org/2000/svg" width="42" height="43" viewBox="0 0 42 43" version="1.1"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g transform="translate(-718.000000, -60.000000)" fill="#000000"><g transform="translate(739.500000, 81.500000) rotate(-45.000000) translate(-739.500000, -81.500000) translate(712.000000, 54.000000)"><path d="M30 30.1L30 52.5C30 53.6 29.1 54.5 28 54.5L25.5 54.5C24.4 54.5 23.5 53.6 23.5 52.5L23.5 30.1 2 30.1C0.9 30.1 0 29.2 0 28.1L0 25.6C0 24.5 0.9 23.6 2 23.6L23.5 23.6 23.5 2.1C23.5 1 24.4 0.1 25.5 0.1L28 0.1C29.1 0.1 30 1 30 2.1L30 23.6 52.4 23.6C53.5 23.6 54.4 24.5 54.4 25.6L54.4 28.1C54.4 29.2 53.5 30.1 52.4 30.1L30 30.1Z"/></g></g></g></svg>
      </li>
    </ul>
  </header>
  <ul class="boxes">
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li>
    <li class="box"></li> 
    <li class="box"></li>
  </ul>
</div>

<script src="app.js"></script> 
</body>
</html>

JS

const boxes = document.querySelector(".boxes");
const player1 = document.getElementById("player1");
const player2 = document.getElementById("player2");
const li = document.getElementsByClassName("box")
player1.classList.add("active");



boxes.addEventListener("click", (e) => {


if (li.className !== "box-filled-1" || li.className !== "box-filled-2"  ){

    if (player1.classList.contains("active")){
     if (e.target.tagName == "LI" ) {   
   e.target.classList.add("box-filled-1");

    player1.classList.remove('active');
    player2.classList.add('active');

    }}

     else if (player2.classList.contains("active")){
     if (e.target.tagName == "LI" ) {   
   e.target.classList.add("box-filled-2");
    player2.classList.remove('active');
    player1.classList.add('active');}}

}


}); 




boxes.addEventListener("mouseout", (e) => {


 if (player1.classList.contains("active")){
  if (e.target.tagName == "LI") {
 e.target.style.backgroundImage = "";}}

    else if (player2.classList.contains("active")){
  if (e.target.tagName == "LI") {
    e.target.style.backgroundImage = "";}}


    });



boxes.addEventListener("mouseover", (e) => {

   if (player1.classList.contains("active")){
   if (e.target.tagName == "LI") {
   e.target.style.backgroundImage = "url(img/o.svg)";}}



  else if (player2.classList.contains("active")){
   if (e.target.tagName == "LI") {
  e.target.style.backgroundImage = "url(img/x.svg)";}}



  if(e.target.classList.contains("box-filled-1")){
    if (e.target.tagName == "LI") {
  e.target.style.backgroundImage = ""}}

    else if(e.target.classList.contains("box-filled-2")){
    if (e.target.tagName == "LI") {
            e.target.style.backgroundImage = ""}}
});

The probelm may be the overarching if statement

if (li.className !== "box-filled-1" || li.className !== "box-filled-2"  )

Or possibly something to do with the mouseout event, I've been stuck on this for a while now. If anyone can help that'd be great :)

1 Answer

Steven Parker
Steven Parker
229,657 Points

You've already identified a problem.

This test expression:

if (li.className !== "box-filled-1" || li.className !== "box-filled-2")

Combining two inequality tests on the same property using OR logic will always be true. Just think about it — no matter what the value is, it won't be equal to at least one of the two literals.

If you intended to test if neither is true, you'll need to combine them with AND logic ("&&"). But it looks like your elements might have more than one class at a time, so you'll need a more sophisticated test anyway.

Neil Bircumshaw
seal-mask
.a{fill-rule:evenodd;}techdegree
Neil Bircumshaw
Full Stack JavaScript Techdegree Student 14,597 Points

I think taking a break and looking at the code the next day really helps sometimes.

if(e.target.className !== "box box-filled-1" &&  e.target.className !== "box box-filled-2"  )

This seemed to do the trick. Thanks for having my back yet again Steven.