Qwen3-Coder实现中国象棋游戏的尝试
提示词1: 使用html实现中国象棋游戏,要求支持人机对弈,注意棋盘布局和棋子的正确位置,棋子的正确走法等。
迭代提示词:九宫格不对,红棋子不吃对方的子,就不能走是不对的。楚河汉界不应该有竖线。
实测效果如上,迭代不能变得更好。
1、棋盘画不对,迭代也不能修改正确;
2、红色棋子不能走,除非吃掉对方的棋子,迭代不能修改正确。
具体代码如下:
中国象棋 - 人机对弈 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; } } ♔ 中国象棋 ♔
红方先行 - 请选择棋子 简单 中等 困难 楚 河 汉 界 走棋记录
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 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.minCol && newCol = palace.minRow && newRow = 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)) { continue; } if (newRow >= 0 && newRow = 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 = 10 || 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 = 0 && newRow = 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 = 10 || 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 4); // 前进 const forwardRow = color === \'red\' ? row - 1 : row + 1; if (forwardRow >= 0 && forwardRow = 0) { if (!this.board[row][leftCol] || this.board[row][leftCol].color !== color) { moves.push({ row: row, col: leftCol }); } } if (rightCol 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 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 { 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(); };