The effect is demonstrated:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>井字棋游戏</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f9;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.game-container {
text-align: center;
width: 400px;
}
.board {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 5px;
margin-bottom: 20px;
}
.cell {
width: 100px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
border: 2px solid #ddd;
font-size: 36px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.cell:hover {
background-color: #f0f0f0;
}
.status {
font-size: 18px;
margin-bottom: 20px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
background-color: #007bff;
color: #fff;
border-radius: 5px;
transition: background-color 0.3s;
}
button:hover {
background-color: #0056b3;
}
</style>
</head>
<body>
<div class="game-container">
<h1>井字棋游戏</h1>
<div class="status">
<span id="gameStatus">玩家 X 的回合</span>
</div>
<div class="board" id="board">
<!-- 9个格子 -->
<div class="cell" data-index="0"></div>
<div class="cell" data-index="1"></div>
<div class="cell" data-index="2"></div>
<div class="cell" data-index="3"></div>
<div class="cell" data-index="4"></div>
<div class="cell" data-index="5"></div>
<div class="cell" data-index="6"></div>
<div class="cell" data-index="7"></div>
<div class="cell" data-index="8"></div>
</div>
<button onclick="restartGame()">重新开始</button>
</div>
<script>
const board = document.getElementById("board");
const gameStatus = document.getElementById("gameStatus");
let currentPlayer = "X";
let gameActive = true;
let boardState = ["", "", "", "", "", "", "", "", ""];
const winningCombinations = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
function handleCellClick(event) {
const index = event.target.getAttribute("data-index");
if (boardState[index] !== "" || !gameActive) return;
boardState[index] = currentPlayer;
event.target.textContent = currentPlayer;
if (checkWinner()) {
gameStatus.textContent = `玩家 ${currentPlayer} 胜利!`;
gameActive = false;
} else if (boardState.every(cell => cell !== "")) {
gameStatus.textContent = "平局!";
gameActive = false;
} else {
currentPlayer = currentPlayer === "X" ? "O" : "X";
gameStatus.textContent = `玩家 ${currentPlayer} 的回合`;
}
}
function checkWinner() {
for (let combination of winningCombinations) {
const [a, b, c] = combination;
if (boardState[a] && boardState[a] === boardState[b] && boardState[a] === boardState[c]) {
return true;
}
}
return false;
}
function restartGame() {
boardState = ["", "", "", "", "", "", "", "", ""];
gameActive = true;
currentPlayer = "X";
gameStatus.textContent = `玩家 ${currentPlayer} 的回合`;
const cells = document.querySelectorAll(".cell");
cells.forEach(cell => {
cell.textContent = "";
});
}
board.addEventListener("click", handleCellClick);
</script>
</body>
</html>
Tic-Tac-Toe Principle and Implementation
Tic-Tac-Toe is a classic two-player board game in which players take turns marking their own symbols (usually "X" and "O") on a 3×3 board by first placing The first player to place three identical symbols in any row, column or diagonal in succession wins. If all squares are filled and no player wins, the game ends in a draw. In this article, we will introduce how to implement a Tic-Tac-Toe mini-game using pure HTML and JavaScript, analyzing the principles behind it and how to implement it.
1. HTML structure
HTML serves as the basic structure of a web page and is primarily responsible for the layout of the interface. In this tic-tac-toe game, we use adivcontainer to contain all the game elements, including the board, game state, and control buttons. The board itself consists of a container with nine child elements containingdivconsists of containers, with each sub-element representing a square on the board. Each lattice is represented by thedata-indexattribute to identify its location for subsequent event handling.
In addition to the board, the page has astatusAn area that displays the current game status, such as "Player X's turn" or "Player X's victory". There is also a "Restart" button that can be clicked to reset the game.
2. CSS style
To enhance the visualization of the game, CSS was used to style the game interface. The board consists of a 3×3 grid using CSS'sgridLayout implementation, each grid fixed size, and set the appropriate border and background color, make the whole board looks simple and beautiful. At the same time, add a hover effect to the grid, when the mouse moves to the top will change the background color, in order to increase the user's interactive experience.
The game also has stylized buttons that change the background color when clicked, enhancing the interactivity of the game.
3. JavaScript Logic
JavaScript serves as the core logic part of the game and is responsible for handling the game's state changes and player interactions. The game is implemented through a program calledboardStatearray to keep track of the state of each square. Each element of the array represents a square on the board.XmaybeoIndicates that the lattice has been marked. If the grid is empty, the value in the array is the empty string.
- Player's Rotation: The game starts with player "X" and each time he clicks on an empty square, the current player's marker is added to that square, after which it is the other player's turn. The player switches between
currentPlayerto achieve rotation. - Winning Decision: Each time a player makes a marker, the system checks to see if the current state of the board meets the conditions for a player to win. This is accomplished by
Winning CombinationsAn array that holds all possible winning lines (horizontal, vertical and diagonal), which are checked to see if they have been occupied after each player mark. If all three squares of a line are marked by the same player, the game ends and that player is declared the winner. - Tie-breaker ruling: If all squares are filled and no player wins, the game is ruled a draw.
- Starting over: The game provides a "Restart" button which, when clicked, resets the state of the board and its display and restarts the game.
4. Code implementation process
During the code implementation, we handle every action of the player by adding a click event listener. When a player clicks on a grid, it first determines whether the grid has been marked, and if not, it updates the state of the grid and checks the win/loss situation of the game. If no one wins and the board is not full, the players are exchanged.
In addition, by examiningboardStateWhether the array is completely filled and there is no winner determines whether a tie has occurred. Once the game is over, the user can't continue, avoiding pointless clicks.
5. summarize
This Tic Tac Toe game is fully functional with simple HTML, CSS and JavaScript. HTML takes care of the layout and structure, CSS takes care of beautifying the interface, and JavaScript handles the game logic and interaction. Through simple arrays and event handling, we have implemented player alternation, win judgment, draw judgment, and game reset functions. This game can not only be used as an entertainment project, but also help beginners to better understand DOM manipulation, event listening, array processing and basic UI design in front-end development.