<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>五子棋 - 极强AI版</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a1a2e, #16213e);
font-family: 'Microsoft YaHei', sans-serif;
color: #fff;
padding: 20px;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
max-width: 1000px;
width: 100%;
}
.game-header {
text-align: center;
margin-bottom: 10px;
}
.game-header h1 {
font-size: 2.5rem;
margin-bottom: 10px;
color: #e94560;
text-shadow: 0 0 10px rgba(233, 69, 96, 0.5);
}
.game-info {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 600px;
background: rgba(255, 255, 255, 0.1);
padding: 15px;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.player-info {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.player-icon {
width: 40px;
height: 40px;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 1.2rem;
}
.black-player .player-icon {
background: #000;
color: white;
}
.white-player .player-icon {
background: #fff;
color: #000;
}
.current-player {
position: relative;
}
.current-player::after {
content: '';
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
width: 10px;
height: 10px;
background: #e94560;
border-radius: 50%;
}
.game-board {
position: relative;
background: #dcb35c;
border: 2px solid #8b6914;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
border-radius: 5px;
overflow: hidden;
}
.board-grid {
display: grid;
grid-template-columns: repeat(15, 1fr);
grid-template-rows: repeat(15, 1fr);
width: 600px;
height: 600px;
position: relative;
}
.cell {
position: relative;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.cell::before, .cell::after {
content: '';
position: absolute;
background: #8b6914;
}
.cell::before {
width: 100%;
height: 1px;
top: 50%;
transform: translateY(-50%);
}
.cell::after {
width: 1px;
height: 100%;
left: 50%;
transform: translateX(-50%);
}
.piece {
position: absolute;
width: 36px;
height: 36px;
border-radius: 50%;
z-index: 10;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
transform: scale(0);
transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}
.piece.black {
background: radial-gradient(circle at 30% 30%, #555, #000);
}
.piece.white {
background: radial-gradient(circle at 30% 30%, #fff, #ccc);
}
.piece.placed {
transform: scale(1);
}
.controls {
display: flex;
gap: 15px;
margin-top: 10px;
}
button {
padding: 12px 25px;
border: none;
border-radius: 5px;
background: #e94560;
color: white;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 5px 15px rgba(233, 69, 96, 0.4);
}
button:hover {
background: #ff6b81;
transform: translateY(-2px);
}
button:active {
transform: translateY(1px);
}
.mode-selector {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.mode-btn {
background: rgba(255, 255, 255, 0.2);
}
.mode-btn.active {
background: #e94560;
}
.game-message {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0);
background: rgba(0, 0, 0, 0.85);
padding: 30px 50px;
border-radius: 10px;
text-align: center;
z-index: 100;
transition: transform 0.5s;
box-shadow: 0 0 30px rgba(233, 69, 96, 0.7);
}
.game-message.show {
transform: translate(-50%, -50%) scale(1);
}
.game-message h2 {
font-size: 2.5rem;
margin-bottom: 20px;
color: #e94560;
}
.game-message p {
font-size: 1.2rem;
margin-bottom: 20px;
}
.last-move {
position: absolute;
width: 20px;
height: 20px;
border-radius: 50%;
background: #e94560;
z-index: 5;
opacity: 0;
transform: scale(0);
transition: all 0.3s;
}
.last-move.show {
opacity: 1;
transform: scale(1);
}
.ai-thinking {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.7);
padding: 15px 30px;
border-radius: 5px;
font-size: 1.2rem;
z-index: 20;
display: none;
}
.ai-thinking.show {
display: block;
}
.difficulty-selector {
display: flex;
gap: 10px;
margin-bottom: 10px;
}
.difficulty-btn {
background: rgba(255, 255, 255, 0.2);
}
.difficulty-btn.active {
background: #e94560;
}
@media (max-width: 650px) {
.board-grid {
width: 400px;
height: 400px;
}
.piece {
width: 24px;
height: 24px;
}
}
@media (max-width: 450px) {
.board-grid {
width: 320px;
height: 320px;
}
.piece {
width: 18px;
height: 18px;
}
.game-header h1 {
font-size: 2rem;
}
}
</style>
</head>
<body>
<div class="container">
<div class="game-header">
<h1>五子棋 - 极强AI版</h1>
<p>点击棋盘交叉点放置棋子,先连成五子者获胜</p>
</div>
<div class="mode-selector">
<button class="mode-btn active" id="pvpMode">双人对战</button>
<button class="mode-btn" id="pveMode">人机对战</button>
</div>
<div class="difficulty-selector" id="difficultySelector">
<button class="difficulty-btn active" data-level="medium">中等</button>
<button class="difficulty-btn" data-level="hard">困难</button>
<button class="difficulty-btn" data-level="expert">专家</button>
</div>
<div class="game-info">
<div class="player-info black-player current-player">
<div class="player-icon">黑</div>
<div>黑方</div>
</div>
<div class="player-info white-player">
<div class="player-icon">白</div>
<div id="whitePlayerLabel">白方</div>
</div>
</div>
<div class="game-board">
<div class="board-grid" id="board"></div>
<div class="ai-thinking" id="aiThinking">AI思考中...</div>
</div>
<div class="controls">
<button id="restart">重新开始</button>
<button id="undo">悔棋</button>
<button id="hint">提示</button>
</div>
</div>
<div class="game-message" id="gameMessage">
<h2 id="messageTitle">游戏结束</h2>
<p id="messageContent">黑方获胜!</p>
<button id="closeMessage">确定</button>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const board = document.getElementById('board');
const restartBtn = document.getElementById('restart');
const undoBtn = document.getElementById('undo');
const hintBtn = document.getElementById('hint');
const gameMessage = document.getElementById('gameMessage');
const messageTitle = document.getElementById('messageTitle');
const messageContent = document.getElementById('messageContent');
const closeMessage = document.getElementById('closeMessage');
const blackPlayer = document.querySelector('.black-player');
const whitePlayer = document.querySelector('.white-player');
const whitePlayerLabel = document.getElementById('whitePlayerLabel');
const pvpModeBtn = document.getElementById('pvpMode');
const pveModeBtn = document.getElementById('pveMode');
const aiThinking = document.getElementById('aiThinking');
const difficultySelector = document.getElementById('difficultySelector');
const BOARD_SIZE = 15;
let currentPlayer = 'black'; // 黑棋先行
let gameOver = false;
let boardState = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
let moveHistory = [];
let lastMoveMarker = null;
let gameMode = 'pvp'; // 'pvp' 或 'pve'
let aiDifficulty = 'medium'; // 'medium', 'hard', 'expert'
// 初始化棋盘
function initBoard() {
board.innerHTML = '';
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = i;
cell.dataset.col = j;
// 添加棋盘交叉点标记
if ((i === 3 || i === 7 || i === 11) && (j === 3 || j === 7 || j === 11)) {
const dot = document.createElement('div');
dot.style.position = 'absolute';
dot.style.width = '8px';
dot.style.height = '8px';
dot.style.backgroundColor = '#8b6914';
dot.style.borderRadius = '50%';
dot.style.zIndex = '1';
cell.appendChild(dot);
}
cell.addEventListener('click', () => handleCellClick(i, j));
board.appendChild(cell);
}
}
}
// 处理格子点击
function handleCellClick(row, col) {
if (gameOver || boardState[row][col]) return;
// 放置棋子
placePiece(row, col, currentPlayer);
// 检查胜负
if (checkWin(row, col, currentPlayer)) {
gameOver = true;
showGameMessage(`${currentPlayer === 'black' ? '黑方' : '白方'}获胜!`);
return;
}
// 检查平局
if (isBoardFull()) {
gameOver = true;
showGameMessage('平局!');
return;
}
// 切换玩家
currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
updatePlayerIndicator();
// 如果是人机对战模式且轮到AI
if (gameMode === 'pve' && currentPlayer === 'white' && !gameOver) {
setTimeout(() => {
aiThinking.classList.add('show');
setTimeout(() => {
makeAIMove();
aiThinking.classList.remove('show');
}, getAIDelay());
}, 100);
}
}
// 放置棋子
function placePiece(row, col, player) {
boardState[row][col] = player;
moveHistory.push({row, col, player});
const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
const piece = document.createElement('div');
piece.className = `piece ${player}`;
cell.appendChild(piece);
// 添加落子动画
setTimeout(() => {
piece.classList.add('placed');
}, 10);
// 标记最后一步
markLastMove(row, col);
}
// 标记最后一步
function markLastMove(row, col) {
// 移除之前的标记
if (lastMoveMarker) {
lastMoveMarker.classList.remove('show');
}
const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
let marker = cell.querySelector('.last-move');
if (!marker) {
marker = document.createElement('div');
marker.className = 'last-move';
cell.appendChild(marker);
}
marker.classList.add('show');
lastMoveMarker = marker;
}
// 更新玩家指示器
function updatePlayerIndicator() {
if (currentPlayer === 'black') {
blackPlayer.classList.add('current-player');
whitePlayer.classList.remove('current-player');
} else {
whitePlayer.classList.add('current-player');
blackPlayer.classList.remove('current-player');
}
}
// 检查是否获胜
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 <= 4; i++) {
const newRow = row + dx * i;
const newCol = col + dy * i;
if (newRow >= 0 && newRow < BOARD_SIZE &&
newCol >= 0 && newCol < BOARD_SIZE &&
boardState[newRow][newCol] === player) {
count++;
} else {
break;
}
}
// 反向检查
for (let i = 1; i <= 4; i++) {
const newRow = row - dx * i;
const newCol = col - dy * i;
if (newRow >= 0 && newRow < BOARD_SIZE &&
newCol >= 0 && newCol < BOARD_SIZE &&
boardState[newRow][newCol] === player) {
count++;
} else {
break;
}
}
if (count >= 5) {
return true;
}
}
return false;
}
// 检查棋盘是否已满
function isBoardFull() {
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (!boardState[i][j]) {
return false;
}
}
}
return true;
}
// 显示游戏消息
function showGameMessage(message) {
messageContent.textContent = message;
gameMessage.classList.add('show');
}
// 重新开始游戏
function restartGame() {
boardState = Array(BOARD_SIZE).fill().map(() => Array(BOARD_SIZE).fill(null));
moveHistory = [];
currentPlayer = 'black';
gameOver = false;
if (lastMoveMarker) {
lastMoveMarker.classList.remove('show');
}
updatePlayerIndicator();
initBoard();
}
// 悔棋
function undoMove() {
if (gameOver || moveHistory.length === 0) return;
const lastMove = moveHistory.pop();
boardState[lastMove.row][lastMove.col] = null;
const cell = document.querySelector(`.cell[data-row="${lastMove.row}"][data-col="${lastMove.col}"]`);
const piece = cell.querySelector('.piece');
if (piece) {
piece.remove();
}
// 更新最后一步标记
if (moveHistory.length > 0) {
const prevMove = moveHistory[moveHistory.length - 1];
markLastMove(prevMove.row, prevMove.col);
} else if (lastMoveMarker) {
lastMoveMarker.classList.remove('show');
}
// 切换玩家
currentPlayer = lastMove.player;
updatePlayerIndicator();
// 如果是人机对战模式且AI刚下完,需要再悔一步
if (gameMode === 'pve' && lastMove.player === 'white' && moveHistory.length > 0) {
const prevMove = moveHistory.pop();
boardState[prevMove.row][prevMove.col] = null;
const prevCell = document.querySelector(`.cell[data-row="${prevMove.row}"][data-col="${prevMove.col}"]`);
const prevPiece = prevCell.querySelector('.piece');
if (prevPiece) {
prevPiece.remove();
}
// 更新最后一步标记
if (moveHistory.length > 0) {
const newPrevMove = moveHistory[moveHistory.length - 1];
markLastMove(newPrevMove.row, newPrevMove.col);
} else if (lastMoveMarker) {
lastMoveMarker.classList.remove('show');
}
currentPlayer = prevMove.player;
updatePlayerIndicator();
}
}
// 提示功能
function showHint() {
if (gameOver) return;
// 简单提示:随机选择一个空位
const emptyCells = [];
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (!boardState[i][j]) {
emptyCells.push({row: i, col: j});
}
}
}
if (emptyCells.length === 0) return;
const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
const cell = document.querySelector(`.cell[data-row="${randomCell.row}"][data-col="${randomCell.col}"]`);
// 添加提示动画
cell.style.boxShadow = '0 0 15px #e94560';
setTimeout(() => {
cell.style.boxShadow = '';
}, 1000);
}
// 获取AI思考时间
function getAIDelay() {
switch(aiDifficulty) {
case 'medium': return 200;
case 'hard': return 400;
case 'expert': return 600;
default: return 200;
}
}
// AI落子 - 极强版
function makeAIMove() {
if (gameOver) return;
let bestMove;
switch(aiDifficulty) {
case 'medium':
bestMove = getMediumAIMove();
break;
case 'hard':
bestMove = getHardAIMove();
break;
case 'expert':
bestMove = getExpertAIMove();
break;
default:
bestMove = getMediumAIMove();
}
if (bestMove) {
placePiece(bestMove.row, bestMove.col, 'white');
// 检查胜负
if (checkWin(bestMove.row, bestMove.col, 'white')) {
gameOver = true;
showGameMessage('白方(AI)获胜!');
return;
}
// 检查平局
if (isBoardFull()) {
gameOver = true;
showGameMessage('平局!');
return;
}
currentPlayer = 'black';
updatePlayerIndicator();
}
}
// 中等AI - 使用评估函数
function getMediumAIMove() {
let bestScore = -Infinity;
let bestMove = null;
// 只考虑有棋子相邻的位置,减少计算量
const candidateMoves = getCandidateMoves();
for (const move of candidateMoves) {
// 模拟在此位置落子
boardState[move.row][move.col] = 'white';
// 计算得分
const score = evaluateBoard('white');
// 撤销模拟落子
boardState[move.row][move.col] = null;
if (score > bestScore) {
bestScore = score;
bestMove = move;
}
}
return bestMove;
}
// 困难AI - 使用快速搜索
function getHardAIMove() {
let bestScore = -Infinity;
let bestMove = null;
// 只考虑有棋子相邻的位置,减少计算量
const candidateMoves = getCandidateMoves();
// 对候选位置进行初步评估,选择前几个最好的进行深度搜索
const scoredMoves = [];
for (const move of candidateMoves) {
boardState[move.row][move.col] = 'white';
const score = evaluateBoard('white');
boardState[move.row][move.col] = null;
scoredMoves.push({move, score});
}
// 按分数排序,选择前5个进行快速搜索
scoredMoves.sort((a, b) => b.score - a.score);
const topMoves = scoredMoves.slice(0, 5);
for (const {move} of topMoves) {
// 模拟在此位置落子
boardState[move.row][move.col] = 'white';
// 使用快速Minimax算法计算得分
const score = fastMinimax(2, false, -Infinity, Infinity);
// 撤销模拟落子
boardState[move.row][move.col] = null;
if (score > bestScore) {
bestScore = score;
bestMove = move;
}
}
return bestMove || getMediumAIMove();
}
// 专家AI - 使用更深的搜索和更复杂的评估
function getExpertAIMove() {
let bestScore = -Infinity;
let bestMove = null;
// 只考虑有棋子相邻的位置,减少计算量
const candidateMoves = getCandidateMoves();
// 对候选位置进行初步评估,选择前几个最好的进行深度搜索
const scoredMoves = [];
for (const move of candidateMoves) {
boardState[move.row][move.col] = 'white';
const score = evaluateBoard('white');
boardState[move.row][move.col] = null;
scoredMoves.push({move, score});
}
// 按分数排序,选择前7个进行深度搜索
scoredMoves.sort((a, b) => b.score - a.score);
const topMoves = scoredMoves.slice(0, 7);
for (const {move} of topMoves) {
// 模拟在此位置落子
boardState[move.row][move.col] = 'white';
// 使用快速Minimax算法计算得分
const score = fastMinimax(3, false, -Infinity, Infinity);
// 撤销模拟落子
boardState[move.row][move.col] = null;
if (score > bestScore) {
bestScore = score;
bestMove = move;
}
}
return bestMove || getHardAIMove();
}
// 快速Minimax算法
function fastMinimax(depth, isMaximizing, alpha, beta) {
// 检查游戏是否结束或达到最大深度
if (depth === 0 || isGameOver()) {
return evaluateBoard('white');
}
if (isMaximizing) {
let maxScore = -Infinity;
const candidateMoves = getCandidateMoves();
// 只考虑前几个候选位置
const topMoves = candidateMoves.slice(0, 6);
for (const move of topMoves) {
boardState[move.row][move.col] = 'white';
const score = fastMinimax(depth - 1, false, alpha, beta);
boardState[move.row][move.col] = null;
maxScore = Math.max(maxScore, score);
alpha = Math.max(alpha, score);
if (beta <= alpha) {
break; // Beta剪枝
}
}
return maxScore;
} else {
let minScore = Infinity;
const candidateMoves = getCandidateMoves();
// 只考虑前几个候选位置
const topMoves = candidateMoves.slice(0, 6);
for (const move of topMoves) {
boardState[move.row][move.col] = 'black';
const score = fastMinimax(depth - 1, true, alpha, beta);
boardState[move.row][move.col] = null;
minScore = Math.min(minScore, score);
beta = Math.min(beta, score);
if (beta <= alpha) {
break; // Alpha剪枝
}
}
return minScore;
}
}
// 检查游戏是否结束
function isGameOver() {
// 检查是否有玩家获胜
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (boardState[i][j] && checkWin(i, j, boardState[i][j])) {
return true;
}
}
}
// 检查棋盘是否已满
return isBoardFull();
}
// 获取候选落子位置(只考虑有棋子相邻的位置)
function getCandidateMoves() {
const candidateMoves = [];
const directions = [
[-1, -1], [-1, 0], [-1, 1],
[0, -1], [0, 1],
[1, -1], [1, 0], [1, 1]
];
// 如果有棋子,只考虑棋子周围的空位
let hasPieces = false;
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (boardState[i][j]) {
hasPieces = true;
// 检查周围的空位
for (const [dx, dy] of directions) {
const newRow = i + dx;
const newCol = j + dy;
if (newRow >= 0 && newRow < BOARD_SIZE &&
newCol >= 0 && newCol < BOARD_SIZE &&
!boardState[newRow][newCol]) {
// 避免重复添加
if (!candidateMoves.some(move => move.row === newRow && move.col === newCol)) {
candidateMoves.push({row: newRow, col: newCol});
}
}
}
}
}
}
// 如果没有候选位置,返回所有空位
if (!hasPieces || candidateMoves.length === 0) {
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (!boardState[i][j]) {
candidateMoves.push({row: i, col: j});
}
}
}
}
return candidateMoves;
}
// 评估棋盘状态 - 极强版
function evaluateBoard(player) {
let score = 0;
// 评估每个位置
for (let i = 0; i < BOARD_SIZE; i++) {
for (let j = 0; j < BOARD_SIZE; j++) {
if (boardState[i][j] === player) {
score += evaluatePosition(i, j, player);
} else if (boardState[i][j] && boardState[i][j] !== player) {
score -= evaluatePosition(i, j, getOpponent(player)) * 1.5; // 对手的威胁权重增加
}
}
}
// 考虑中心控制
for (let i = 5; i <= 9; i++) {
for (let j = 5; j <= 9; j++) {
if (boardState[i][j] === player) {
score += 15;
} else if (boardState[i][j] === getOpponent(player)) {
score -= 15;
}
}
}
return score;
}
// 获取对手
function getOpponent(player) {
return player === 'white' ? 'black' : 'white';
}
// 评估位置得分 - 极强版
function evaluatePosition(row, col, player) {
let score = 0;
// 评估四个方向
const directions = [
[0, 1], // 水平
[1, 0], // 垂直
[1, 1], // 对角线
[1, -1] // 反对角线
];
for (const [dx, dy] of directions) {
// 计算连续棋子数量
let count = 1; // 当前位置
let openEnds = 0;
// 正向检查
let blocked = false;
for (let i = 1; i <= 4; i++) {
const newRow = row + dx * i;
const newCol = col + dy * i;
if (newRow >= 0 && newRow < BOARD_SIZE &&
newCol >= 0 && newCol < BOARD_SIZE) {
if (boardState[newRow][newCol] === player) {
count++;
} else if (boardState[newRow][newCol] === null) {
openEnds++;
break;
} else {
blocked = true;
break;
}
} else {
blocked = true;
break;
}
}
// 反向检查
for (let i = 1; i <= 4; i++) {
const newRow = row - dx * i;
const newCol = col - dy * i;
if (newRow >= 0 && newRow < BOARD_SIZE &&
newCol >= 0 && newCol < BOARD_SIZE) {
if (boardState[newRow][newCol] === player) {
count++;
} else if (boardState[newRow][newCol] === null) {
openEnds++;
break;
} else {
blocked = true;
break;
}
} else {
blocked = true;
break;
}
}
// 根据连续棋子和开放端评分
if (count >= 5) {
score += 1000000; // 五连
} else if (count === 4) {
if (openEnds === 2) {
score += 50000; // 活四
} else if (openEnds === 1) {
score += 10000; // 冲四
}
} else if (count === 3) {
if (openEnds === 2) {
score += 5000; // 活三
} else if (openEnds === 1) {
score += 1000; // 眠三
}
} else if (count === 2) {
if (openEnds === 2) {
score += 500; // 活二
} else if (openEnds === 1) {
score += 100; // 眠二
}
} else if (count === 1 && openEnds === 2) {
score += 10; // 活一
}
// 特殊棋型:双三、四三等
if (count === 3 && openEnds === 2) {
// 检查是否形成双三
score += 3000;
}
// 检查双四
if (count === 4 && openEnds === 2) {
score += 20000;
}
}
return score;
}
// 切换游戏模式
function switchGameMode(mode) {
gameMode = mode;
if (mode === 'pvp') {
pvpModeBtn.classList.add('active');
pveModeBtn.classList.remove('active');
whitePlayerLabel.textContent = '白方';
difficultySelector.style.display = 'none';
restartGame();
} else {
pveModeBtn.classList.add('active');
pvpModeBtn.classList.remove('active');
whitePlayerLabel.textContent = 'AI';
difficultySelector.style.display = 'flex';
restartGame();
}
}
// 切换AI难度
function switchAIDifficulty(level) {
aiDifficulty = level;
// 更新难度按钮状态
document.querySelectorAll('.difficulty-btn').forEach(btn => {
btn.classList.remove('active');
});
event.target.classList.add('active');
}
// 事件监听
restartBtn.addEventListener('click', restartGame);
undoBtn.addEventListener('click', undoMove);
hintBtn.addEventListener('click', showHint);
closeMessage.addEventListener('click', () => {
gameMessage.classList.remove('show');
});
pvpModeBtn.addEventListener('click', () => switchGameMode('pvp'));
pveModeBtn.addEventListener('click', () => switchGameMode('pve'));
difficultySelector.addEventListener('click', (e) => {
if (e.target.classList.contains('difficulty-btn')) {
switchAIDifficulty(e.target.dataset.level);
}
});
// 初始化游戏
initBoard();
});
</script>
</body>
</html>