SOURCE

console 命令行工具 X clear

                    
>
console
<!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>
        :root {
            --bg-color: #2c3e50;
            --board-light: #f0d9b5;
            --board-dark: #b58863;
            --highlight: rgba(255, 255, 0, 0.5);
            --valid-move: rgba(0, 255, 0, 0.4);
        }

        body {
            background-color: var(--bg-color);
            color: white;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin: 0;
            padding: 20px;
        }

        h1 { margin-bottom: 10px; }

        .controls {
            margin-bottom: 20px;
            display: flex;
            gap: 15px;
            align-items: center;
        }

        select, button {
            padding: 8px 12px;
            font-size: 16px;
            border-radius: 5px;
            border: none;
            cursor: pointer;
        }

        button {
            background-color: #e74c3c;
            color: white;
            font-weight: bold;
            transition: 0.2s;
        }

        button:hover { background-color: #c0392b; }

        .status {
            margin-bottom: 15px;
            font-size: 1.2rem;
            font-weight: bold;
            height: 24px;
        }

        /* 棋盘样式 */
        #board {
            display: grid;
            grid-template-columns: repeat(8, 60px);
            grid-template-rows: repeat(8, 60px);
            border: 4px solid #1a252f;
            box-shadow: 0 10px 20px rgba(0,0,0,0.5);
        }

        .square {
            width: 60px;
            height: 60px;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 45px;
            cursor: pointer;
            user-select: none;
            position: relative;
        }

        .square.light { background-color: var(--board-light); }
        .square.dark { background-color: var(--board-dark); }
        
        .square.selected { background-color: var(--highlight) !important; }
        .square.valid-move::after {
            content: '';
            width: 15px;
            height: 15px;
            background-color: var(--valid-move);
            border-radius: 50%;
            position: absolute;
        }
        
        .square.capture-move::after {
            width: 100%;
            height: 100%;
            border-radius: 0;
            background-color: transparent;
            border: 4px solid var(--valid-move);
            box-sizing: border-box;
        }

        /* 统一使用 Unicode 字符展示棋子,更美观 */
        .piece-white { color: #ffffff; text-shadow: 1px 1px 2px #000, -1px -1px 2px #000, 1px -1px 2px #000, -1px 1px 2px #000; }
        .piece-black { color: #000000; text-shadow: 1px 1px 2px #fff, -1px -1px 2px #fff, 1px -1px 2px #fff, -1px 1px 2px #fff; }

    </style>
</head>
<body>

    <h1>国际象棋</h1>
    
    <div class="controls">
        <select id="gameMode">
            <option value="pvp">双人对战</option>
            <option value="pve">人机对战 (你执白)</option>
        </select>
        <button onclick="resetGame()">重新开始</button>
    </div>

    <div class="status" id="status">白方走棋</div>
    <div id="board"></div>

<script>
    // 棋盘初始状态 (大写为白方,小写为黑方,. 为空格)
    const initialBoard = [
        ['r', 'n', 'b', 'q', 'k', 'b', 'n', 'r'],
        ['p', 'p', 'p', 'p', 'p', 'p', 'p', 'p'],
        ['.', '.', '.', '.', '.', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.', '.', '.'],
        ['.', '.', '.', '.', '.', '.', '.', '.'],
        ['P', 'P', 'P', 'P', 'P', 'P', 'P', 'P'],
        ['R', 'N', 'B', 'Q', 'K', 'B', 'N', 'R']
    ];

    // 棋子对应的 Unicode 字符
    const pieces = {
        'K': '♔', 'Q': '♕', 'R': '♖', 'B': '♗', 'N': '♘', 'P': '♙',
        'k': '♚', 'q': '♛', 'r': '♜', 'b': '♝', 'n': '♞', 'p': '♟'
    };

    let board = [];
    let turn = 'w'; // 'w' 白方, 'b' 黑方
    let selectedSquare = null;
    let isGameOver = false;

    const boardElement = document.getElementById('board');
    const statusElement = document.getElementById('status');
    const modeSelect = document.getElementById('gameMode');

    // 初始化棋盘
    function init() {
        board = JSON.parse(JSON.stringify(initialBoard));
        turn = 'w';
        selectedSquare = null;
        isGameOver = false;
        updateStatus();
        renderBoard();
    }

    // 渲染棋盘
    function renderBoard() {
        boardElement.innerHTML = '';
        for (let r = 0; r < 8; r++) {
            for (let c = 0; c < 8; c++) {
                const square = document.createElement('div');
                square.className = `square ${(r + c) % 2 === 0 ? 'light' : 'dark'}`;
                square.dataset.row = r;
                square.dataset.col = c;
                
                const piece = board[r][c];
                if (piece !== '.') {
                    const span = document.createElement('span');
                    span.textContent = pieces[piece];
                    span.className = piece === piece.toUpperCase() ? 'piece-white' : 'piece-black';
                    square.appendChild(span);
                }

                if (selectedSquare && selectedSquare.row === r && selectedSquare.col === c) {
                    square.classList.add('selected');
                }

                square.addEventListener('click', () => handleSquareClick(r, c));
                boardElement.appendChild(square);
            }
        }
    }

    // 处理点击事件
    function handleSquareClick(r, c) {
        if (isGameOver || (modeSelect.value === 'pve' && turn === 'b')) return;

        const piece = board[r][c];

        // 如果已经选中了棋子,尝试移动
        if (selectedSquare) {
            const validMoves = getValidMoves(selectedSquare.row, selectedSquare.col);
            const isMoveValid = validMoves.some(m => m.row === r && m.col === c);

            if (isMoveValid) {
                makeMove(selectedSquare.row, selectedSquare.col, r, c);
                return;
            }
        }

        // 选中/取消选中己方棋子
        if (piece !== '.') {
            const isWhitePiece = piece === piece.toUpperCase();
            if ((turn === 'w' && isWhitePiece) || (turn === 'b' && !isWhitePiece)) {
                selectedSquare = { row: r, col: c };
                renderBoard();
                showValidMoves(r, c);
                return;
            }
        }

        // 点击空白处取消选择
        selectedSquare = null;
        renderBoard();
    }

    // 显示合法移动位置
    function showValidMoves(r, c) {
        const moves = getValidMoves(r, c);
        moves.forEach(move => {
            const index = move.row * 8 + move.col;
            const square = boardElement.children[index];
            if (board[move.row][move.col] !== '.') {
                square.classList.add('capture-move');
            } else {
                square.classList.add('valid-move');
            }
        });
    }

    // 执行移动
    function makeMove(fromR, fromC, toR, toC) {
        board[toR][toC] = board[fromR][fromC];
        board[fromR][fromC] = '.';
        
        selectedSquare = null;
        turn = turn === 'w' ? 'b' : 'w';
        updateStatus();
        renderBoard();

        // 人机对战逻辑
        if (modeSelect.value === 'pve' && turn === 'b') {
            setTimeout(makeAIMove, 300); // 延迟一下让玩家看清自己的走子
        }
    }

    // 更新状态提示
    function updateStatus() {
        if (isGameOver) return;
        statusElement.textContent = turn === 'w' ? '白方走棋' : '黑方走棋 (思考中...)';
        if (modeSelect.value === 'pvp') {
            statusElement.textContent = turn === 'w' ? '白方走棋' : '黑方走棋';
        }
    }

    // 核心规则:获取合法移动 (简化版,未包含王车易位、吃过路兵、逼王等)
    function getValidMoves(r, c) {
        const piece = board[r][c];
        if (piece === '.') return [];
        
        const isWhite = piece === piece.toUpperCase();
        const type = piece.toLowerCase();
        const moves = [];

        const addMove = (row, col) => {
            if (row < 0 || row > 7 || col < 0 || col > 7) return false;
            const target = board[row][col];
            if (target === '.') {
                moves.push({ row, col });
                return true;
            } else {
                const isTargetWhite = target === target.toUpperCase();
                if (isWhite !== isTargetWhite) {
                    moves.push({ row, col }); // 可以吃子
                }
                return false; // 遇到棋子阻挡
            }
        };

        if (type === 'p') { // 兵
            const dir = isWhite ? -1 : 1;
            const startRow = isWhite ? 6 : 1;
            
            // 前进
            if (r + dir >= 0 && r + dir <= 7 && board[r + dir][c] === '.') {
                moves.push({ row: r + dir, col: c });
                // 开局走两格
                if (r === startRow && board[r + dir * 2][c] === '.') {
                    moves.push({ row: r + dir * 2, col: c });
                }
            }
            // 吃子
            [-1, 1].forEach(offset => {
                const nc = c + offset;
                const nr = r + dir;
                if (nr >= 0 && nr <= 7 && nc >= 0 && nc <= 7) {
                    const target = board[nr][nc];
                    if (target !== '.' && (target === target.toUpperCase()) !== isWhite) {
                        moves.push({ row: nr, col: nc });
                    }
                }
            });
        } 
        else if (type === 'n') { // 马
            const offsets = [[-2,-1],[-2,1],[-1,-2],[-1,2],[1,-2],[1,2],[2,-1],[2,1]];
            offsets.forEach(([dr, dc]) => addMove(r + dr, c + dc));
        } 
        else if (type === 'r') { // 车
            const dirs = [[0,1],[0,-1],[1,0],[-1,0]];
            dirs.forEach(([dr, dc]) => {
                let nr = r + dr, nc = c + dc;
                while (addMove(nr, nc)) { nr += dr; nc += dc; }
            });
        } 
        else if (type === 'b') { // 象
            const dirs = [[1,1],[1,-1],[-1,1],[-1,-1]];
            dirs.forEach(([dr, dc]) => {
                let nr = r + dr, nc = c + dc;
                while (addMove(nr, nc)) { nr += dr; nc += dc; }
            });
        } 
        else if (type === 'q') { // 后
            const dirs = [[0,1],[0,-1],[1,0],[-1,0],[1,1],[1,-1],[-1,1],[-1,-1]];
            dirs.forEach(([dr, dc]) => {
                let nr = r + dr, nc = c + dc;
                while (addMove(nr, nc)) { nr += dr; nc += dc; }
            });
        } 
        else if (type === 'k') { // 王
            const dirs = [[0,1],[0,-1],[1,0],[-1,0],[1,1],[1,-1],[-1,1],[-1,-1]];
            dirs.forEach(([dr, dc]) => addMove(r + dr, c + dc));
        }

        return moves;
    }

    // 简易 AI (贪心算法:评估所有走法,选择能吃掉最高价值棋子的走法,否则随机)
    function makeAIMove() {
        if (isGameOver) return;
        
        let bestMove = null;
        let maxScore = -Infinity;
        
        // 棋子价值评估
        const values = { 'p': 10, 'n': 30, 'b': 30, 'r': 50, 'q': 90, 'k': 1000 };

        // 遍历所有黑方棋子
        for (let r = 0; r < 8; r++) {
            for (let c = 0; c < 8; c++) {
                const piece = board[r][c];
                if (piece !== '.' && piece === piece.toLowerCase()) {
                    const moves = getValidMoves(r, c);
                    moves.forEach(move => {
                        // 计算这步棋的分数(吃子价值)
                        let score = 0;
                        const targetPiece = board[move.row][move.col];
                        if (targetPiece !== '.') {
                            score = values[targetPiece.toLowerCase()];
                        }
                        
                        // 加入一点随机性,防止 AI 每次走法完全一样
                        score += Math.random(); 

                        if (score > maxScore) {
                            maxScore = score;
                            bestMove = { fromR: r, fromC: c, toR: move.row, toC: move.col };
                        }
                    });
                }
            }
        }

        if (bestMove) {
            // 检查是否吃掉王(极简版胜负判定)
            if (board[bestMove.toR][bestMove.toC].toLowerCase() === 'k') {
                board[bestMove.toR][bestMove.toC] = board[bestMove.fromR][bestMove.fromC];
                board[bestMove.fromR][bestMove.fromC] = '.';
                renderBoard();
                statusElement.textContent = "黑方胜利!游戏结束。";
                isGameOver = true;
                return;
            }
            makeMove(bestMove.fromR, bestMove.fromC, bestMove.toR, bestMove.toC);
        }
    }

    // 重新开始
    function resetGame() {
        init();
    }

    // 监听模式切换
    modeSelect.addEventListener('change', resetGame);

    // 启动游戏
    init();

</script>
</body>
</html>