【问题标题】:TicTacToe Game in JavaScriptJavaScript 中的井字游戏
【发布时间】:2021-08-15 23:28:14
【问题描述】:

我一直试图找出为什么我的井字游戏没有按照我想要的方式进行检查。由于我一直在看教程,但仍然无法弄清楚当玩家赢得游戏时正确使函数winning 运行的逻辑。

这里我尝试将 O 或 X 推送到数组中,并使用 console.log 来查看它的样子以及获胜条件检查不起作用的原因。

  spaces.push[id];
  console.log(spaces);

我还尝试了其他方法来使程序正确,例如使用预先制作的获胜条件并映射当前数组,但也无法正常工作......

  const winningCondition = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];

对于单元格,我在 HTML 中创建 9 个 div,并在 CSS 中使用网格系统。

非常感谢您的帮助!下面是井字游戏的 JavaScript 代码:

const winning = (player) => {
  if (spaces[0] === player) {
    if (spaces[1] === player && spaces[2] === player) return true;
    if (spaces[3] === player && spaces[6] === player) return true;
    if (spaces[4] === player && spaces[8] === player) return true;
  }
  if (spaces[8] === player) {
    if (spaces[2] === player && spaces[5] === player) return true;
    if (spaces[6] === player && spaces[7] === player) return true;
  }
  if (spaces[4] === player) {
    if (spaces[1] === player && spaces[7] === player) return true;
    if (spaces[3] === player && spaces[5] === player) return true;
  }
};

【问题讨论】:

  • 请提供重现问题所需的所有代码。见minimal reproducible example
  • 请也添加 HTML。我想知道为那些 .cell 元素设置了哪些 ID?
  • 回答问题:What is 'spaces' and how information is stored there? 应该有助于解决问题。
  • 你可以尝试制作一个codepen或jsfiddle吗?

标签: javascript tic-tac-toe


【解决方案1】:

看起来板是一个名为spaces 的数组,长度为九。看起来该数组的值是' ''x''o',表示两个玩家之一未被占用或占用。

您已经列举了玩家获胜时必须占据哪些空间。一个检查胜利的简单函数将迭代该数组。

// assuming spaces is defined here as game state, an array 'x', 'o' or ' '
const winningLines = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6],
  ];


// call with 'x' or 'o' representing player
function playerWon(player) {
  const playerOccupiesLine = line => line.every(el => spaces[el] === player);
  return winningLines.some(line => playerOccupiesLine(line);
}

【讨论】:

    【解决方案2】:

    没有理由让spaces.push(id) 在数组末尾添加额外元素,只需将其删除即可。您已经拥有spaces[id] = currentPlayer,它将当前玩家值写入spaces 中所需的位置。

    我发现的唯一问题是单元格应该有从 0 到 8 的数字,对应于 spaces 数组中的索引:

    0 1 2
    3 4 5
    6 7 8
    <div class="game">
        <div class="cell" id="0"></div>
        <div class="cell" id="1"></div>
        <div class="cell" id="2"></div>
        <div class="cell" id="3"></div>
        <div class="cell" id="4"></div>
        <div class="cell" id="5"></div>
        <div class="cell" id="6"></div>
        <div class="cell" id="7"></div>
        <div class="cell" id="8"></div>
    </div>
    

    有 8 个获胜条件(3 行、3 列和 2 个对角线)。缺少一个对角线条件:

    if (spaces[4] === player) {
        // ...
        if (spaces[2] === player && spaces[6] === player) return true;
    }
    

    这里是完整的代码:

    const cells = document.querySelectorAll(".cell");
    const playText = document.getElementById("game-text");
    const restartBtn = document.getElementById("restart");
    
    const spaces = [];
    const OPlayer = "O";
    const XPlayer = "X";
    let currentPlayer;
    
    function handleClick(e) {
        const id = e.target.id;
        if (!spaces[id]) {
            spaces[id] = currentPlayer;
    
            console.log('[' + spaces.slice(0, 3) + ']\n[' + spaces.slice(3, 6) + ']\n[' + spaces.slice(6) + ']');
            e.target.innerText = currentPlayer;
    
            if (playerWon(currentPlayer)) {
                const winningAlert = document.createElement("p");
                winningAlert.setAttribute("id", "winning-text");
                winningAlert.innerText = `${currentPlayer} HAS WON!`;
                playText.appendChild(winningAlert);
    
                setTimeout(() => {
                    restart();
                }, 4000);
                return;
            }
            currentPlayer = currentPlayer === OPlayer ? XPlayer : OPlayer;
        }
    }
    
    cells.forEach((cell) => {
        cell.addEventListener("click", handleClick);
    });
    
    const playerWon = (player) => {
        if (spaces[0] === player) {
            if (spaces[1] === player && spaces[2] === player) return true;
            if (spaces[3] === player && spaces[6] === player) return true;
            if (spaces[4] === player && spaces[8] === player) return true;
        }
        if (spaces[8] === player) {
            if (spaces[2] === player && spaces[5] === player) return true;
            if (spaces[6] === player && spaces[7] === player) return true;
        }
        if (spaces[4] === player) {
            if (spaces[1] === player && spaces[7] === player) return true;
            if (spaces[3] === player && spaces[5] === player) return true;
            if (spaces[2] === player && spaces[6] === player) return true;
        }
    };
    
    const restart = () => {
        spaces.forEach((space, index) => {
            console.log(space);
            spaces[index] = null;
        });
        cells.forEach((cell) => {
            cell.innerText = "";
        });
        playText.innerHTML = `LET'S PLAY!`;
        currentPlayer = OPlayer;
    };
    
    restartBtn.addEventListener("click", restart);
    
    restart();
    * {
        box-sizing: border-box;
        font-family: Verdana, Geneva, Tahoma, sans-serif;
    }
    
    .game-board {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        margin: 6% 15%;
    }
    
    .game {
        display: grid;
        grid-gap: 1px;
        grid-template-columns: repeat(3, 1fr);
    }
    
    .btn {
        padding: 15px 18px;
        margin: 30px auto auto auto;
        width: 120px;
        font-size: 18px;
        border-radius: 8px;
        border: none;
        color: white;
        background: green;
        cursor: pointer;
    }
    
    .btn:hover {
        transition-duration: 0.3s;
        background-color: red;
        transform: translateY(-5px);
    }
    
    
    .cell {
        width: 150px;
        height: 150px;
        margin: 8px 8px;
        border-radius: 15px;
        background-color: brown;
        text-align: center;
        font-size: 120px;
    }
    
    #game-text {
        font-size: 25px;
        font-weight: bold;
        text-transform: uppercase;
        margin: -10px auto 25px auto;
    }
    
    #winning-text {
        text-align: center;
        margin-bottom: -20px;
        font-size: 20px;
        color: purple;
    }
    <section class="game-board">
        <div id="game-text"></div>
        <div class="game">
            <div class="cell" id="0"></div>
            <div class="cell" id="1"></div>
            <div class="cell" id="2"></div>
            <div class="cell" id="3"></div>
            <div class="cell" id="4"></div>
            <div class="cell" id="5"></div>
            <div class="cell" id="6"></div>
            <div class="cell" id="7"></div>
            <div class="cell" id="8"></div>
        </div>
        <button class="btn" id="restart">Restart</button>
    </section>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多