示例成品AI 按一组示范选项写的
```html
<!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 { display: flex; flex-direction: column; align-items: center; font-family: "Microsoft YaHei", sans-serif; background: #f0e6d2; margin-top: 20px; }
h2 { color: #5d4037; }
#status { font-size: 20px; margin: 10px 0; font-weight: bold; color: #d84315; }
canvas { background: #dcb35c; border: 3px solid #8d6e63; border-radius: 4px; cursor: pointer; }
button { margin-top: 15px; padding: 8px 24px; font-size: 16px; background: #8d6e63; color: white; border: none; border-radius: 5px; cursor: pointer; }
button:hover { background: #6d4c41; }
</style>
</head>
<body>
<h2>亲子五子棋</h2>
<div id="status">黑棋落子</div>
<canvas id="board" width="450" height="450"></canvas>
<button onclick="initGame()">重新开始</button>
<script>
const canvas = document.getElementById('board');
const ctx = canvas.getContext('2d');
const gridSize = 15; // 15x15棋盘
const cellSize = 30; // 每格30像素
const padding = 15; // 边距
let board = []; // 0空 1黑 2白
let currentPlayer = 1;
let gameOver = false;
// 初始化游戏
function initGame() {
board = Array.from({ length: gridSize }, () => Array(gridSize).fill(0));
currentPlayer = 1;
gameOver = false;
document.getElementById('status').innerText = '黑棋落子';
drawBoard();
}
// 绘制棋盘和棋子
function drawBoard() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 画线
ctx.strokeStyle = '#5d4037';
for (let i = 0; i < gridSize; i++) {
ctx.beginPath();
ctx.moveTo(padding + i * cellSize, padding);
ctx.lineTo(padding + i * cellSize, padding + (gridSize - 1) * cellSize);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(padding, padding + i * cellSize);
ctx.lineTo(padding + (gridSize - 1) * cellSize, padding + i * cellSize);
ctx.stroke();
}
// 画棋子
for (let r = 0; r < gridSize; r++) {
for (let c = 0; c < gridSize; c++) {
if (board[r][c] !== 0) {
ctx.beginPath();
ctx.arc(padding + c * cellSize, padding + r * cellSize, cellSize / 2 - 2, 0, Math.PI * 2);
ctx.fillStyle = board[r][c] === 1 ? '#1a1a1a' : '#f5f5f5';
ctx.fill();
ctx.strokeStyle = '#000';
ctx.stroke();
}
}
}
}
// 点击落子
canvas.addEventListener('click', (e) => {
if (gameOver) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const col = Math.round((x - padding) / cellSize);
const row = Math.round((y - padding) / cellSize);
if (row < 0 || row >= gridSize || col < 0 || col >= gridSize || board[row][col] !== 0) return;
board[row][col] = currentPlayer;
drawBoard();
if (checkWin(row, col)) {
document.getElementById('status').innerText = (currentPlayer === 1 ? '黑棋' : '白棋') + '获胜!';
gameOver = true;
return;
}
currentPlayer = currentPlayer === 1 ? 2 : 1;
document.getElementById('status').innerText = (currentPlayer === 1 ? '黑棋' : '白棋') + '落子';
});
// 判断胜负(横、竖、斜四个方向连成5子)
function checkWin(r, c) {
const dirs = [[0,1],[1,0],[1,1],[1,-1]];
for (const [dr, dc] of dirs) {
let count = 1;
for (let i = 1; i < 5; i++) { if (board[r+dr*i]?.[c+dc*i] === board[r][c]) count++; else break; }
for (let i = 1; i < 5; i++) { if (board[r-dr*i]?.[c-dc*i] === board[r][c]) count++; else break; }
if (count >= 5) return true;
}
return false;
}
initGame();
</script>
</body>
</html>
```