<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>五子棋游戏</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#8B5A2B',
secondary: '#D2B48C',
board: '#DEB887',
black: '#000000',
white: '#FFFFFF',
},
fontFamily: {
sans: ['Inter', 'system-ui', 'sans-serif'],
},
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.content-auto {
content-visibility: auto;
}
.board-grid {
background-image: linear-gradient(#000 1px, transparent 1px),
linear-gradient(90deg, #000 1px, transparent 1px);
}
.piece-black {
background: radial-gradient(circle at 35% 35%, #555, #000);
}
.piece-white {
background: radial-gradient(circle at 35% 35%, #fff, #ddd);
}
.piece-shadow {
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16);
}
}
</style>
</head>
<body class="bg-gray-100 min-h-screen flex flex-col items-center justify-center p-4 font-sans">
<div class="max-w-4xl w-full bg-white rounded-xl shadow-lg overflow-hidden">
<!-- 游戏标题 -->
<div class="bg-primary text-white p-4 text-center">
<h1 class="text-2xl md:text-3xl font-bold">五子棋游戏</h1>
</div>
<div class="p-4 md:p-6 flex flex-col md:flex-row gap-6">
<!-- 游戏信息面板 -->
<div class="w-full md:w-1/4 bg-gray-50 rounded-lg p-4 shadow-sm">
<div class="mb-4">
<h2 class="text-lg font-semibold mb-2 flex items-center">
<i class="fa fa-info-circle mr-2 text-primary"></i>游戏状态
</h2>
<div id="game-status" class="bg-white p-3 rounded border border-gray-200 min-h-[60px] flex items-center justify-center text-gray-700">
黑方先行
</div>
</div>
<div class="mb-4">
<h2 class="text-lg font-semibold mb-2 flex items-center">
<i class="fa fa-user-circle mr-2 text-primary"></i>当前玩家
</h2>
<div id="current-player" class="bg-white p-3 rounded border border-gray-200 flex items-center justify-center">
<div class="w-8 h-8 rounded-full piece-black piece-shadow"></div>
<span class="ml-2 text-gray-700">黑方</span>
</div>
</div>
<div class="mb-4">
<h2 class="text-lg font-semibold mb-2 flex items-center">
<i class="fa fa-trophy mr-2 text-primary"></i>游戏统计
</h2>
<div class="bg-white p-3 rounded border border-gray-200">
<div class="flex justify-between items-center mb-2">
<span class="text-gray-600">黑方胜场</span>
<span id="black-wins" class="font-bold">0</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-600">白方胜场</span>
<span id="white-wins" class="font-bold">0</span>
</div>
</div>
</div>
<div class="flex flex-col gap-2">
<button id="restart-btn" class="bg-primary hover:bg-primary/90 text-white py-2 px-4 rounded transition-all duration-300 flex items-center justify-center">
<i class="fa fa-refresh mr-2"></i>重新开始
</button>
<button id="undo-btn" class="bg-gray-200 hover:bg-gray-300 text-gray-700 py-2 px-4 rounded transition-all duration-300 flex items-center justify-center">
<i class="fa fa-undo mr-2"></i>悔棋
</button>
</div>
</div>
<!-- 游戏棋盘 -->
<div class="w-full md:w-3/4 flex flex-col items-center">
<div class="relative w-full max-w-lg aspect-square">
<div id="board" class="absolute inset-0 rounded-lg bg-board board-grid bg-[length:calc(100%/14)_calc(100%/14)] cursor-pointer shadow-md transition-all duration-300 hover:shadow-lg"></div>
<div id="pieces-container" class="absolute inset-0 pointer-events-none"></div>
</div>
<div class="mt-4 text-sm text-gray-500">
<p>点击棋盘落子,连成五子即获胜。</p>
</div>
</div>
</div>
<!-- 页脚 -->
<div class="bg-gray-100 p-3 text-center text-gray-500 text-sm">
<p>© 2025 五子棋游戏 | 简单又有趣的经典游戏</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
// 游戏配置
const BOARD_SIZE = 15; // 15x15棋盘
const CELL_SIZE = 100 / (BOARD_SIZE - 1); // 百分比单位
// 游戏状态
let gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
let currentPlayer = 'black'; // 'black' 或 'white'
let gameActive = true;
let moveHistory = [];
let blackWins = 0;
let whiteWins = 0;
// DOM 元素
const boardElement = document.getElementById('board');
const piecesContainer = document.getElementById('pieces-container');
const gameStatusElement = document.getElementById('game-status');
const currentPlayerElement = document.getElementById('current-player');
const restartButton = document.getElementById('restart-btn');
const undoButton = document.getElementById('undo-btn');
const blackWinsElement = document.getElementById('black-wins');
const whiteWinsElement = document.getElementById('white-wins');
// 初始化棋盘
function initializeBoard() {
// 设置棋盘网格
boardElement.style.backgroundSize = `${CELL_SIZE}% ${CELL_SIZE}%`;
// 绑定点击事件
boardElement.addEventListener('click', handleBoardClick);
// 初始化按钮事件
restartButton.addEventListener('click', restartGame);
undoButton.addEventListener('click', undoMove);
// 更新统计信息
updateStats();
}
// 处理棋盘点击
function handleBoardClick(event) {
if (!gameActive) return;
// 获取点击位置
const rect = boardElement.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// 计算落子位置
const cellX = Math.round((x / rect.width) * (BOARD_SIZE - 1));
const cellY = Math.round((y / rect.height) * (BOARD_SIZE - 1));
// 检查位置是否合法
if (cellX < 0 || cellX >= BOARD_SIZE || cellY < 0 || cellY >= BOARD_SIZE) return;
if (gameBoard[cellY][cellX] !== null) return;
// 落子
placePiece(cellX, cellY);
}
// 放置棋子
function placePiece(x, y) {
// 更新游戏状态
gameBoard[y][x] = currentPlayer;
moveHistory.push({ x, y, player: currentPlayer });
// 添加棋子到界面
const piece = document.createElement('div');
piece.className = `absolute w-[${CELL_SIZE}%] h-[${CELL_SIZE}%] rounded-full piece-shadow transition-all duration-200 scale-0`;
piece.classList.add(currentPlayer === 'black' ? 'piece-black' : 'piece-white');
piece.style.left = `${x * CELL_SIZE}%`;
piece.style.top = `${y * CELL_SIZE}%`;
piece.style.transformOrigin = 'center';
piecesContainer.appendChild(piece);
// 添加动画效果
setTimeout(() => {
piece.classList.remove('scale-0');
piece.classList.add('scale-100');
}, 10);
// 检查是否获胜
if (checkWin(x, y)) {
gameActive = false;
gameStatusElement.textContent = `${currentPlayer === 'black' ? '黑方' : '白方'}获胜!`;
// 更新统计
if (currentPlayer === 'black') {
blackWins++;
} else {
whiteWins++;
}
updateStats();
// 高亮获胜的五个棋子
highlightWinningPieces();
return;
}
// 检查是否平局
if (checkDraw()) {
gameActive = false;
gameStatusElement.textContent = '游戏平局!';
return;
}
// 切换玩家
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updateGameStatus();
}
// 检查获胜
function checkWin(x, y) {
const directions = [
[1, 0], // 水平
[0, 1], // 垂直
[1, 1], // 对角线
[1, -1] // 反对角线
];
const player = gameBoard[y][x];
for (const [dx, dy] of directions) {
let count = 1; // 当前位置已经有一个棋子
// 正方向检查
for (let i = 1; i < 5; i++) {
const nx = x + dx * i;
const ny = y + dy * i;
if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE) break;
if (gameBoard[ny][nx] !== player) break;
count++;
}
// 反方向检查
for (let i = 1; i < 5; i++) {
const nx = x - dx * i;
const ny = y - dy * i;
if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE) break;
if (gameBoard[ny][nx] !== player) break;
count++;
}
// 五子连珠
if (count >= 5) {
// 保存获胜的棋子位置
window.winningPieces = [];
// 正方向
for (let i = 0; i < 5; i++) {
const nx = x + dx * i;
const ny = y + dy * i;
if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE) break;
if (gameBoard[ny][nx] !== player) break;
window.winningPieces.push({ x: nx, y: ny });
}
// 反方向
for (let i = 1; i < 5; i++) {
const nx = x - dx * i;
const ny = y - dy * i;
if (nx < 0 || nx >= BOARD_SIZE || ny < 0 || ny >= BOARD_SIZE) break;
if (gameBoard[ny][nx] !== player) break;
window.winningPieces.push({ x: nx, y: ny });
}
// 去重
window.winningPieces = [...new Set(window.winningPieces.map(p => JSON.stringify(p)))]
.map(p => JSON.parse(p));
return true;
}
}
return false;
}
// 高亮获胜的棋子
function highlightWinningPieces() {
if (!window.winningPieces) return;
const pieces = piecesContainer.querySelectorAll('div');
window.winningPieces.forEach(({ x, y }) => {
const index = y * BOARD_SIZE + x;
const piece = pieces[index];
if (piece) {
piece.classList.add('ring-2', 'ring-yellow-400', 'z-10');
piece.style.transform = 'scale(1.1)';
}
});
}
// 检查平局
function checkDraw() {
for (let y = 0; y < BOARD_SIZE; y++) {
for (let x = 0; x < BOARD_SIZE; x++) {
if (gameBoard[y][x] === null) {
return false; // 还有空位,不是平局
}
}
}
return true; // 棋盘已满,平局
}
// 更新游戏状态显示
function updateGameStatus() {
const playerText = currentPlayer === 'black' ? '黑方' : '白方';
const playerClass = currentPlayer === 'black' ? 'piece-black' : 'piece-white';
gameStatusElement.textContent = `${playerText}回合`;
currentPlayerElement.innerHTML = `
<div class="w-8 h-8 rounded-full ${playerClass} piece-shadow"></div>
<span class="ml-2 text-gray-700">${playerText}</span>
`;
}
// 重新开始游戏
function restartGame() {
// 清空棋盘
gameBoard = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
gameActive = true;
moveHistory = [];
// 移除所有棋子
while (piecesContainer.firstChild) {
piecesContainer.removeChild(piecesContainer.firstChild);
}
// 重置当前玩家
currentPlayer = 'black';
updateGameStatus();
// 更新状态
gameStatusElement.textContent = '黑方先行';
// 移除获胜高亮
if (window.winningPieces) {
delete window.winningPieces;
}
}
// 悔棋
function undoMove() {
if (moveHistory.length === 0 || !gameActive) return;
const lastMove = moveHistory.pop();
gameBoard[lastMove.y][lastMove.x] = null;
// 移除最后一个棋子
const pieces = piecesContainer.querySelectorAll('div');
if (pieces.length > 0) {
const lastPiece = pieces[pieces.length - 1];
lastPiece.classList.remove('scale-100');
lastPiece.classList.add('scale-0');
setTimeout(() => {
piecesContainer.removeChild(lastPiece);
}, 200);
}
// 切换回上一个玩家
currentPlayer = lastMove.player;
updateGameStatus();
}
// 更新统计信息
function updateStats() {
blackWinsElement.textContent = blackWins;
whiteWinsElement.textContent = whiteWins;
}
// 初始化游戏
initializeBoard();
});
</script>
</body>
</html>
Xikuer 希葵锦尚网络
收藏的用户(0)
X
正在加载信息~