Javascript 代码有效,但不是立即有效

Javascript code works, but not immediately

我试着写了一个简单的井字游戏。当我编码时遇到一个奇怪的“错误”我会说?名为“isWinner”的函数检查是否有人赢了。它将一个名为“winningCombinations”的数组与它获得的组合进行比较。问题是代码在找到获胜组合后应立即显示“winner chicken dinner”。好吧,它没有。它在 3 个额外的动作后显示出来。我不知道出了什么问题,所以我会很感激任何帮助。提前致谢。哦,这是代码:

代码笔: https://codepen.io/vivmaha/pen/abJNBzX

const turndiv = document.getElementById('turn');
const board = document.getElementById('board');
const boxes = document.querySelectorAll('.boxes');

const winningCombinations = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [1, 4, 7],
    [2, 5, 8],
    [3, 6, 9],
    [1, 5, 9],
    [3, 5, 7]
];

let claimedcells = new Array();
let xturn = true;

/* Those variables will have X and O combinations separetly */

let xcombination = new Array();
let ocombination = new Array();
let turn = xcombination;

/* Add event listeners to every cell */

boxes.forEach(cell => {
    cell.addEventListener('click', handleCellClick);
});

/* Handles cell, at this stage is confirmed, that this cell has ben clicked for first time */

function handleCellPlayed(cell, value) {
    if(xturn) {
        cell.textContent = 'x';
        xturn = false;
        xcombination.push(value);
    }
    else {
        cell.textContent = 'o';
        xturn = true;
        ocombination.push(value);
    }
}

/* Handles click on any cell */

function handleCellClick() {

    if(xturn) {
        if(isWinner(xcombination)) {
            alert('winner chicken dinner');
        }
    }
    else if(isWinner(ocombination)) {
            alert('winner chicken dinner');
    }

    let clickedcell = this.getAttribute('value');

    let freeCell = isCellFree(clickedcell);

    if(freeCell) {

        handleCellPlayed(this, this.getAttribute('value'));
        
        claimedcells.push(clickedcell);
    }
    
}

/* Checks is Cell free */

function isCellFree(cell) {

    let freeCell = true;

    for(i=0; i<claimedcells.length; i++) {

        let claimedcell = claimedcells[i];

        if(cell == claimedcell) {
            freeCell = false;
        }

    }

    return freeCell;
}

/* Check if game has winner */

function isWinner(usercombination) {

    let winner = false;

    winningCombinations.forEach(combination => {

        let a = combination[0] + "";
        let b = combination[1] + "";
        let c = combination[2] + "";

        if(usercombination.includes(a) && usercombination.includes(b) && usercombination.includes(c)) {
            winner = true;
        }

    });

    return winner;
}
body {
    background-color:azure;
}

.container {
    min-width: 100%;
    min-height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

#gameholder {
    width: 30vw;
    background-color: beige;
    padding: 10px;
    text-align: center;
}

#board {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    flex-basis: 33.333333%;
    text-transform: uppercase;
    font-weight: bold;
    font-size: 100px;
}

.boxes {
    width: 31%;
    height: 8vw;
    border: 0.5px black solid;
}

.boxes:first-child, .boxes:nth-child(2), .boxes:nth-child(3) {
    border-top: none;
}

.boxes:first-child, .boxes:nth-child(4), .boxes:nth-child(7) {
    border-left: none;
}

.boxes:nth-child(7), .boxes:nth-child(8), .boxes:nth-child(9) {
    border-bottom: none;
}

.boxes:nth-child(3),
.boxes:nth-child(6),
.boxes:nth-child(9) {
    border-right: none;
}
<body>
    <div class="container">
        <div id="gameholder">
            <!-------Current turn-------------->
            <div id="turn">
                <h1>X turn!</h1>
            </div>

            <!--- Game board --->
            <div id="board">
                <div class="boxes" value='1'></div>
                <div class="boxes" value='2'></div>
                <div class="boxes" value='3'></div>
                <div class="boxes" value='4'></div>
                <div class="boxes" value='5'></div>
                <div class="boxes" value='6'></div>
                <div class="boxes" value='7'></div>
                <div class="boxes" value='8'></div>
                <div class="boxes" value='9'></div>
            </div>

            <div id="time"></div>
        </div>
    </div>

    <script src="game.js" async></script>
</body>

您的 handleCellClick 功能会在执行任何其他操作之前测试获胜者。

