一次获取数组中的多个元素,便于比较

前端开发 2026-07-11

我正在做一个井字棋项目。我有一个对象(gameBoard),它包含一个数组;接着我有另一个对象,我想从它创建一个玩家来在棋盘上进行对局;然后我有一个函数,我想用来控制游戏的流程。请注意,这个项目的核心是使用“函数族”、闭包和解构赋值来实现所需的结果。某处在gameController函数中,我在格子上添加了一个eventListener,因此当它们被点击时,它们会把事件登记到gameBoard上,并把点击的标记添加到gameBoard内的array中。

现在的问题在于如何比较多个索引来宣布赢家。例如:如果gameBoard对象中的数组,或对象本身,在索引 [0]、[3] 和 [6] 处有玩家 'Me' 的标记,就让玩家 'Me' 成为赢家;但也要覆盖所有其他可能宣布赢家的索引组合。我尝试用if/else,当我点击棋盘上某些索引的格子,尤其是从索引 [2] 或 [5] 开始时,它在我只点击一个格子的情况下就自动宣布赢家。if/else语句似乎没有正确评估成为赢家所需满足的条件。

希望得到一些帮助。

const gameBoard = {
  board: [
    "", "", "",
    "", "", "",
    "", "", ""
  ],
};

function gamePlayers(player, marker) {
  return {
    player,
    marker
  };
};

const player = gamePlayers('Me', 'X');
const playerTwo = gamePlayers('You', 'O');

function gameController(firstPlayer, secondPlayer) {
  firstPlayer = player;
  secondPlayer = playerTwo;
  let turn = 1;

  const squares = document.querySelectorAll('.squares');
  squares.forEach((square, index) => {
    for (let i = 0; i < gameBoard.length; i++) {
      if (i === index) {
        i = index;
      }
    }
    square.addEventListener('click', () => {
      if (turn === 1) {
        gameBoard[index] = player.marker;
        square.textContent = player.marker;
        gameBoard.board.splice(index, 1, player.marker);
        turn = 2;
      } else if (turn === 2) {
        gameBoard[index] = playerTwo.marker;
        square.textContent = playerTwo.marker;
        gameBoard.board.splice(index, 1, playerTwo.marker);
        turn = 1;
      } else {
        return;
      };

      if (gameBoard[0, 3, 6] === player.marker || gameBoard[1, 4, 7] === player.marker || gameBoard[2, 5, 8] === player.marker || gameBoard[0, 1, 2] === player.marker || gameBoard[3, 4, 5] === player.marker || gameBoard[6, 7, 8] === player.marker || gameBoard[2, 4, 6] === player.marker || gameBoard[0, 4, 8] === player.marker) {
        console.log('I win');
      } else if (gameBoard[0, 3, 6] === playerTwo.marker || gameBoard[1, 4, 7] === playerTwo.marker || gameBoard[2, 5, 8] === playerTwo.marker || gameBoard[0, 1, 2] === playerTwo.marker || gameBoard[3, 4, 5] === playerTwo.marker || gameBoard[6, 7, 8] === playerTwo.marker || gameBoard[2, 4, 6] === playerTwo.marker || gameBoard[0, 4, 8] === playerTwo.marker) {
        console.log('You win');
      } else {
        return;
      };

    });
  })
  return {
    gameBoard,
    firstPlayer,
    secondPlayer
  };
};
<div class="game-board">
  <div class="squares" data-index="0"></div>
  <div class="squares" data-index="1"></div>
  <div class="squares" data-index="2"></div>
  <div class="squares" data-index="3"></div>
  <div class="squares" data-index="4"></div>
  <div class="squares" data-index="5"></div>
  <div class="squares" data-index="6"></div>
  <div class="squares" data-index="7"></div>
  <div class="squares" data-index="8"></div>
</div>

解决方案

立即出现的错误胜利来自于ADyson提到的逗号运算符,但还有另一个问题:你是在检查gameBoard而不是gameBoard.board。

下面是一个示例(我添加了一些CSS以便更直观地观察),它也像我建议的那样从div上进行事件委托。

const gameBoard = {
  board: ['', '', '', '', '', '', '', '', '']
};

const gamePlayers = (player, marker) => {
  return {
    player,
    marker
  };
};

const player = gamePlayers('Me', '✕');
const playerTwo = gamePlayers('You', '◯');

const gameController = (firstPlayer = player, secondPlayer = playerTwo) => {
  let turn = 1;
  let gameOver = false;

  const boardElement = document.querySelector('.game-board');
  const {
    board
  } = gameBoard;

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

  const hasWinner = (marker) => {
    return winningCombos.some(([a, b, c]) => {
      return board[a] === marker &&
        board[b] === marker &&
        board[c] === marker;
    });
  };

  boardElement.addEventListener('click', (e) => {
    const square = e.target.closest('.squares');
    if (!square || gameOver) return;

    const index = +square.dataset.index;

    if (board[index] !== '') return;

    const currentPlayer = turn === 1 ? firstPlayer : secondPlayer;

    board[index] = currentPlayer.marker;
    square.textContent = currentPlayer.marker;

    if (hasWinner(currentPlayer.marker)) {
      console.log(`${currentPlayer.player} wins`);
      gameOver = true;
      return;
    }

    if (board.every(cell => cell !== '')) {
      console.log('Draw');
      gameOver = true;
      return;
    }

    turn = turn === 1 ? 2 : 1;
  });

  return {
    gameBoard,
    firstPlayer,
    secondPlayer
  };
}

