提示词1: 使用html实现中国象棋游戏,要求支持人机对弈,注意棋盘布局和棋子的正确位置,棋子的正确走法等。
迭代提示词:九宫格不对,红棋子不吃对方的子,就不能走是不对的。楚河汉界不应该有竖线。
实测效果如上,迭代不能变得更好。
1、棋盘画不对,迭代也不能修改正确;
2、红色棋子不能走,除非吃掉对方的棋子,迭代不能修改正确。
具体代码如下:
<!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 {
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
margin: 0;
padding: 20px;
display: flex;
flex-direction: column;
align-items: center;
min-height: 100vh;
}
.game-container {
background: white;
border-radius: 15px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
text-align: center;
}
h1 {
color: #333;
margin-bottom: 20px;
}
.chessboard {
width: 480px;
height: 540px;
background: #f0d9b5;
border: 3px solid #8b4513;
position: relative;
margin: 0 auto;
}
.board-grid {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.board-line {
position: absolute;
background: #000;
}
.horizontal-line {
width: 100%;
height: 1px;
}
.vertical-line {
width: 1px;
height: 100%;
}
.river {
position: absolute;
width: 100%;
height: 60px;
top: 240px;
display: flex;
justify-content: space-around;
align-items: center;
font-size: 24px;
color: #8b4513;
font-weight: bold;
}
.chess-pieces {
position: relative;
width: 100%;
height: 100%;
}
.piece {
position: absolute;
width: 45px;
height: 45px;
border-radius: 50%;
border: 2px solid #8b4513;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
transform: translate(-50%, -50%);
z-index: 10;
}
.piece.red {
background: #ff6b6b;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
.piece.black {
background: #2c3e50;
color: white;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
.piece.selected {
box-shadow: 0 0 15px #ffd700;
transform: translate(-50%, -50%) scale(1.1);
}
.piece.valid-move::after {
content: "";
position: absolute;
width: 15px;
height: 15px;
border-radius: 50%;
background: rgba(0, 255, 0, 0.5);
}
.game-info {
margin: 20px 0;
padding: 15px;
background: #ecf0f1;
border-radius: 10px;
font-size: 18px;
font-weight: bold;
}
.controls {
margin: 20px 0;
}
button {
background: #3498db;
color: white;
border: none;
padding: 12px 24px;
margin: 0 10px;
border-radius: 25px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: all 0.3s ease;
}
button:hover {
background: #2980b9;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
button:active {
transform: translateY(0);
}
.difficulty {
margin: 15px 0;
}
select {
padding: 8px 12px;
border-radius: 5px;
border: 2px solid #3498db;
font-size: 14px;
}
.move-history {
width: 480px;
max-height: 200px;
overflow-y: auto;
background: #ecf0f1;
border-radius: 10px;
padding: 10px;
margin-top: 20px;
}
.move-history h3 {
margin: 0 0 10px 0;
color: #333;
}
.move-item {
padding: 5px;
border-bottom: 1px solid #bdc3c7;
}
.move-item:last-child {
border-bottom: none;
}
@media (max-width: 600px) {
.chessboard {
width: 320px;
height: 360px;
}
.piece {
width: 30px;
height: 30px;
font-size: 14px;
}
.move-history {
width: 320px;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>♔ 中国象棋 ♔</h1>
<div class="game-info" id="gameInfo">
红方先行 - 请选择棋子
</div>
<div class="controls">
<button onclick="newGame()">新游戏</button>
<button onclick="undoMove()">悔棋</button>
<div class="difficulty">
<label>难度:</label>
<select id="difficulty">
<option value="easy">简单</option>
<option value="medium" selected>中等</option>
<option value="hard">困难</option>
</select>
</div>
</div>
<div class="chessboard" id="chessboard">
<div class="board-grid" id="boardGrid"></div>
<div class="river">
<span>楚</span>
<span>河</span>
<span>汉</span>
<span>界</span>
</div>
<div class="chess-pieces" id="chessPieces"></div>
</div>
<div class="move-history">
<h3>走棋记录</h3>
<div id="moveHistory"></div>
</div>
</div>
<script>
class ChineseChess {
constructor() {
this.board = [];
this.currentPlayer = 'red'; // red or black
this.selectedPiece = null;
this.validMoves = [];
this.moveHistory = [];
this.gameOver = false;
this.pieceNames = {
'king': '帅',
'advisor': '仕',
'elephant': '相',
'rook': '车',
'knight': '马',
'cannon': '炮',
'pawn': '兵'
};
this.pieceNamesBlack = {
'king': '将',
'advisor': '士',
'elephant': '象',
'rook': '车',
'knight': '马',
'cannon': '炮',
'pawn': '卒'
};
this.initializeBoard();
this.drawBoard();
this.drawPieces();
}
initializeBoard() {
// 初始化空棋盘 (10行9列)
for (let i = 0; i < 10; i++) {
this.board[i] = [];
for (let j = 0; j < 9; j++) {
this.board[i][j] = null;
}
}
// 放置红方棋子 (下方)
// 第9行 (数组索引9): 车马相仕帅仕相马车
this.board[9][0] = { type: 'rook', color: 'red' };
this.board[9][1] = { type: 'knight', color: 'red' };
this.board[9][2] = { type: 'elephant', color: 'red' };
this.board[9][3] = { type: 'advisor', color: 'red' };
this.board[9][4] = { type: 'king', color: 'red' };
this.board[9][5] = { type: 'advisor', color: 'red' };
this.board[9][6] = { type: 'elephant', color: 'red' };
this.board[9][7] = { type: 'knight', color: 'red' };
this.board[9][8] = { type: 'rook', color: 'red' };
// 第7行 (数组索引7): 炮 炮
this.board[7][1] = { type: 'cannon', color: 'red' };
this.board[7][7] = { type: 'cannon', color: 'red' };
// 第6行 (数组索引6): 兵 兵 兵 兵 兵
this.board[6][0] = { type: 'pawn', color: 'red' };
this.board[6][2] = { type: 'pawn', color: 'red' };
this.board[6][4] = { type: 'pawn', color: 'red' };
this.board[6][6] = { type: 'pawn', color: 'red' };
this.board[6][8] = { type: 'pawn', color: 'red' };
// 放置黑方棋子 (上方)
// 第0行 (数组索引0): 车马象士将士士象马车
this.board[0][0] = { type: 'rook', color: 'black' };
this.board[0][1] = { type: 'knight', color: 'black' };
this.board[0][2] = { type: 'elephant', color: 'black' };
this.board[0][3] = { type: 'advisor', color: 'black' };
this.board[0][4] = { type: 'king', color: 'black' };
this.board[0][5] = { type: 'advisor', color: 'black' };
this.board[0][6] = { type: 'elephant', color: 'black' };
this.board[0][7] = { type: 'knight', color: 'black' };
this.board[0][8] = { type: 'rook', color: 'black' };
// 第2行 (数组索引2): 炮 炮
this.board[2][1] = { type: 'cannon', color: 'black' };
this.board[2][7] = { type: 'cannon', color: 'black' };
// 第3行 (数组索引3): 卒 卒 卒 卒 卒
this.board[3][0] = { type: 'pawn', color: 'black' };
this.board[3][2] = { type: 'pawn', color: 'black' };
this.board[3][4] = { type: 'pawn', color: 'black' };
this.board[3][6] = { type: 'pawn', color: 'black' };
this.board[3][8] = { type: 'pawn', color: 'black' };
}
drawBoard() {
const boardGrid = document.getElementById('boardGrid');
boardGrid.innerHTML = '';
const cellWidth = 480 / 8; // 9个点,8个间隔
const cellHeight = 540 / 9; // 10个点,9个间隔
// 绘制横线 (10条线)
for (let i = 0; i < 10; i++) {
const line = document.createElement('div');
line.className = 'board-line horizontal-line';
line.style.top = (i * cellHeight) + 'px';
line.style.width = '100%';
boardGrid.appendChild(line);
}
// 绘制竖线 (9条线),但河界中间不画竖线
for (let j = 0; j < 9; j++) {
// 上半部分 (0-4行)
const topLine = document.createElement('div');
topLine.className = 'board-line vertical-line';
topLine.style.left = (j * cellWidth) + 'px';
topLine.style.top = '0px';
topLine.style.height = (5 * cellHeight) + 'px';
boardGrid.appendChild(topLine);
// 下半部分 (5-9行)
const bottomLine = document.createElement('div');
bottomLine.className = 'board-line vertical-line';
bottomLine.style.left = (j * cellWidth) + 'px';
bottomLine.style.top = (5 * cellHeight) + 'px';
bottomLine.style.height = (5 * cellHeight) + 'px';
boardGrid.appendChild(bottomLine);
}
// 绘制九宫格边界
this.drawPalace();
}
drawPalace() {
const boardGrid = document.getElementById('boardGrid');
const cellWidth = 480 / 8;
const cellHeight = 540 / 9;
// 红方九宫格 (第7-9行,第3-5列)
// 垂直线
const redVLine1 = document.createElement('div');
redVLine1.className = 'board-line vertical-line';
redVLine1.style.left = (3 * cellWidth) + 'px';
redVLine1.style.top = (7 * cellHeight) + 'px';
redVLine1.style.height = (2 * cellHeight) + 'px';
boardGrid.appendChild(redVLine1);
const redVLine2 = document.createElement('div');
redVLine2.className = 'board-line vertical-line';
redVLine2.style.left = (5 * cellWidth) + 'px';
redVLine2.style.top = (7 * cellHeight) + 'px';
redVLine2.style.height = (2 * cellHeight) + 'px';
boardGrid.appendChild(redVLine2);
// 水平线
const redHLine1 = document.createElement('div');
redHLine1.className = 'board-line horizontal-line';
redHLine1.style.top = (7 * cellHeight) + 'px';
redHLine1.style.left = (3 * cellWidth) + 'px';
redHLine1.style.width = (2 * cellWidth) + 'px';
boardGrid.appendChild(redHLine1);
const redHLine2 = document.createElement('div');
redHLine2.className = 'board-line horizontal-line';
redHLine2.style.top = (9 * cellHeight) + 'px';
redHLine2.style.left = (3 * cellWidth) + 'px';
redHLine2.style.width = (2 * cellWidth) + 'px';
boardGrid.appendChild(redHLine2);
// 黑方九宫格 (第0-2行,第3-5列)
// 垂直线
const blackVLine1 = document.createElement('div');
blackVLine1.className = 'board-line vertical-line';
blackVLine1.style.left = (3 * cellWidth) + 'px';
blackVLine1.style.top = (0 * cellHeight) + 'px';
blackVLine1.style.height = (2 * cellHeight) + 'px';
boardGrid.appendChild(blackVLine1);
const blackVLine2 = document.createElement('div');
blackVLine2.className = 'board-line vertical-line';
blackVLine2.style.left = (5 * cellWidth) + 'px';
blackVLine2.style.top = (0 * cellHeight) + 'px';
blackVLine2.style.height = (2 * cellHeight) + 'px';
boardGrid.appendChild(blackVLine2);
// 水平线
const blackHLine1 = document.createElement('div');
blackHLine1.className = 'board-line horizontal-line';
blackHLine1.style.top = (0 * cellHeight) + 'px';
blackHLine1.style.left = (3 * cellWidth) + 'px';
blackHLine1.style.width = (2 * cellWidth) + 'px';
boardGrid.appendChild(blackHLine1);
const blackHLine2 = document.createElement('div');
blackHLine2.className = 'board-line horizontal-line';
blackHLine2.style.top = (2 * cellHeight) + 'px';
blackHLine2.style.left = (3 * cellWidth) + 'px';
blackHLine2.style.width = (2 * cellWidth) + 'px';
boardGrid.appendChild(blackHLine2);
// 绘制九宫格斜线
this.drawPalaceLines();
}
drawPalaceLines() {
const boardGrid = document.getElementById('boardGrid');
const cellWidth = 480 / 8;
const cellHeight = 540 / 9;
// 红方九宫格 (第7-9行,第3-5列)
// 左上到右下
const redLine1 = document.createElement('div');
redLine1.className = 'board-line';
redLine1.style.position = 'absolute';
redLine1.style.width = '2px';
redLine1.style.height = Math.sqrt(2 * cellWidth * cellWidth + 2 * cellHeight * cellHeight) + 'px';
redLine1.style.left = (3 * cellWidth) + 'px';
redLine1.style.top = (7 * cellHeight) + 'px';
redLine1.style.transform = `rotate(45deg)`;
redLine1.style.transformOrigin = 'top left';
boardGrid.appendChild(redLine1);
// 右上到左下
const redLine2 = document.createElement('div');
redLine2.className = 'board-line';
redLine2.style.position = 'absolute';
redLine2.style.width = '2px';
redLine2.style.height = Math.sqrt(2 * cellWidth * cellWidth + 2 * cellHeight * cellHeight) + 'px';
redLine2.style.left = (5 * cellWidth) + 'px';
redLine2.style.top = (7 * cellHeight) + 'px';
redLine2.style.transform = `rotate(-45deg)`;
redLine2.style.transformOrigin = 'top right';
boardGrid.appendChild(redLine2);
// 黑方九宫格 (第0-2行,第3-5列)
// 左上到右下
const blackLine1 = document.createElement('div');
blackLine1.className = 'board-line';
blackLine1.style.position = 'absolute';
blackLine1.style.width = '2px';
blackLine1.style.height = Math.sqrt(2 * cellWidth * cellWidth + 2 * cellHeight * cellHeight) + 'px';
blackLine1.style.left = (3 * cellWidth) + 'px';
blackLine1.style.top = (0 * cellHeight) + 'px';
blackLine1.style.transform = `rotate(45deg)`;
blackLine1.style.transformOrigin = 'top left';
boardGrid.appendChild(blackLine1);
// 右上到左下
const blackLine2 = document.createElement('div');
blackLine2.className = 'board-line';
blackLine2.style.position = 'absolute';
blackLine2.style.width = '2px';
blackLine2.style.height = Math.sqrt(2 * cellWidth * cellWidth + 2 * cellHeight * cellHeight) + 'px';
blackLine2.style.left = (5 * cellWidth) + 'px';
blackLine2.style.top = (0 * cellHeight) + 'px';
blackLine2.style.transform = `rotate(-45deg)`;
blackLine2.style.transformOrigin = 'top right';
boardGrid.appendChild(blackLine2);
}
drawPieces() {
const chessPieces = document.getElementById('chessPieces');
chessPieces.innerHTML = '';
const cellWidth = 480 / 8;
const cellHeight = 540 / 9;
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 9; j++) {
if (this.board[i][j]) {
const piece = document.createElement('div');
piece.className = `piece ${this.board[i][j].color}`;
piece.style.left = (j * cellWidth) + 'px';
piece.style.top = (i * cellHeight) + 'px';
const pieceName = this.board[i][j].color === 'red' ?
this.pieceNames[this.board[i][j].type] :
this.pieceNamesBlack[this.board[i][j].type];
piece.textContent = pieceName;
piece.addEventListener('click', () => this.selectPiece(i, j));
chessPieces.appendChild(piece);
}
}
}
}
selectPiece(row, col) {
if (this.gameOver) return;
const piece = this.board[row][col];
// 如果已经选中了棋子
if (this.selectedPiece) {
const selectedRow = this.selectedPiece.row;
const selectedCol = this.selectedPiece.col;
// 检查是否点击的是合法移动位置
const isValidMove = this.validMoves.some(move =>
move.row === row && move.col === col
);
if (isValidMove) {
this.movePiece(selectedRow, selectedCol, row, col);
this.clearSelection();
return;
}
// 如果点击的是己方其他棋子,重新选择
if (piece && piece.color === this.currentPlayer) {
this.clearSelection();
this.selectPiece(row, col);
return;
}
this.clearSelection();
return;
}
// 选择棋子
if (piece && piece.color === this.currentPlayer) {
this.selectedPiece = { row, col, piece };
this.validMoves = this.getValidMoves(row, col, piece);
// 高亮显示选中的棋子和可移动位置
this.highlightValidMoves();
}
}
clearSelection() {
this.selectedPiece = null;
this.validMoves = [];
this.drawPieces();
}
highlightValidMoves() {
this.drawPieces();
// 高亮选中的棋子
if (this.selectedPiece) {
const cellWidth = 480 / 8;
const cellHeight = 540 / 9;
const pieces = document.querySelectorAll('.piece');
pieces.forEach(piece => {
const left = parseFloat(piece.style.left);
const top = parseFloat(piece.style.top);
const col = Math.round(left / cellWidth);
const row = Math.round(top / cellHeight);
if (row === this.selectedPiece.row && col === this.selectedPiece.col) {
piece.classList.add('selected');
}
});
}
// 显示可移动位置
this.showValidMoves();
}
showValidMoves() {
const cellWidth = 480 / 8;
const cellHeight = 540 / 9;
this.validMoves.forEach(move => {
const moveIndicator = document.createElement('div');
moveIndicator.className = 'piece valid-move';
moveIndicator.style.left = (move.col * cellWidth) + 'px';
moveIndicator.style.top = (move.row * cellHeight) + 'px';
moveIndicator.style.width = '20px';
moveIndicator.style.height = '20px';
moveIndicator.style.backgroundColor = 'transparent';
moveIndicator.style.border = 'none';
document.getElementById('chessPieces').appendChild(moveIndicator);
});
}
getValidMoves(row, col, piece) {
const moves = [];
switch (piece.type) {
case 'king':
moves.push(...this.getKingMoves(row, col, piece.color));
break;
case 'advisor':
moves.push(...this.getAdvisorMoves(row, col, piece.color));
break;
case 'elephant':
moves.push(...this.getElephantMoves(row, col, piece.color));
break;
case 'rook':
moves.push(...this.getRookMoves(row, col, piece.color));
break;
case 'knight':
moves.push(...this.getKnightMoves(row, col, piece.color));
break;
case 'cannon':
moves.push(...this.getCannonMoves(row, col, piece.color));
break;
case 'pawn':
moves.push(...this.getPawnMoves(row, col, piece.color));
break;
}
return moves;
}
getKingMoves(row, col, color) {
const moves = [];
const directions = [[-1,0], [1,0], [0,-1], [0,1]];
const palace = color === 'red' ?
{ minRow: 7, maxRow: 9, minCol: 3, maxCol: 5 } :
{ minRow: 0, maxRow: 2, minCol: 3, maxCol: 5 };
for (const [dr, dc] of directions) {
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= palace.minRow && newRow <= palace.maxRow &&
newCol >= palace.minCol && newCol <= palace.maxCol) {
if (!this.board[newRow][newCol] ||
this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
}
}
return moves;
}
getAdvisorMoves(row, col, color) {
const moves = [];
const directions = [[-1,-1], [-1,1], [1,-1], [1,1]];
const palace = color === 'red' ?
{ minRow: 7, maxRow: 9, minCol: 3, maxCol: 5 } :
{ minRow: 0, maxRow: 2, minCol: 3, maxCol: 5 };
for (const [dr, dc] of directions) {
const newRow = row + dr;
const newCol = col + dc;
if (newRow >= palace.minRow && newRow <= palace.maxRow &&
newCol >= palace.minCol && newCol <= palace.maxCol) {
if (!this.board[newRow][newCol] ||
this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
}
}
return moves;
}
getElephantMoves(row, col, color) {
const moves = [];
const directions = [[-2,-2], [-2,2], [2,-2], [2,2]];
const riverRow = color === 'red' ? 5 : 4;
for (const [dr, dc] of directions) {
const newRow = row + dr;
const newCol = col + dc;
const blockRow = row + dr/2;
const blockCol = col + dc/2;
// 象不能过河
if ((color === 'red' && newRow < riverRow) ||
(color === 'black' && newRow > riverRow)) {
continue;
}
if (newRow >= 0 && newRow < 10 && newCol >= 0 && newCol < 9) {
// 检查象眼是否被堵
if (!this.board[blockRow][blockCol]) {
if (!this.board[newRow][newCol] ||
this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
}
}
}
return moves;
}
getRookMoves(row, col, color) {
const moves = [];
const directions = [[-1,0], [1,0], [0,-1], [0,1]];
for (const [dr, dc] of directions) {
for (let i = 1; i < 10; i++) {
const newRow = row + dr * i;
const newCol = col + dc * i;
if (newRow < 0 || newRow >= 10 || newCol < 0 || newCol >= 9) {
break;
}
if (!this.board[newRow][newCol]) {
moves.push({ row: newRow, col: newCol });
} else {
if (this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
break;
}
}
}
return moves;
}
getKnightMoves(row, col, color) {
const moves = [];
const directions = [
[-2,-1], [-2,1], [-1,-2], [-1,2],
[1,-2], [1,2], [2,-1], [2,1]
];
const blockDirections = [
[-1,0], [-1,0], [0,-1], [0,1],
[0,-1], [0,1], [1,0], [1,0]
];
for (let i = 0; i < directions.length; i++) {
const [dr, dc] = directions[i];
const [br, bc] = blockDirections[i];
const newRow = row + dr;
const newCol = col + dc;
const blockRow = row + br;
const blockCol = col + bc;
if (newRow >= 0 && newRow < 10 && newCol >= 0 && newCol < 9) {
// 检查马腿是否被堵
if (!this.board[blockRow][blockCol]) {
if (!this.board[newRow][newCol] ||
this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
}
}
}
return moves;
}
getCannonMoves(row, col, color) {
const moves = [];
const directions = [[-1,0], [1,0], [0,-1], [0,1]];
for (const [dr, dc] of directions) {
let hasJumped = false;
for (let i = 1; i < 10; i++) {
const newRow = row + dr * i;
const newCol = col + dc * i;
if (newRow < 0 || newRow >= 10 || newCol < 0 || newCol >= 9) {
break;
}
if (!this.board[newRow][newCol]) {
if (!hasJumped) {
moves.push({ row: newRow, col: newCol });
}
} else {
if (!hasJumped) {
hasJumped = true;
} else {
if (this.board[newRow][newCol].color !== color) {
moves.push({ row: newRow, col: newCol });
}
break;
}
}
}
}
return moves;
}
getPawnMoves(row, col, color) {
const moves = [];
const isCrossedRiver = color === 'red' ? (row < 5) : (row > 4);
// 前进
const forwardRow = color === 'red' ? row - 1 : row + 1;
if (forwardRow >= 0 && forwardRow < 10) {
if (!this.board[forwardRow][col] ||
this.board[forwardRow][col].color !== color) {
moves.push({ row: forwardRow, col: col });
}
}
// 过河后可以左右移动
if (isCrossedRiver) {
const leftCol = col - 1;
const rightCol = col + 1;
if (leftCol >= 0) {
if (!this.board[row][leftCol] ||
this.board[row][leftCol].color !== color) {
moves.push({ row: row, col: leftCol });
}
}
if (rightCol < 9) {
if (!this.board[row][rightCol] ||
this.board[row][rightCol].color !== color) {
moves.push({ row: row, col: rightCol });
}
}
}
return moves;
}
movePiece(fromRow, fromCol, toRow, toCol) {
const piece = this.board[fromRow][fromCol];
const capturedPiece = this.board[toRow][toCol];
// 记录移动历史
const moveRecord = {
from: { row: fromRow, col: fromCol },
to: { row: toRow, col: toCol },
piece: piece,
captured: capturedPiece,
player: this.currentPlayer
};
this.moveHistory.push(moveRecord);
// 执行移动
this.board[toRow][toCol] = piece;
this.board[fromRow][fromCol] = null;
// 更新界面
this.drawPieces();
this.updateGameInfo();
// 检查是否吃掉了将/帅
if (capturedPiece && capturedPiece.type === 'king') {
this.gameOver = true;
alert(`${this.currentPlayer === 'red' ? '红方' : '黑方'}获胜!`);
return;
}
// 切换玩家
this.currentPlayer = this.currentPlayer === 'red' ? 'black' : 'red';
// 如果是黑方(AI)回合,执行AI移动
if (this.currentPlayer === 'black' && !this.gameOver) {
setTimeout(() => this.aiMove(), 1000);
}
}
aiMove() {
if (this.gameOver) return;
const difficulty = document.getElementById('difficulty').value;
let bestMove = null;
if (difficulty === 'hard') {
bestMove = this.getBestAIMove();
} else {
bestMove = this.getRandomAIMove();
}
if (bestMove) {
this.movePiece(bestMove.fromRow, bestMove.fromCol, bestMove.toRow, bestMove.toCol);
}
}
getRandomAIMove() {
const blackPieces = [];
// 找到所有黑方棋子
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 9; j++) {
if (this.board[i][j] && this.board[i][j].color === 'black') {
const moves = this.getValidMoves(i, j, this.board[i][j]);
if (moves.length > 0) {
blackPieces.push({ row: i, col: j, moves: moves });
}
}
}
}
if (blackPieces.length === 0) return null;
// 随机选择一个棋子和移动
const randomPiece = blackPieces[Math.floor(Math.random() * blackPieces.length)];
const randomMove = randomPiece.moves[Math.floor(Math.random() * randomPiece.moves.length)];
return {
fromRow: randomPiece.row,
fromCol: randomPiece.col,
toRow: randomMove.row,
toCol: randomMove.col
};
}
getBestAIMove() {
// 简化的AI策略:优先吃子,其次随机移动
const blackPieces = [];
// 找到所有黑方棋子及其可移动位置
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 9; j++) {
if (this.board[i][j] && this.board[i][j].color === 'black') {
const moves = this.getValidMoves(i, j, this.board[i][j]);
moves.forEach(move => {
blackPieces.push({
fromRow: i,
fromCol: j,
toRow: move.row,
toCol: move.col,
piece: this.board[i][j],
capture: this.board[move.row][move.col]
});
});
}
}
}
if (blackPieces.length === 0) return null;
// 优先选择能吃子的移动
const captureMoves = blackPieces.filter(move => move.capture);
if (captureMoves.length > 0) {
// 优先吃价值高的棋子
captureMoves.sort((a, b) => {
const pieceValues = {
'king': 1000, 'advisor': 20, 'elephant': 20,
'rook': 100, 'knight': 40, 'cannon': 45, 'pawn': 10
};
return (pieceValues[b.capture.type] || 0) - (pieceValues[a.capture.type] || 0);
});
const bestCapture = captureMoves[0];
return {
fromRow: bestCapture.fromRow,
fromCol: bestCapture.fromCol,
toRow: bestCapture.toRow,
toCol: bestCapture.toCol
};
}
// 如果没有吃子机会,随机移动
return this.getRandomAIMove();
}
updateGameInfo() {
const gameInfo = document.getElementById('gameInfo');
const currentPlayerName = this.currentPlayer === 'red' ? '红方' : '黑方';
gameInfo.textContent = `${currentPlayerName}行棋`;
// 更新走棋记录
this.updateMoveHistory();
}
updateMoveHistory() {
const moveHistory = document.getElementById('moveHistory');
moveHistory.innerHTML = '';
this.moveHistory.slice(-10).forEach((move, index) => {
const moveItem = document.createElement('div');
moveItem.className = 'move-item';
const playerName = move.player === 'red' ? '红方' : '黑方';
const pieceName = move.player === 'red' ?
this.pieceNames[move.piece.type] :
this.pieceNamesBlack[move.piece.type];
moveItem.textContent = `${playerName} ${pieceName}: (${move.from.row},${move.from.col}) → (${move.to.row},${move.to.col})`;
moveHistory.appendChild(moveItem);
});
}
}
let game;
function newGame() {
game = new ChineseChess();
}
function undoMove() {
if (game && game.moveHistory.length > 0) {
const lastMove = game.moveHistory.pop();
// 撤销移动
game.board[lastMove.from.row][lastMove.from.col] = lastMove.piece;
game.board[lastMove.to.row][lastMove.to.col] = lastMove.captured;
// 切换回上一个玩家
game.currentPlayer = lastMove.player;
game.gameOver = false;
// 重新绘制
game.drawPieces();
game.updateGameInfo();
}
}
// 初始化游戏
window.onload = function() {
newGame();
};
</script>
</body>
</html>