所以我点击了“X”,代码进入并检查获胜者(目前还没有)。然后它更新所有内容,然后轮到 o,它进来并检查 O 的获胜者,什么都没有。然后它更新所有内容,然后再次 X 转它检查获胜者,现在它响应 true。

您需要将获胜者支票移至处理完剩余的点击之后。

这里有 2 个问题,

  1. 您在放置标记之前进行了 isWinner 检查
  2. 您在检查之前更改了 xturn。

下面我已经修改以解决这两个问题。

我做了一个简单的 xturn = !xturn; 来翻转用户是否赢了。

const turndiv = document.getElementById('turn');
const board = document.getElementById('board');
const boxes = document.querySelectorAll('.boxes');

const winningCombinations = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
    [1, 4, 7],
    [2, 5, 8],
    [3, 6, 9],
    [1, 5, 9],
    [3, 5, 7]
];

let claimedcells = new Array();
let xturn = true;

/* Those variables will have X and O combinations separetly */

let xcombination = new Array();
let ocombination = new Array();
let turn = xcombination;

/* Add event listeners to every cell */

boxes.forEach(cell => {
    cell.addEventListener('click', handleCellClick);
});

/* Handles cell, at this stage is confirmed, that this cell has ben clicked for first time */

function handleCellPlayed(cell, value) {
    if(xturn) {
        cell.textContent = 'x';
        //xturn = false;
        xcombination.push(value);
    }
    else {
        cell.textContent = 'o';
        //xturn = true;
        ocombination.push(value);
    }
}

/* Handles click on any cell */

function handleCellClick() {

 

    let clickedcell = this.getAttribute('value');

    let freeCell = isCellFree(clickedcell);

    if(freeCell) {

        handleCellPlayed(this, this.getAttribute('value'));
        if(xturn) {
          if(isWinner(xcombination)) {
             alert('winner chicken dinner');
          }
        }
        else if(isWinner(ocombination)) {
          alert('winner chicken dinner');
        }
        xturn = !xturn;
        claimedcells.push(clickedcell);
    }
    
}

/* Checks is Cell free */

function isCellFree(cell) {

    let freeCell = true;

    for(i=0; i<claimedcells.length; i++) {

        let claimedcell = claimedcells[i];

        if(cell == claimedcell) {
            freeCell = false;
        }

    }

    return freeCell;
}

/* Check if game has winner */

function isWinner(usercombination) {

    let winner = false;

    winningCombinations.forEach(combination => {

        let a = combination[0] + "";
        let b = combination[1] + "";
        let c = combination[2] + "";

        if(usercombination.includes(a) && usercombination.includes(b) && usercombination.includes(c)) {
            winner = true;
        }

    });

    return winner;
}
body {
    background-color:azure;
}

.container {
    min-width: 100%;
    min-height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

#gameholder {
    width: 30vw;
    background-color: beige;
    padding: 10px;
    text-align: center;
}

#board {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    flex-basis: 33.333333%;
    text-transform: uppercase;
    font-weight: bold;
    font-size: 100px;
}

.boxes {
    width: 31%;
    height: 8vw;
    border: 0.5px black solid;
}

.boxes:first-child, .boxes:nth-child(2), .boxes:nth-child(3) {
    border-top: none;
}

.boxes:first-child, .boxes:nth-child(4), .boxes:nth-child(7) {
    border-left: none;
}

.boxes:nth-child(7), .boxes:nth-child(8), .boxes:nth-child(9) {
    border-bottom: none;
}

.boxes:nth-child(3),
.boxes:nth-child(6),
.boxes:nth-child(9) {
    border-right: none;
}
<body>
    <div class="container">
        <div id="gameholder">
            <!-------Current turn-------------->
            <div id="turn">
                <h1>X turn!</h1>
            </div>

            <!--- Game board --->
            <div id="board">
                <div class="boxes" value='1'></div>
                <div class="boxes" value='2'></div>
                <div class="boxes" value='3'></div>
                <div class="boxes" value='4'></div>
                <div class="boxes" value='5'></div>
                <div class="boxes" value='6'></div>
                <div class="boxes" value='7'></div>
                <div class="boxes" value='8'></div>
                <div class="boxes" value='9'></div>
            </div>

            <div id="time"></div>
        </div>
    </div>

    <script src="game.js" async></script>
</body>