Javascript 井字游戏在未选择获胜连击时不显示平局

Javascript Tic Tac Toe Game does not display Tie whenever win combos are not chosen

我正在使用 javascript 的立即调用函数元素 (IIFE) 创建 Tic Tac Toe 游戏。到目前为止,我已经成功地创建了带有 CSS 和 HTML 的游戏板,并且还成功地获得了根据标志识别获胜者的游戏。我还能够创建重置功能。然而,我的问题是,当找到 none 个组合时,我无法弄清楚如何对逻辑进行编程以显示平局。经常发生的情况是,每当我尝试对平局的逻辑进行编程时,它会在第一次单击游戏板上时显示平局。谁能帮我解决这个问题!

    const gameBoard = (() =>{        
        const sectors = document.querySelectorAll(".sector");
        
        let sector = Array.from(sectors);
        const winner = [
            [0,1,2],
            [3,4,5],
            [6,7,8],
            [0,3,6],
            [1,4,7],
            [2,5,8],
            [0,4,8],
            [2,4,6]
        ];

        let choice = "X"; 
                
        const gamePlay = () =>{
            const count = () => sector.forEach((val, index)=>{
                val.addEventListener('click',()=>{
                    if(val.textContent === choice){
                        index += 1;
                    }else{
                        index = 0;
                    }
                })
                
            })
            const move = () =>{                
                sector.forEach((mark)=>{
                    mark.addEventListener("click",()=>{
                        if(mark.textContent === ""){                                            
                        choice = choice === "X"?"O":"X";
                        mark.textContent = choice;
                        gameWinner();
                        }                                               
                    })
                })                
            }
            move()
            const resetGame = () =>{
                const reset = document.querySelector("#reset");
                reset.addEventListener('click',()=>{
                    sector.forEach((mark) =>{
                        mark.textContent = "";
                    })
                })
            }
            resetGame();           
            const gameWinner = () =>{
                winner.forEach((combo)=>{
                    let checkWinner = combo.every(idx =>
                        sector[idx].textContent === choice)
                    if(checkWinner){
                        alert(choice + " has won!");
                    }else if(count() <= winner.length && !checkWinner){
                        alert('tie');
                    }
                })                               
            }            
        }
        const players = (player1, player2, machine)=>{
            
        }
        return {gamePlay};       
    })();
    gameBoard.gamePlay();
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Tic-Tac-Toe</title>
        <script src="game.js" defer></script>
        <link rel="stylesheet" href="layout.css">
    </head>
    <body>
        <header id="title">Tic-Tac-Toe</header>
        <main>
            <!--<div id="playerSelection">
                <p>Select Your Mark</p>
                <button id="x">X</button><button id="o">O</button>
            </div>-->
            <div id="board">
                <div id = "one" class="sector"></div>
                <div id = "two" class="sector"></div>
                <div id = "three" class="sector"></div>
                <div id = "four" class="sector"></div>
                <div id = "five" class="sector"></div>
                <div id = "six" class="sector"></div>
                <div id = "seven"class="sector"></div>
                <div id = "eight" class="sector"></div>
                <div id = "nine" class="sector"></div>
            </div>
            <button id="reset">Reset</button>            
        </main>
    </body>
</html>
#title{
    display:flex;
    align-items: center;
    justify-content: center;
}
#board{
    display:grid;
    grid-template-columns: 100px 100px 100px;
    grid-template-rows: 100px 100px 100px;
    grid-gap:10px;
    background-color: darkblue;
    width:320px;
    height:320px;
}
.sector{
    background-color: cadetblue;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 50px;
}
#playerSelection{
    display:flex;
    flex-direction: column;
    justify-content: center;
}
main{
    display:flex;
    flex-direction:column;
    align-items: center;
    justify-content: center;
}

一些问题:

  • count 正在绑定事件侦听器。它不算什么。当这些事件被触发时(当被点击时)一些事情就完成了,但那是无用的。 index 增量不会有任何影响,因为这个变量除了递增和重置之外从未用于任何其他用途。最后,count() 总是 returns undefined,因为这就是 forEach 旨在 return 的目的。而是定义一个函数 boardIsFull:

    const boardIsFull = () => sector.every((val) => val.textContent != "");
    
  • gameWinner 正在为 每个 组合调用 count()。当然,平局状态不依赖于正在验证的组合,因此平局检查应该只发生一次。以下是定义此函数的方法:

    const gameWinner = () => {
        let checkWinner = winner.find((combo) => 
            combo.every(idx => sector[idx].textContent === choice)
        );
        if (checkWinner) {
            alert(choice + " has won!");
        } else if(boardIsFull()) {
            alert('tie');
        }
    };            
    

您应该进一步改进您的代码,以避免在玩家已经做出获胜连击后继续游戏。

然后您可以添加更多功能,例如计算移动的算法,这样您就可以与“计算机”对手对战。有关此类实现,请参阅 this answer