<!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>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: #F5DEB3;
font-family: serif;
}
.game-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 20px;
}
.title {
font-size: 32px;
color: #4A2E19;
margin-bottom: 10px;
}
.status {
font-size: 16px;
color: #4A2E19;
margin-bottom: 10px;
}
#boardCanvas {
background-color: #DEB887;
border: 1px solid #4A2E19;
cursor: pointer;
}
#restartBtn {
background-color: #8B4513;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: transform 0.2s ease;
}
#restartBtn:hover {
transform: translateY(-2px);
}
</style>
</head>
<body>
<div class="game-container">
<div class="title">五子棋</div>
<div class="status" id="status">黑方回合</div>
<canvas id="boardCanvas" width="600" height="600"></canvas>
<button id="restartBtn">重新开始</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('boardCanvas');
const ctx = canvas.getContext('2d');
const statusDisplay = document.getElementById('status');
const restartBtn = document.getElementById('restartBtn');
const GRID_SIZE = 15;
const CELL_WIDTH = 40;
const MARGIN = 20;
const PIECE_RADIUS = 16;
const STONE_COLORS = { black: '#000000', white: '#FFFFFF' };
const BORDER_COLOR = '#4A2E19';
let board = Array(GRID_SIZE).fill().map(() => Array(GRID_SIZE).fill(null));
let currentPlayer = 'black';
let gameOver = false;
function initGame() {
board = Array(GRID_SIZE).fill().map(() => Array(GRID_SIZE).fill(null));
currentPlayer = 'black';
gameOver = false;
updateStatus();
drawBoard();
}
function updateStatus() {
if (gameOver) {
const winner = currentPlayer === 'black' ? '黑方胜利' : '白方胜利';
statusDisplay.textContent = winner;
} else {
statusDisplay.textContent = `${currentPlayer === 'black' ? '黑方' : '白方'}回合`;
}
}
function drawBoard() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = BORDER_COLOR;
ctx.lineWidth = 1;
for (let i = 0; i < GRID_SIZE; i++) {
const y = MARGIN + i * CELL_WIDTH;
ctx.beginPath();
ctx.moveTo(MARGIN, y);
ctx.lineTo(canvas.width - MARGIN, y);
ctx.stroke();
}
for (let j = 0; j < GRID_SIZE; j++) {
const x = MARGIN + j * CELL_WIDTH;
ctx.beginPath();
ctx.moveTo(x, MARGIN);
ctx.lineTo(x, canvas.height - MARGIN);
ctx.stroke();
}
for (let row = 0; row < GRID_SIZE; row++) {
for (let col = 0; col < GRID_SIZE; col++) {
if (board[row][col]) {
drawPiece(col, row, board[row][col]);
}
}
}
}
function drawPiece(col, row, color) {
const x = MARGIN + col * CELL_WIDTH;
const y = MARGIN + row * CELL_WIDTH;
ctx.beginPath();
ctx.arc(x, y, PIECE_RADIUS, 0, Math.PI * 2);
ctx.fillStyle = STONE_COLORS[color];
ctx.fill();
ctx.strokeStyle = BORDER_COLOR;
ctx.lineWidth = 1;
ctx.stroke();
}
function checkWin(row, col, player) {
const directions = [
[0, 1],
[1, 0],
[1, 1],
[1, -1]
];
for (const [dx, dy] of directions) {
let count = 1;
for (let i = 1; i < 5; i++) {
const newRow = row + i * dy;
const newCol = col + i * dx;
if (newRow >= 0 && newRow < GRID_SIZE && newCol >= 0 && newCol < GRID_SIZE && board[newRow][newCol] === player) {
count++;
} else {
break;
}
}
for (let i = 1; i < 5; i++) {
const newRow = row - i * dy;
const newCol = col - i * dx;
if (newRow >= 0 && newRow < GRID_SIZE && newCol >= 0 && newCol < GRID_SIZE && board[newRow][newCol] === player) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
}
return false;
}
canvas.addEventListener('click', (e) => {
if (gameOver) return;
const rect = canvas.getBoundingClientRect();
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
let col = Math.round((mouseX - MARGIN) / CELL_WIDTH);
let row = Math.round((mouseY - MARGIN) / CELL_WIDTH);
col = Math.max(0, Math.min(GRID_SIZE - 1, col));
row = Math.max(0, Math.min(GRID_SIZE - 1, row));
if (board[row][col]) return;
board[row][col] = currentPlayer;
drawPiece(col, row, currentPlayer);
if (checkWin(row, col, currentPlayer)) {
gameOver = true;
updateStatus();
return;
}
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updateStatus();
});
restartBtn.addEventListener('click', initGame);
initGame();
});
</script>
</body>
</html>