<!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;
}
:root {
--primary-dark: #0f172a;
--secondary-dark: #1e293b;
--accent-gold: #f59e0b;
--accent-silver: #94a3b8;
--text-light: #f1f5f9;
--text-gray: #cbd5e1;
--board-light: #f0d9b5;
--board-dark: #8b6914;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, var(--primary-dark) 0%, #000 100%);
color: var(--text-light);
min-height: 100vh;
overflow-x: hidden;
}
/* 导航栏 */
header {
padding: 1.5rem 5%;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(15, 23, 42, 0.9);
backdrop-filter: blur(10px);
position: fixed;
width: 100%;
top: 0;
z-index: 1000;
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
}
.logo {
font-size: 1.5rem;
font-weight: bold;
display: flex;
align-items: center;
gap: 0.5rem;
}
.logo::before {
content: '♔';
font-size: 2rem;
color: var(--accent-gold);
}
nav ul {
display: flex;
list-style: none;
gap: 2rem;
}
nav a {
color: var(--text-gray);
text-decoration: none;
transition: color 0.3s;
font-weight: 500;
}
nav a:hover {
color: var(--accent-gold);
}
/* 主游戏区域 */
.game-section {
margin-top: 80px;
padding: 2rem 5%;
max-width: 1400px;
margin-left: auto;
margin-right: auto;
display: grid;
grid-template-columns: 1fr 2fr 1fr;
gap: 2rem;
align-items: start;
}
/* 左侧控制面板 */
.control-panel {
background: rgba(30, 41, 59, 0.6);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid rgba(148, 163, 184, 0.1);
}
.control-panel h3 {
color: var(--accent-gold);
margin-bottom: 1rem;
font-size: 1.2rem;
}
.game-controls {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 2rem;
}
.btn {
padding: 0.75rem 1rem;
border: none;
border-radius: 6px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
display: inline-block;
text-align: center;
}
.btn-primary {
background: linear-gradient(135deg, var(--accent-gold) 0%, #d97706 100%);
color: var(--primary-dark);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(245, 158, 11, 0.3);
}
.btn-secondary {
background: transparent;
color: var(--accent-silver);
border: 2px solid var(--accent-silver);
}
.btn-secondary:hover {
background: var(--accent-silver);
color: var(--primary-dark);
}
.move-history {
max-height: 300px;
overflow-y: auto;
background: rgba(15, 23, 42, 0.4);
border-radius: 6px;
padding: 1rem;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
}
.move-item {
padding: 0.25rem 0;
color: var(--text-gray);
border-bottom: 1px solid rgba(148, 163, 184, 0.1);
}
.move-item:last-child {
border-bottom: none;
}
/* 中央棋盘 */
.chess-board-container {
background: rgba(30, 41, 59, 0.6);
border-radius: 12px;
padding: 2rem;
border: 1px solid rgba(148, 163, 184, 0.1);
display: flex;
flex-direction: column;
align-items: center;
}
.board-status {
margin-bottom: 1rem;
text-align: center;
}
.current-player-display {
font-size: 1.5rem;
font-weight: bold;
padding: 0.5rem 2rem;
border-radius: 8px;
display: inline-block;
}
.current-player-display.white {
background: linear-gradient(135deg, #fff 0%, #f0f0f0 100%);
color: var(--primary-dark);
}
.current-player-display.black {
background: linear-gradient(135deg, #000 0%, #333 100%);
color: #fff;
}
.chess-board {
display: grid;
grid-template-columns: repeat(8, 60px);
grid-template-rows: repeat(8, 60px);
border: 3px solid var(--secondary-dark);
border-radius: 6px;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
margin: 1rem 0;
}
.board-square {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s;
position: relative;
}
.board-square.light {
background: var(--board-light);
}
.board-square.dark {
background: var(--board-dark);
}
.board-square.selected {
background: #7fb069 !important;
box-shadow: inset 0 0 10px rgba(0,0,0,0.3);
}
.board-square.valid-move {
background: #4ecdc4 !important;
position: relative;
}
.board-square.valid-move::after {
content: '';
position: absolute;
width: 20px;
height: 20px;
background: rgba(78, 205, 196, 0.7);
border-radius: 50%;
}
.board-square.check {
background: #e74c3c !important;
}
.board-square.king-captured {
background: #9b59b6 !important;
animation: pulse 1s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}
.chess-piece {
font-size: 2.5rem;
cursor: pointer;
transition: transform 0.3s;
user-select: none;
z-index: 10;
}
.chess-piece:hover {
transform: scale(1.1);
}
.chess-piece.dragging {
opacity: 0.5;
cursor: grabbing;
}
/* 右侧信息面板 */
.info-panel {
background: rgba(30, 41, 59, 0.6);
border-radius: 12px;
padding: 1.5rem;
border: 1px solid rgba(148, 163, 184, 0.1);
}
.info-section {
margin-bottom: 2rem;
}
.info-section h3 {
color: var(--accent-gold);
margin-bottom: 0.75rem;
font-size: 1.1rem;
}
.info-section p {
color: var(--text-gray);
line-height: 1.6;
font-size: 0.9rem;
}
.captured-pieces {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 0.5rem;
}
.captured-piece {
font-size: 1.5rem;
opacity: 0.7;
}
/* 响应式设计 */
@media (max-width: 1200px) {
.game-section {
grid-template-columns: 1fr;
gap: 1rem;
}
.chess-board-container {
order: -1;
}
.chess-board {
grid-template-columns: repeat(8, 50px);
grid-template-rows: repeat(8, 50px);
}
.board-square {
width: 50px;
height: 50px;
}
.chess-piece {
font-size: 2rem;
}
}
@media (max-width: 600px) {
.chess-board {
grid-template-columns: repeat(8, 40px);
grid-template-rows: repeat(8, 40px);
}
.board-square {
width: 40px;
height: 40px;
}
.chess-piece {
font-size: 1.5rem;
}
}
/* 游戏结束覆盖层 */
.game-over-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.8);
display: none;
align-items: center;
justify-content: center;
z-index: 2000;
}
.game-over-modal {
background: var(--secondary-dark);
border-radius: 12px;
padding: 3rem;
text-align: center;
border: 2px solid var(--accent-gold);
max-width: 500px;
width: 90%;
}
.game-over-modal h2 {
color: var(--accent-gold);
font-size: 2.5rem;
margin-bottom: 1rem;
}
.game-over-modal p {
font-size: 1.2rem;
margin-bottom: 2rem;
color: var(--text-gray);
}
.game-over-modal .reason {
font-size: 1.4rem;
font-weight: bold;
color: #e74c3c;
margin-bottom: 1rem;
}
/* 警告提示 */
.warning-message {
position: fixed;
top: 100px;
left: 50%;
transform: translateX(-50%);
background: rgba(231, 76, 60, 0.9);
color: white;
padding: 1rem 2rem;
border-radius: 8px;
font-weight: bold;
display: none;
z-index: 1500;
animation: slideDown 0.3s ease-out;
}
@keyframes slideDown {
from {
transform: translateX(-50%) translateY(-100px);
opacity: 0;
}
to {
transform: translateX(-50%) translateY(0);
opacity: 1;
}
}
</style>
</head>
<body>
<header>
<div class="logo">国际象棋大师</div>
<nav>
<ul>
<li><a href="#play">开始对局</a></li>
<li><a href="#learn">学习规则</a></li>
<li><a href="#puzzles">战术谜题</a></li>
<li><a href="#about">关于我们</a></li>
</ul>
</nav>
</header>
<section class="game-section" id="play">
<!-- 左侧控制面板 -->
<aside class="control-panel">
<h3>游戏控制</h3>
<div class="game-controls">
<button class="btn btn-primary" onclick="resetGame()">🔄 新游戏</button>
<button class="btn btn-secondary" onclick="undoMove()">↩️ 悔棋</button>
<button class="btn btn-secondary" onclick="flipBoard()">🔄 翻转棋盘</button>
<button class="btn btn-secondary" onclick="showHint()">💡 提示</button>
</div>
<h3>对局记录</h3>
<div class="move-history" id="moveHistory">
<div class="move-item">等待开始对局...</div>
</div>
</aside>
<!-- 中央棋盘 -->
<main class="chess-board-container">
<div class="board-status">
<div class="current-player-display white" id="currentPlayerDisplay">
白方回合
</div>
</div>
<div class="chess-board" id="chessBoard"></div>
<div style="margin-top: 1rem; text-align: center;">
<small style="color: var(--text-gray);">点击棋子选择,点击目标位置移动</small>
</div>
</main>
<!-- 右侧信息面板 -->
<aside class="info-panel">
<div class="info-section">
<h3>游戏状态</h3>
<p id="gameStatus">对局进行中</p>
</div>
<div class="info-section">
<h3>被吃掉的棋子</h3>
<div class="captured-pieces" id="capturedPieces">
</div>
</div>
<div class="info-section">
<h3>快速规则</h3>
<p style="font-size: 0.85rem; line-height: 1.4;">
♔ 王:横、直、斜走一格<br>
♕ 后:横、直、斜任意格<br>
♖ 车:横、直任意格<br>
♗ 象:斜线任意格<br>
♞ 马:日字形移动<br>
♟ 兵:前进一格,吃子斜一格
</p>
</div>
<div class="info-section">
<h3>特殊规则</h3>
<p style="font-size: 0.85rem; line-height: 1.4;">
• 王车易位:王和车未移动,王车之间无棋子<br>
• 吃过路兵:对方兵跳两格时可斜吃<br>
• 升变:兵到达底线可变成后、车、象或马
</p>
</div>
</aside>
</section>
<!-- 游戏结束覆盖层 -->
<div class="game-over-overlay" id="gameOverOverlay">
<div class="game-over-modal">
<h2 id="gameOverTitle">游戏结束</h2>
<p class="reason" id="gameOverReason">王被吃掉!</p>
<p id="gameOverMessage">获胜方:白方</p>
<button class="btn btn-primary" onclick="resetGame()">再玩一局</button>
</div>
</div>
<!-- 警告提示 -->
<div class="warning-message" id="warningMessage"></div>
<script>
// 国际象棋游戏逻辑
class ChessGame {
constructor() {
this.board = \[\];
this.currentPlayer = 'white';
this.selectedSquare = null;
this.moveHistory = \[\];
this.capturedPieces = { white: \[\], black: \[\] };
this.kingPositions = { white: 7, 4, black: 0, 4 };
this.castlingRights = { white: { king: true, queen: true }, black: { king: true, queen: true } };
this.gameOver = false;
this.pieces = {
'K': '♔', 'Q': '♕', 'R': '♖', 'B': '♗', 'N': '♘', 'P': '♙',
'k': '♚', 'q': '♛', 'r': '♜', 'b': '♝', 'n': '♞', 'p': '♟'
};
this.initializeBoard();
this.renderBoard();
}
initializeBoard() {
// 初始化8x8棋盘
for (let row = 0; row < 8; row++) {
this.boardrow = \[\];
for (let col = 0; col < 8; col++) {
this.boardrowcol = '';
}
}
// 摆放棋子
// 黑方(上方)
this.board0 = 'r', 'n', 'b', 'q', 'k', 'b', 'n', 'r';
this.board1 = 'p', 'p', 'p', 'p', 'p', 'p', 'p', 'p';
// 白方(下方)
this.board6 = 'P', 'P', 'P', 'P', 'P', 'P', 'P', 'P';
this.board7 = 'R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R';
}
renderBoard() {
const boardElement = document.getElementById('chessBoard');
boardElement.innerHTML = '';
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const square = document.createElement('div');
square.className = `board-square ${(row + col) % 2 === 0 ? 'light' : 'dark'}`;
square.dataset.row = row;
square.dataset.col = col;
const piece = this.boardrowcol;
if (piece) {
const pieceElement = document.createElement('span');
pieceElement.className = 'chess-piece';
pieceElement.textContent = this.piecespiece;
pieceElement.dataset.piece = piece;
square.appendChild(pieceElement);
}
if (this.kingPositions.white0 === row && this.kingPositions.white1 === col && this.isKingInCheck('white')) {
square.classList.add('check');
}
if (this.kingPositions.black0 === row && this.kingPositions.black1 === col && this.isKingInCheck('black')) {
square.classList.add('check');
}
square.onclick = () => this.handleSquareClick(row, col);
boardElement.appendChild(square);
}
}
this.updateDisplay();
}
handleSquareClick(row, col) {
if (this.gameOver) return;
if (this.selectedSquare) {
const fromRow = this.selectedSquare0;
const fromCol = this.selectedSquare1;
if (fromRow === row && fromCol === col) {
// 取消选择
this.selectedSquare = null;
this.renderBoard();
} else if (this.isValidMove(fromRow, fromCol, row, col)) {
// 执行移动
this.makeMove(fromRow, fromCol, row, col);
} else {
// 重新选择
this.selectedSquare = row, col;
this.highlightMoves(fromRow, fromCol, row, col);
}
} else {
// 选择棋子
const piece = this.boardrowcol;
if (piece && this.getPieceColor(piece) === this.currentPlayer) {
this.selectedSquare = row, col;
this.highlightMoves(row, col);
}
}
}
highlightMoves(row, col) {
this.renderBoard();
const validMoves = this.getValidMoves(row, col);
validMoves.forEach((toRow, toCol) => {
const square = document.querySelector(`data-row="${toRow}"data-col="${toCol}"`);
if (square) {
square.classList.add('valid-move');
}
});
const selectedSquare = document.querySelector(`data-row="${row}"data-col="${col}"`);
if (selectedSquare) {
selectedSquare.classList.add('selected');
}
}
getPieceColor(piece) {
return piece === piece.toUpperCase() ? 'white' : 'black';
}
isValidMove(fromRow, fromCol, toRow, toCol) {
const piece = this.boardfromRowfromCol;
const targetPiece = this.boardtoRowtoCol;
if (!piece || this.getPieceColor(piece) !== this.currentPlayer) return false;
if (targetPiece && this.getPieceColor(targetPiece) === this.currentPlayer) return false;
const moves = this.getValidMoves(fromRow, fromCol);
return moves.some((r, c) => r === toRow && c === toCol);
}
getValidMoves(row, col) {
const piece = this.boardrowcol;
const color = this.getPieceColor(piece);
const moves = \[\];
switch (piece.toUpperCase()) {
case 'P':
moves.push(...this.getPawnMoves(row, col, color));
break;
case 'R':
moves.push(...this.getRookMoves(row, col, color));
break;
case 'N':
moves.push(...this.getKnightMoves(row, col, color));
break;
case 'B':
moves.push(...this.getBishopMoves(row, col, color));
break;
case 'Q':
moves.push(...this.getQueenMoves(row, col, color));
break;
case 'K':
moves.push(...this.getKingMoves(row, col, color));
break;
}
// 过滤会导致己方被将军的走法
return moves.filter((toRow, toCol) => {
const tempBoard = this.board.map(row => ...row);
tempBoardtoRowtoCol = tempBoardrowcol;
tempBoardrowcol = '';
const tempKingPos = { ...this.kingPositions };
if (piece.toUpperCase() === 'K') {
tempKingPoscolor = toRow, toCol;
}
return !this.isKingInCheck(color, tempBoard, tempKingPos);
});
}
getPawnMoves(row, col, color) {
const moves = \[\];
const direction = color === 'white' ? -1 : 1;
const startRow = color === 'white' ? 6 : 1;
// 前进
if (this.boardrow + direction && this.boardrow + directioncol === '') {
moves.push(row + direction, col);
// 初始位置可以走两格
if (row === startRow && this.boardrow + 2 \* directioncol === '') {
moves.push(row + 2 \* direction, col);
}
}
// 吃子
-1, 1.forEach(offset => {
if (this.boardrow + direction && this.boardrow + directioncol + offset) {
const target = this.boardrow + directioncol + offset;
if (target && this.getPieceColor(target) !== color) {
moves.push(row + direction, col + offset);
}
}
});
return moves;
}
getRookMoves(row, col, color) {
return this.getLineMoves(row, col, \[0, 1, 1, 0, 0, -1, -1, 0], color);
}
getBishopMoves(row, col, color) {
return this.getLineMoves(row, col, \[1, 1, 1, -1, -1, 1, -1, -1], color);
}
getQueenMoves(row, col, color) {
return [
...this.getRookMoves(row, col, color),
...this.getBishopMoves(row, col, color)
];
}
getKnightMoves(row, col, color) {
const moves = \[\];
const knightMoves = [
2, 1, 2, -1, -2, 1, -2, -1,
1, 2\], \[1, -2\], \[-1, 2\], \[-1, -2
];
knightMoves.forEach((dr, dc) => {
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {
const target = this.boardnewRownewCol;
if (!target || this.getPieceColor(target) !== color) {
moves.push(newRow, newCol);
}
}
});
return moves;
}
getKingMoves(row, col, color) {
const moves = \[\];
for (let dr = -1; dr <= 1; dr++) {
for (let dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) continue;
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {
const target = this.boardnewRownewCol;
if (!target || this.getPieceColor(target) !== color) {
moves.push(newRow, newCol);
}
}
}
}
return moves;
}
getLineMoves(row, col, directions, color) {
const moves = \[\];
directions.forEach((dr, dc) => {
let newRow = row + dr;
let newCol = col + dc;
while (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {
const target = this.boardnewRownewCol;
if (!target) {
moves.push(newRow, newCol);
} else {
if (this.getPieceColor(target) !== color) {
moves.push(newRow, newCol);
}
break;
}
newRow += dr;
newCol += dc;
}
});
return moves;
}
isKingInCheck(color, board = this.board, kingPos = this.kingPositions) {
const kingRow, kingCol = kingPoscolor;
// 检查对方所有棋子是否能吃到王
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const piece = boardrowcol;
if (piece && this.getPieceColor(piece) !== color) {
const moves = this.getPotentialMoves(row, col, board);
if (moves.some((r, c) => r === kingRow && c === kingCol)) {
return true;
}
}
}
}
return false;
}
getPotentialMoves(row, col, board) {
const piece = boardrowcol;
const color = this.getPieceColor(piece);
const moves = \[\];
switch (piece.toUpperCase()) {
case 'P':
const direction = color === 'white' ? -1 : 1;
-1, 1.forEach(offset => {
if (boardrow + direction && boardrow + directioncol + offset) {
moves.push(row + direction, col + offset);
}
});
break;
case 'N':
const knightMoves = [
2, 1, 2, -1, -2, 1, -2, -1,
1, 2\], \[1, -2\], \[-1, 2\], \[-1, -2
];
knightMoves.forEach((dr, dc) => {
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= 0 && newRow < 8 && newCol >= 0 && newCol < 8) {
moves.push(newRow, newCol);
}
});
break;
case 'K':
for (let dr = -1; dr <= 1; dr++) {
for (let dc = -1; dc <= 1; dc++) {
if (dr === 0 && dc === 0) continue;
moves.push(row + dr, col + dc);
}
}
break;
case 'R':
moves.push(...this.getLineMoves(row, col, \[0, 1, 1, 0, 0, -1, -1, 0], color, board));
break;
case 'B':
moves.push(...this.getLineMoves(row, col, \[1, 1, 1, -1, -1, 1, -1, -1], color, board));
break;
case 'Q':
moves.push(...this.getLineMoves(row, col, \[0, 1, 1, 0, 0, -1, -1, 0, 1, 1, 1, -1, -1, 1, -1, -1], color, board));
break;
}
return moves;
}
makeMove(fromRow, fromCol, toRow, toCol) {
const piece = this.boardfromRowfromCol;
const capturedPiece = this.boardtoRowtoCol;
// 记录移动
const moveNotation = this.getMoveNotation(fromRow, fromCol, toRow, toCol, capturedPiece);
this.moveHistory.push(moveNotation);
// 处理被吃掉的棋子
if (capturedPiece) {
this.capturedPiecesthis.getPieceColor(capturedPiece).push(this.piecescapturedPiece);
// 检查是否吃掉王
if (capturedPiece.toUpperCase() === 'K') {
this.handleKingCaptured(this.getPieceColor(capturedPiece));
return;
}
}
// 移动棋子
this.boardtoRowtoCol = this.boardfromRowfromCol;
this.boardfromRowfromCol = '';
// 更新王的位置
if (piece.toUpperCase() === 'K') {
this.kingPositionsthis.currentPlayer = toRow, toCol;
}
// 检查升变
if (piece.toUpperCase() === 'P' && (toRow === 0 || toRow === 7)) {
this.boardtoRowtoCol = piece.toUpperCase() === 'P' ? 'Q' : 'q';
}
// 切换玩家
this.currentPlayer = this.currentPlayer === 'white' ? 'black' : 'white';
this.selectedSquare = null;
this.renderBoard();
this.updateHistory();
// 检查游戏状态
this.checkGameState();
}
handleKingCaptured(loserColor) {
this.gameOver = true;
const winner = loserColor === 'white' ? '黑方' : '白方';
const loser = loserColor === 'white' ? '白方' : '黑方';
// 显示警告动画
this.showWarning(`${loser}的王被吃掉了!`);
// 延迟显示游戏结束弹窗
setTimeout(() => {
this.showGameOver(`{winner}获胜!\`, \`{loser}的王被吃掉`, 'king-captured');
}, 1500);
// 标记被吃掉王的位置
const kingPos = this.kingPositionsloserColor;
const square = document.querySelector(`data-row="${kingPos\[0}"]data-col="${kingPos\[1}"]`);
if (square) {
square.classList.add('king-captured');
}
}
showWarning(message) {
const warningElement = document.getElementById('warningMessage');
warningElement.textContent = message;
warningElement.style.display = 'block';
setTimeout(() => {
warningElement.style.display = 'none';
}, 3000);
}
getMoveNotation(fromRow, fromCol, toRow, toCol, capturedPiece) {
const piece = this.boardfromRowfromCol;
const files = 'abcdefgh';
const ranks = '87654321';
let notation = '';
// 棋子符号(兵不写)
if (piece.toUpperCase() !== 'P') {
notation += piece.toUpperCase();
}
// 吃子标记
if (capturedPiece) {
if (piece.toUpperCase() === 'P') {
notation += filesfromCol;
}
notation += 'x';
}
// 目标位置
notation += filestoCol + rankstoRow;
return notation;
}
updateHistory() {
const historyElement = document.getElementById('moveHistory');
historyElement.innerHTML = this.moveHistory.map((move, i) => {
if (i % 2 === 0) {
return `<div class="move-item">{Math.floor(i / 2) + 1}. {move}</div>`;
} else {
return `<div class="move-item">${move}</div>`;
}
}).join('');
historyElement.scrollTop = historyElement.scrollHeight;
}
updateDisplay() {
const display = document.getElementById('currentPlayerDisplay');
if (this.gameOver) {
display.textContent = '游戏结束';
} else {
display.textContent = `{this.currentPlayer === 'white' ? '⚪' : '⚫'} {this.currentPlayer === 'white' ? '白方' : '黑方'}回合`;
}
display.className = `current-player-display ${this.currentPlayer}`;
}
checkKingExistence() {
let whiteKingExists = false;
let blackKingExists = false;
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const piece = this.boardrowcol;
if (piece) {
if (piece === 'K') whiteKingExists = true;
if (piece === 'k') blackKingExists = true;
}
}
}
if (!whiteKingExists) {
return { gameOver: true, winner: 'black', loser: 'white', reason: '白方王被吃' };
}
if (!blackKingExists) {
return { gameOver: true, winner: 'white', loser: 'black', reason: '黑方王被吃' };
}
return { gameOver: false };
}
checkGameState() {
// 首先检查王是否存在
const kingCheck = this.checkKingExistence();
if (kingCheck.gameOver) {
this.handleKingCaptured(kingCheck.loser);
return;
}
// 检查是否有合法移动
let hasValidMove = false;
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const piece = this.boardrowcol;
if (piece && this.getPieceColor(piece) === this.currentPlayer) {
if (this.getValidMoves(row, col).length > 0) {
hasValidMove = true;
break;
}
}
}
if (hasValidMove) break;
}
if (!hasValidMove) {
const isInCheck = this.isKingInCheck(this.currentPlayer);
if (isInCheck) {
const winner = this.currentPlayer === 'white' ? '黑方' : '白方';
const reason = '将死';
this.showGameOver(`${winner}获胜!`, reason);
} else {
this.showGameOver('平局!', '逼和');
}
}
}
showGameOver(result, reason, type = '') {
this.gameOver = true;
document.getElementById('gameOverTitle').textContent = result;
document.getElementById('gameOverReason').textContent = reason;
document.getElementById('gameOverMessage').textContent = `获胜方:${result.includes('白方') ? '白方' : '黑方'}`;
document.getElementById('gameOverOverlay').style.display = 'flex';
// 更新游戏状态显示
this.updateDisplay();
}
reset() {
this.board = \[\];
this.currentPlayer = 'white';
this.selectedSquare = null;
this.moveHistory = \[\];
this.capturedPieces = { white: \[\], black: \[\] };
this.kingPositions = { white: 7, 4, black: 0, 4 };
this.castlingRights = { white: { king: true, queen: true }, black: { king: true, queen: true } };
this.gameOver = false;
this.initializeBoard();
this.renderBoard();
this.updateHistory();
document.getElementById('gameOverOverlay').style.display = 'none';
document.getElementById('warningMessage').style.display = 'none';
}
undoMove() {
if (this.moveHistory.length > 0) {
this.moveHistory.pop();
// 简化实现:重置棋盘
this.reset();
}
}
}
// 全局实例
let game = null;
// 页面加载完成后初始化
document.addEventListener('DOMContentLoaded', function() {
game = new ChessGame();
});
// 全局函数
function resetGame() {
game.reset();
}
function undoMove() {
game.undoMove();
}
function flipBoard() {
alert('翻转棋盘功能开发中...');
}
function showHint() {
alert('提示功能开发中...');
}
</script>
</body>
</html>