Tic Tac Toe project: JavaScript / jQuery question

Tic Tac Toe project: JavaScript / jQuery question
0.0 0

#1

I’m working on the Advanced Front End Development Tic Tac Toe Project and am hitting what feels like is probably a simple-to-solve problem but I can’t find any documentation on it in my searches.

Basically, I have my script coded to append an image (the ‘player-icon’) to the div when the user clicks on a given box. Then the computer plays. The unexpected behavior is that when the player clicks their next box selection, the first image is removed and a new one is placed. How can I get their previous icons to stay so that all of their moves are reflected on the board for the duration of the match? The icon being removed with each click means that the class for the box being ‘taken’ is also removed and would impact the logic I was planning to implement for my AI. (I am also tracking their moves in an array so that class being removed is not the end of the world from a logic standpoint. But the icon disappearing does greatly affect the UX and is unacceptable for expected gameplay.)

HTML in question (just for game board, let me know if you need to see more in order to answer):

<div class="row justify-content-center">                
                <div class="game-display game-board hidden">   
                    <div class="d-flex flex-row justify-content-center">  
                        <div class="boxes right bottom" id="box1">
                        </div>
                        <div class="boxes right bottom" id="box2">
                        </div>
                        <div class="boxes bottom" id="box3">
                        </div>
                    </div> 

                    <div class="d-flex flex-row justify-content-center"> 
                        <div class="boxes right bottom" id="box4">
                        </div>
                        <div class="boxes right bottom" id="box5">
                        </div>
                        <div class="boxes bottom" id="box6">
                        </div>
                    </div>    

                    <div class="d-flex flex-row justify-content-center align-items-center">  
                        <div class="boxes right" id="box7">
                        </div>
                        <div class="boxes right" id="box8">
                        </div>
                        <div class="boxes" id="box9">
                        </div>
                    </div>
                </div>
            </div>

JavaScript / jQuery:

/* user play functionality to display icon */ 
    $('.boxes').on('click', function() {

          /* to track which boxes the user has played */ 
        var boxID = this.id;
        userSquaresArr.push(boxID);
        console.log(userSquaresArr);

         /* to mark the box with the correct icon and mark the box 'taken' */ 
        if (userIcon === 'X') {
            $(this)
                .append(cross)
                .addClass('taken');

         /* changes flags to indicate player or computer's turn */  
            $('#x-turn').addClass('hidden');
            $('#o-turn').removeClass('hidden');
 
        /* to keep track of how many boxes have been played */ 
            boxCount++; 

       /* to tell computer to play */ 
            DeterminePlayer();
            return boxCount;
        } else {
            $(this)
                .append(circle)
                .addClass('taken');
            $('#o-turn').addClass('hidden');
            $('#x-turn').removeClass('hidden');
            boxCount++; 
            DeterminePlayer();
            return boxCount; 
        }
    });

I think that should be enough to help determine my issue, but if you need more code, let me know.

Thank you in advance for any suggestions.


#2

I think I managed to solve my problem while working on another issue. :smile:

I wanted there to be a delay in the computer’s move being displayed. Using the append() method was not allowing this behavior (no way to set a timer on that method that I am aware of). So I changed the coding of my HTML to include both player icons hidden on the board. Then rescripted the JavaScript/jQuery so that once the user or computer plays that box, the icon fades in. Since the icons are already present, they can not be removed on additional user clicks.

If anyone has an explanation of how to make an appended HTML element permanent, I would still be curious to hear it. Thanks so much.

new HTML:

<div class="row justify-content-center">                
                <div class="game-display game-board hidden">   
                    <div class="d-flex flex-row justify-content-center">  
                        <div class="boxes right bottom" id="box1">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes right bottom" id="box2">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes bottom" id="box3">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                    </div> 

                    <div class="d-flex flex-row justify-content-center"> 
                        <div class="boxes right bottom" id="box4">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes right bottom" id="box5">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes bottom" id="box6">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                    </div>    

                    <div class="d-flex flex-row justify-content-center align-items-center">  
                        <div class="boxes right" id="box7">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes right" id="box8">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                        <div class="boxes" id="box9">
                            <img class="player-icon-x player-icon hidden" src="cross-small.png" alt="small cross icon">
                            <img class="player-icon-o player-icon hidden" src="circle-outline-128.png" alt="small circle icon">
                        </div>
                    </div>
                </div>
            </div>

revised JavaScript:

 /* user play functionality to display icon */ 
    $('.boxes').on('click', function() {

         /* to track which boxes the user has played */
        var boxID = this.id;
        userSquaresArr.push(boxID);
        console.log(userSquaresArr);

         /* to mark the box with the correct icon and mark the box 'taken' */  
        if (userIcon === 'X') {
            $(this)
                .children('.player-icon-x')
                .fadeIn(500)
                .addClass('taken');
           
            /* changes flags to indicate player or computer's turn */ 
            $('#x-turn').addClass('hidden');
            $('#o-turn').fadeIn(800);
  
            /* to keep track of how many boxes have been played */ 
            boxCount++; 

            /* to tell computer to play */
            DeterminePlayer();
            return boxCount;
        } else {
            $(this)
                .children('.player-icon-o')
                .fadeIn(500)
                .addClass('taken');
            $('#o-turn').addClass('hidden');
            $('#x-turn').fadeIn(800);
            boxCount++; 
            DeterminePlayer();
            return boxCount; 
        }
    });

#3

Would you mine posting your CSS (everything is hidden) or just post a link to your entire code, so we can see what is going on?


#4

Thank you for looking at my code.
The full repo is here: GitHub Repo for my Tic Tac Toe project

If you go back to commits on Feb 22, you can see the code I was working with at the time I submitted the question. The most recent commits (from Feb 24) have the alterations I outline above that corrected the problem I was encountering.