Qwen3-Coder实现中国象棋游戏的尝试

发布于:2025-07-28 ⋅ 阅读:(12) ⋅ 点赞:(0)

提示词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>


网站公告

今日签到

点亮在社区的每一天
去签到