📜  使用 jQuery 创建井字游戏(1)

📅  最后修改于: 2023-12-03 15:22:13.311000             🧑  作者: Mango

使用 jQuery 创建井字游戏

本文将介绍如何使用 jQuery 创建井字游戏。jQuery 是一个流行的 JavaScript 库,使开发者可以更轻松地处理 HTML 文档遍历和操作、事件处理、动画等常见的前端开发任务。本文假设读者已经基本掌握了 jQuery 的用法。

游戏规则

井字游戏是一个两人玩的游戏,双方轮流在一个 3x3 的棋盘上落子,用自己的棋子(通常为 X 和 O)尝试在水平、垂直或对角线上先形成一条线(三个棋子)。若双方都没有形成连线,则平局。

实现思路

为了方便起见,我们使用 div 元素模拟棋盘格子,用 CSS 样式控制它们的外观。 棋盘格子被默认为无背景颜色,若有玩家下棋子,就会改变它的背景颜色。 游戏结束后,我们将禁用所有格子,以使它们保持在它们当前的状态。

游戏状态存储在一个对象中。随着棋子的下落,该对象被修改以反映更改的状态。 当检测到游戏结束时,我们将弹出一个模态窗口显示游戏结果,并提示用户是否要再次玩游戏。

代码实现
HTML 代码

我们需要一个简单的 HTML 结构,包含用于展示游戏棋盘、显示游戏信息的元素。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Tic-Tac-Toe</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="board">
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
    <div class="square"></div>
  </div>
  <div class="game-info">
    <p class="status">Now it's X's turn!</p>
    <button class="restart-btn">Restart</button>
  </div>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="main.js"></script>
</body>
</html>
CSS 代码

我们使用 CSS3 中的 Flexbox 布局使得棋盘中的每个格子能够正确布局。同时,我们定义了一些其他样式属性,用于使游戏元素更易于阅读和辨别。

.board {
  display: flex;
  flex-wrap: wrap;
  width: 300px;
  height: 300px;
  border: 5px solid #333;
}

.square {
  width: calc(100% / 3);
  height: calc(100% / 3);
  background-color: #fff;
  border: 2px solid #333;
  box-sizing: border-box;
  font-size: 48px;
  text-align: center;
  line-height: calc(100% / 3);
  cursor: pointer;
}

.square.x {
  color: #03a9f4;
}

.square.o {
  color: #f44336;
}

.game-info {
  margin-top: 20px;
  text-align: center;
}

.status {
  font-size: 24px;
}

.restart-btn {
  font-size: 24px;
  background-color: #03a9f4;
  color: #fff;
  padding: 10px 20px;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
jQuery 代码

该代码是我们实现该游戏的主要后端。 它实际执行的是游戏的逻辑和状态跟踪。 我们可以将该代码拆分为以下部分:

1、定义数据结构和变量

在我们开始实现 jQuery 代码之前,我们需要使用一个 JavaScript 对象来表示游戏状态。 在该对象中,我们跟踪棋盘的每格状态以及该轮下的玩家(X 或 O)。 我们还需要处理其他一些变量,例如游戏状态、当前玩家以及模态窗口元素等。

// Initialize game state variables
let currentPlayer = 'X';
let gameStatus = true;
let gameState = ['', '', '', '', '', '', '', '', ''];

// DOM Elements
const statusDisplay = $('.status');
const square = $('.square');
const restartBtn = $('.restart-btn');
const modal = $('.modal');
const modalMsg = $('.modal .message');

2、更新游戏状态

在每个回合结束时(即玩家按下方格元素时),我们需要检查是否有任何玩家赢得了游戏,或者是否经过了 9 个回合,结果是平局。 如果游戏终止,则将游戏状态设置为 false。 当游戏结束时,我们还会更改游戏信息显示元素的文本,以指示游戏是谁赢了,或游戏是否已结束。

/**
* Updates the game state
* @param {number} index - square element index
*/
function updateGameState(index) {
  // Update game state
  gameState[index] = currentPlayer;

  // Switch players after updating game state
  currentPlayer = currentPlayer === 'X' ? 'O' : 'X';

  // Check if there are any winning cells
  const winningCells = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
  ];
  for (let i = 0; i < winningCells.length; i++) {
    const [a, b, c] = winningCells[i];
    if (
      gameState[a] &&
      gameState[a] === gameState[b] &&
      gameState[b] === gameState[c]
    ) {
      gameStatus = false;
      const winningPlayer = gameState[a];
      statusDisplay.text(`Congratulations, ${winningPlayer} won!`);
      showModal(`Congratulations, ${winningPlayer} won!`);
    }
  }

  // Check if all cells have been played and there is no winner
  if (gameState.every(cell => cell) && gameStatus) {
    gameStatus = false;
    statusDisplay.text('It was a tie!');
    showModal('It was a tie!');
  }

  // Update game text
  if (gameStatus) {
    statusDisplay.text(`Now it's ${currentPlayer}'s turn!`);
  }
}

3、处理点击事件

每当一个方格元素被点击时(即玩家的回合开始),我们需要检查该元素是否已经被占据。 如果空闲,我们将元素标记为已占据,并检查是否达到游戏结束条件。

/**
* Handles the square click event
*/
square.on('click', function () {
  const index = square.index(this);

  // Handle game clicks when the game is still active
  if (gameStatus && !gameState[index]) {
    $(this).addClass(currentPlayer.toLowerCase())
           .text(currentPlayer);
    updateGameState(index);
  }
});

4、处理重新开始事件

当重新开始按钮元素被点击时,我们需要初始化游戏状态并重置元素。

/**
* Handles the restart button click event
*/
restartBtn.on('click', function () {
  currentPlayer = 'X';
  gameStatus = true;
  gameState = ['', '', '', '', '', '', '', '', ''];
  square.removeClass('x o').text('');
  statusDisplay.text(`Now it's ${currentPlayer}'s turn!`);
  modal.css('display', 'none');
});

5、处理游戏结束事件和模态框

我们使用一个模态框元素来显示游戏结束的情况。 这个元素在一开始就应该被隐藏,只有在游戏结束时才显示出来。

/**
* Handles showing the game end modal
* @param {string} message - message to display in the modal
*/
function showModal(message) {
  modal.css('display', 'block');
  modalMsg.text(message);
}
结论

在本文中,我们通过使用 jQuery 库和一些 CSS 形成了井字游戏。 我们涵盖了管理游戏状态、处理玩家点击、检查赢家、进行游戏的重新开始以及显示游戏结束模态框的所有主要方面。 我们还简单地介绍了 jQuery 中一些最常见的方法和工具,例如选择器、事件和 DOM 内容操作。