五子棋是一种起源于中国的传统棋类游戏,具有悠久的历史。
基本规则
-
棋盘:
- 五子棋通常在一个 15x15 的棋盘上进行,但也可以在更大的棋盘上进行。
- 棋盘上的每个交叉点称为一个“点”。
-
棋子:
- 五子棋使用黑白两色的棋子。
- 两名玩家分别持有一种颜色的棋子。
-
游戏目标:
- 游戏的目标是先在棋盘上形成连续五个同色棋子的一方获胜。
- 这些棋子可以是水平、垂直或对角线排列的。
-
下棋规则:
- 游戏开始时,棋盘是空的。
- 黑方先行,然后双方轮流在棋盘的空点上放置一枚棋子。
- 棋子一旦放下,就不能移动或移除。
HTML源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>五子棋</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>基于HTML+CSS+JS实现的五子棋小游戏</h1>
<div id="status"></div>
<div id="board"></div>
<div> <button id="reset">重置游戏</button> <button id="toggle-move-number">显示/隐藏手数</button></div>
<script src="script.js"></script>
</body>
</html>
CSS源码
body {
display: flex;
flex-direction: column;
align-items: center;
font-family: Arial, sans-serif;
background-color: #f0f0f0;
margin: 0;
padding: 20px;
}
h1 {
color: #333;
}
#board {
display: grid;
grid-template-columns: repeat(15, 40px);
grid-template-rows: repeat(15, 40px);
gap: 1px;
margin: 20px 0;
}
.cell {
width: 40px;
height: 40px;
background-color: #fff;
border: 1px solid #ccc;
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
cursor: pointer;
position: relative;
}
.cell.black {
background-color: black;
border-radius: 50%;
color: white; /* 黑色棋子的序号显示为白色 */
}
.cell.black.current::after {
content: '';
display: block;
width: 30px;
height: 30px;
border: 2px solid white;
border-radius: 50%;
position: absolute;
top: 4px;
left: 4px;
box-sizing: border-box;
}
.cell.white {
background-color: white;
border: 1px solid black;
border-radius: 50%;
color: black; /* 白色棋子的序号显示为黑色 */
}
.cell.white.current::after {
content: '';
display: block;
width: 30px;
height: 30px;
border: 2px solid black;
border-radius: 50%;
position: absolute;
top: 4px;
left: 4px;
box-sizing: border-box;
}
#status {
margin: 10px 0;
font-size: 18px;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
background-color: #4caf50;
color: white;
border: none;
border-radius: 5px;
}
button:hover {
background-color: #45a049;
}
JS源码
const board = document.getElementById('board');
const status = document.getElementById('status');
const resetButton = document.getElementById('reset');
const toggleMoveNumberButton = document.getElementById('toggle-move-number');
const size = 15;
let cells = [];
let currentPlayer = 'black';
let gameOver = false;
let moveCount = 0;
let showMoveNumber = true; // 控制是否显示当前是第几手
function createBoard() {
board.innerHTML = '';
cells = [];
moveCount = 0;
for (let i = 0; i < size; i++) {
cells[i] = [];
for (let j = 0; j < size; j++) {
const cell = document.createElement('div');
cell.classList.add('cell');
cell.dataset.row = i;
cell.dataset.col = j;
cell.addEventListener('click', handleCellClick);
board.appendChild(cell);
cells[i][j] = cell;
}
}
updateStatus();
}
function handleCellClick(event) {
if (gameOver) return;
const cell = event.target;
const row = parseInt(cell.dataset.row);
const col = parseInt(cell.dataset.col);
if (cell.classList.contains('black') || cell.classList.contains('white')) {
return;
}
moveCount++;
cell.classList.add(currentPlayer);
cell.classList.add('current');
cell.dataset.moveNumber = moveCount; // 存储手数在 data-move-number 属性中
if (showMoveNumber) {
cell.textContent = moveCount;
}
if (checkWin(row, col)) {
status.textContent = `玩家 ${currentPlayer === 'black' ? '⚫' : '⚪'} 赢了!`;
gameOver = true;
} else {
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updateStatus();
updateCurrentMarker();
}
}
function checkWin(row, col) {
return checkDirection(row, col, 1, 0) || // Horizontal
checkDirection(row, col, 0, 1) || // Vertical
checkDirection(row, col, 1, 1) || // Diagonal /
checkDirection(row, col, 1, -1); // Diagonal \
}
function checkDirection(row, col, deltaRow, deltaCol) {
let count = 0;
let r = row;
let c = col;
while (r >= 0 && r < size && c >= 0 && c < size && cells[r][c].classList.contains(currentPlayer)) {
count++;
r += deltaRow;
c += deltaCol;
}
r = row - deltaRow;
c = col - deltaCol;
while (r >= 0 && r < size && c >= 0 && c < size && cells[r][c].classList.contains(currentPlayer)) {
count++;
r -= deltaRow;
c -= deltaCol;
}
return count >= 5;
}
function updateStatus() {
status.textContent = `当前玩家: ${currentPlayer === 'black' ? '⚫' : '⚪'}`;
}
function updateCurrentMarker() {
document.querySelectorAll('.cell').forEach(cell => cell.classList.remove('current'));
}
function toggleMoveNumber() {
showMoveNumber = !showMoveNumber;
document.querySelectorAll('.cell').forEach(cell => {
if (cell.classList.contains('black') || cell.classList.contains('white')) {
cell.textContent = showMoveNumber ? cell.dataset.moveNumber : '';
}
});
}
resetButton.addEventListener('click', () => {
currentPlayer = 'black';
gameOver = false;
createBoard();
});
toggleMoveNumberButton.addEventListener('click', toggleMoveNumber);
createBoard();