gameController();
.game-board {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  gap: 2px;
}

.squares {
  width: 100px;
  height: 100px;
  border: 1px solid #000;
  display: grid;
  place-items: center;
  font-size: 64px;
  line-height: 1;
  cursor: pointer;
}
<div class="game-board">
  <div class="squares" data-index="0"></div>
  <div class="squares" data-index="1"></div>
  <div class="squares" data-index="2"></div>
  <div class="squares" data-index="3"></div>
  <div class="squares" data-index="4"></div>
  <div class="squares" data-index="5"></div>
  <div class="squares" data-index="6"></div>
  <div class="squares" data-index="7"></div>
  <div class="squares" data-index="8"></div>
</div>

下面是一个更简化的版本

const gameBoard = {
  board: ['', '', '', '', '', '', '', '', '']
};

function gamePlayers(player, marker) {
  return {
    player,
    marker
  };
}

const player = gamePlayers('Me', '✕');
const playerTwo = gamePlayers('You', '◯');

function gameController(firstPlayer, secondPlayer) {
  firstPlayer = player;
  secondPlayer = playerTwo;
  let turn = 1;

  const board = document.querySelector('.game-board');

  board.addEventListener('click', (e) => {
    const square = e.target.closest('.squares');
    if (!square) return;

    const index = +square.dataset.index;

    if (gameBoard.board[index] !== '') return;

    if (turn === 1) {
      gameBoard.board[index] = player.marker;
      square.textContent = player.marker;
      turn = 2;
    } else {
      gameBoard.board[index] = playerTwo.marker;
      square.textContent = playerTwo.marker;
      turn = 1;
    }

    if (
      (gameBoard.board[0] === player.marker && gameBoard.board[3] === player.marker && gameBoard.board[6] === player.marker) ||
      (gameBoard.board[1] === player.marker && gameBoard.board[4] === player.marker && gameBoard.board[7] === player.marker) ||
      (gameBoard.board[2] === player.marker && gameBoard.board[5] === player.marker && gameBoard.board[8] === player.marker) ||
      (gameBoard.board[0] === player.marker && gameBoard.board[1] === player.marker && gameBoard.board[2] === player.marker) ||
      (gameBoard.board[3] === player.marker && gameBoard.board[4] === player.marker && gameBoard.board[5] === player.marker) ||
      (gameBoard.board[6] === player.marker && gameBoard.board[7] === player.marker && gameBoard.board[8] === player.marker) ||
      (gameBoard.board[2] === player.marker && gameBoard.board[4] === player.marker && gameBoard.board[6] === player.marker) ||
      (gameBoard.board[0] === player.marker && gameBoard.board[4] === player.marker && gameBoard.board[8] === player.marker)
    ) {
      console.log('I win');
    } else if (
      (gameBoard.board[0] === playerTwo.marker && gameBoard.board[3] === playerTwo.marker && gameBoard.board[6] === playerTwo.marker) ||
      (gameBoard.board[1] === playerTwo.marker && gameBoard.board[4] === playerTwo.marker && gameBoard.board[7] === playerTwo.marker) ||
      (gameBoard.board[2] === playerTwo.marker && gameBoard.board[5] === playerTwo.marker && gameBoard.board[8] === playerTwo.marker) ||
      (gameBoard.board[0] === playerTwo.marker && gameBoard.board[1] === playerTwo.marker && gameBoard.board[2] === playerTwo.marker) ||
      (gameBoard.board[3] === playerTwo.marker && gameBoard.board[4] === playerTwo.marker && gameBoard.board[5] === playerTwo.marker) ||
      (gameBoard.board[6] === playerTwo.marker && gameBoard.board[7] === playerTwo.marker && gameBoard.board[8] === playerTwo.marker) ||
      (gameBoard.board[2] === playerTwo.marker && gameBoard.board[4] === playerTwo.marker && gameBoard.board[6] === playerTwo.marker) ||
      (gameBoard.board[0] === playerTwo.marker && gameBoard.board[4] === playerTwo.marker && gameBoard.board[8] === playerTwo.marker)
    ) {
      console.log('You win');
    }
  });

  return {
    gameBoard,
    firstPlayer,
    secondPlayer
  };
}

gameController();
.game-board {
  display: grid;
  grid-template-columns: repeat(3, 100px);
  gap: 2px;
}

.squares {
  width: 100px;
  height: 100px;
  border: 1px solid #000;
  display: grid;
  place-items: center;
  font-size: 64px;
  line-height: 1;
  cursor: pointer;
}
<div class="game-board">
  <div class="squares" data-index="0"></div>
  <div class="squares" data-index="1"></div>
  <div class="squares" data-index="2"></div>
  <div class="squares" data-index="3"></div>
  <div class="squares" data-index="4"></div>
  <div class="squares" data-index="5"></div>
  <div class="squares" data-index="6"></div>
  <div class="squares" data-index="7"></div>
  <div class="squares" data-index="8"></div>
</div>
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章