当前位置: 首页 > news >正文

11.11 脚本网页 跳棋

  难点一,如何绘制棋盘,绘制棋盘算法还是社会工程 (本文选择查表) 已实现 ✔

  难点二,后端跳棋人工智能算法,这里只提供了,前端js简单交互逻辑  未实现

  下面是,只需一个页面就可以交互的跳棋。

 

<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <title>六角星跳棋</title>

    <style>

        /* 样式部分保持不变 */

        * {

            margin: 0;

            padding: 0;

            box-sizing: border-box;

        }

        

        body {

            font-family: 'Arial', sans-serif;

            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

            min-height: 100vh;

            display: flex;

            flex-direction: column;

            align-items: center;

            padding: 10px;

            overflow-x: hidden;

        }

        

        .game-container {

            width: 100%;

            max-width: 700px;

            background: rgba(255, 255, 255, 0.95);

            border-radius: 20px;

            box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);

            padding: 20px;

            margin-top: 20px;

        }

        

        .game-header {

            text-align: center;

            margin-bottom: 20px;

        }

        

        h1 {

            color: #333;

            font-size: 2rem;

            margin-bottom: 10px;

        }

        

        .game-info {

            display: flex;

            justify-content: space-around;

            align-items: center;

            margin-bottom: 15px;

            padding: 10px;

            background: #f8f9fa;

            border-radius: 10px;

            flex-wrap: wrap;

        }

        

        .player-info {

            display: flex;

            align-items: center;

            gap: 8px;

            margin: 5px;

        }

        

        .player-indicator {

            width: 24px;

            height: 24px;

            border-radius: 50%;

            border: 2px solid #333;

            transition: all 0.3s ease;

        }

        

        .current-player {

            transform: scale(1.3);

            box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);

        }

        

        .board-container {

            position: relative;

            width: 100%;

            height: 520px;

            max-width: 600px;

            margin: 0 auto;

            background: #f5f5dc;

            border-radius: 15px;

            box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);

            overflow: hidden;

        }

        

        .board {

            position: relative;

            width: 100%;

            height: 100%;

        }

        

        .position {

            position: absolute;

            width: 20px;

            height: 20px;

            border-radius: 50%;

            background: #e0d5c7;

            border: 1px solid #999;

            cursor: pointer;

            transition: all 0.3s ease;

            z-index: 1;

        }

        

        .position:hover {

            background: #d4c4b0;

            transform: scale(1.1);

        }

        

        .position.valid-move {

            background: #90EE90;

            animation: pulse 1s infinite;

            box-shadow: 0 0 10px rgba(0, 255, 0, 0.5);

        }

        

        @keyframes pulse {

            0% { transform: scale(1); }

            50% { transform: scale(1.15); }

            100% { transform: scale(1); }

        }

        

        .chess {

            position: absolute;

            width: 18px;

            height: 18px;

            border-radius: 50%;

            cursor: pointer;

            transition: all 0.4s cubic-bezier(0.68, -0.55, 0.265, 1.55);

            z-index: 10;

            box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);

        }

        

        .chess:hover {

            transform: scale(1.1);

            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);

        }

        

        .chess.selected {

            transform: scale(1.2);

            box-shadow: 0 0 15px rgba(255, 215, 0, 0.8);

            z-index: 20;

        }

        

        .chess.moving {

            z-index: 30;

            transition: all 0.6s ease-in-out;

        }

        

        .controls {

            display: flex;

            justify-content: center;

            gap: 15px;

            margin-top: 20px;

        }

        

        .btn {

            padding: 12px 25px;

            font-size: 1rem;

            font-weight: bold;

            border: none;

            border-radius: 25px;

            cursor: pointer;

            transition: all 0.3s ease;

            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);

        }

        

        .btn-primary {

            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);

            color: white;

        }

        

        .btn-primary:hover {

            transform: translateY(-2px);

            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.2);

        }

        

        .btn-secondary {

            background: #6c757d;

            color: white;

        }

        

        .btn-secondary:hover {

            background: #5a6268;

        }

        

        .message {

            text-align: center;

            margin-top: 15px;

            padding: 10px;

            border-radius: 10px;

            font-weight: bold;

            min-height: 40px;

            display: flex;

            align-items: center;

            justify-content: center;

            background: #e9ecef;

            color: #495057;

        }

        

        .winner-message {

            background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);

            color: white;

            animation: celebrate 1s ease-in-out;

        }

        

        @keyframes celebrate {

            0%, 100% { transform: scale(1); }

            50% { transform: scale(1.05); }

        }

        

        .ai-thinking {

            display: inline-block;

            margin-left: 10px;

        }

        

        .ai-thinking span {

            display: inline-block;

            width: 6px;

            height: 6px;

            border-radius: 50%;

            background: #667eea;

            margin: 0 2px;

            animation: thinking 1.4s infinite ease-in-out both;

        }

        

        .ai-thinking span:nth-child(1) { animation-delay: -0.32s; }

        .ai-thinking span:nth-child(2) { animation-delay: -0.16s; }

        

        @keyframes thinking {

            0%, 80%, 100% {

                transform: scale(0);

                opacity: 0.5;

            }

            40% {

                transform: scale(1);

                opacity: 1;

            }

        }

        

        @media (max-width: 600px) {

            .board-container {

                height: 400px;

                max-width: 450px;

            }

            

            .position {

                width: 16px;

                height: 16px;

            }

            

            .chess {

                width: 14px;

                height: 14px;

            }

            

            h1 {

                font-size: 1.5rem;

            }

            

            .btn {

                padding: 10px 20px;

                font-size: 0.9rem;

            }

        }

    </style>

</head>

<body>

    <div class="game-container">

        <div class="game-header">

            < 一、游戏界面 >

            <h1>🎯 六角星跳棋</h1>

        </div>

        

        <div class="game-info">

            <div class="player-info">

                <div class="player-indicator" id="player1-indicator"></div>

                <span>玩家</span>

            </div>

            <div class="player-info">

                <div class="player-indicator" id="player2-indicator"></div>

                <span>AI 1</span>

            </div>

            <div class="player-info">

                <div class="player-indicator" id="player3-indicator"></div>

                <span>AI 2</span>

            </div>

        </div>

        

        <div class="board-container">

            <div class="board" id="board"></div>

        </div>

        

        <div class="controls">

            <button class="btn btn-primary" id="startBtn">开始游戏</button>

            <button class="btn btn-secondary" id="resetBtn">重置</button>

        </div>

        

        <div class="message" id="message">点击"开始游戏"开始对战</div>

    </div>

 

    <script>

        // 二、游戏主类定义

        class ChineseCheckersGame {

            constructor() {

                // 1. 棋盘参数设置

                this.width = 300;

                this.height = this.width * Math.sqrt(3);

                this.rotateY = Math.round((this.width * 2 * 2 / 3) * Math.sqrt(3) / 2);

                this.radius = this.width * 2 / (12 + 12 * 0.4) / 2;

                this.gap = 2 * 0.4 * this.radius;

                

                // 2. 玩家设置

                this.playerColors = ['pink', 'orange', 'brown']; // 使用3个颜色

                this.setTargets = {

                    pink: { targetColor: 'orange', targetArray: [] },

                    orange: { targetColor: 'brown', targetArray: [] },

                    brown: { targetColor: 'pink', targetArray: [] }

                };

                

                // 3. 玩家信息

                this.players = [

                    { id: 1, name: '玩家', color: 'pink', isAI: false, pieces: [] },

                    { id: 2, name: 'AI 1', color: 'orange', isAI: true, pieces: [] },

                    { id: 3, name: 'AI 2', color: 'brown', isAI: true, pieces: [] }

                ];

                

                // 4. 游戏状态变量

                this.currentPlayerIndex = 0;

                this.selectedPiece = null;

                this.validMoves = [];

                this.gameActive = false;

                this.moveInProgress = false;

                this.position = [];

                

                // 5. 初始化棋盘和事件监听

                this.initBoard();

                this.setupEventListeners();

            }

            

            // 三、棋盘初始化

            initBoard() {

                const board = document.getElementById('board');

                board.innerHTML = '';

                this.position = [];

                

                // 1. 生成三角形区域的棋子和棋盘位置

                for (let k = 0; k < 6; k++) {

                    for (let i = 0; i < 4; i++) {

                        for (let j = 0; j < i + 1; j++) {

                            // 1.1 只在前3个角生成棋子

                            if (k < 3) {

                                const chessPos = {

                                    key: `tri-${k}-${i}-${j}`,

                                    isChess: true,

                                    locate: '',

                                    style: {

                                        background: this.playerColors[k],

                                        left: Math.round(Math.cos(k * 60 * 2 * Math.PI / 360) * (this.width - this.width * 2 / (4 * 3 * 2) * i + j * this.width * 2 / (4 * 3) - this.width) - Math.sin(k * 60 * 2 * Math.PI / 360) * ((i * this.gap + 2 * this.radius * i) * Math.sqrt(3) / 2 - this.rotateY) + this.width),

                                        top: Math.round(Math.sin(k * 60 * 2 * Math.PI / 360) * (this.width - this.width * 2 / (4 * 3 * 2) * i + j * this.width * 2 / (4 * 3) - this.width) + Math.cos(k * 60 * 2 * Math.PI / 360) * ((i * this.gap + 2 * this.radius * i) * Math.sqrt(3) / 2 - this.rotateY) + this.rotateY),

                                        zIndex: 2

                                    }

                                };

                                this.position.push(chessPos);

                            }

                            

                            // 1.2 所有6个角都生成棋盘位置

                            const boardPos = {

                                key: `board-tri-${k}-${i}-${j}`,

                                isChess: false,

                                style: {

                                    left: Math.round(Math.cos(k * 60 * 2 * Math.PI / 360) * (this.width - this.width * 2 / (4 * 3 * 2) * i + j * this.width * 2 / (4 * 3) - this.width) - Math.sin(k * 60 * 2 * Math.PI / 360) * ((i * this.gap + 2 * this.radius * i) * Math.sqrt(3) / 2 - this.rotateY) + this.width),

                                    top: Math.round(Math.sin(k * 60 * 2 * Math.PI / 360) * (this.width - this.width * 2 / (4 * 3 * 2) * i + j * this.width * 2 / (4 * 3) - this.width) + Math.cos(k * 60 * 2 * Math.PI / 360) * ((i * this.gap + 2 * this.radius * i) * Math.sqrt(3) / 2 - this.rotateY) + this.rotateY),

                                    zIndex: 1

                                }

                            };

                            this.position.push(boardPos);

                        }

                    }

                }

                

                // 2. 生成六边形上半边棋盘位置

                for (let i = 0; i < 5; i++) {

                    for (let j = 0; j < i + 5; j++) {

                        const hexPos = {

                            key: `hex-up-${i}-${j}`,

                            isChess: false,

                            style: {

                                left: Math.round(2 * this.width / 3 - this.width * 2 / (4 * 3 * 2) * i + (this.gap + 2 * this.radius) * j),

                                top: Math.round(this.rotateY / 2 + this.width * 2 / (4 * 3) * Math.sqrt(3) / 2 * i),

                                zIndex: 1

                            }

                        };

                        this.position.push(hexPos);

                    }

                }

                

                // 3. 生成六边形下半边棋盘位置

                for (let i = 5; i < 9; i++) {

                    for (let j = 0; j < 13 - i; j++) {

                        const hexPos = {

                            key: `hex-down-${i}-${j}`,

                            isChess: false,

                            style: {

                                left: Math.round(2 * this.width / 3 - this.width * 2 / (4 * 3 * 2) * 3 + this.width * 2 / (4 * 3 * 2) * (i - 5) + (this.gap + 2 * this.radius) * j),

                                top: Math.round(this.rotateY * 3 / 2 - this.width * 2 / (4 * 3) * Math.sqrt(3) / 2 * 3 + this.width * 2 / (4 * 3) * Math.sqrt(3) / 2 * (i - 5)),

                                zIndex: 1

                            }

                        };

                        this.position.push(hexPos);

                    }

                }

                

                // 4. 处理棋盘位置数据

                this.position = this.sort(this.position);

                this.setTarget(this.position);

                this.position = this.isOccupy(this.position);

                

                // 5. 渲染棋盘

                this.renderBoard();

            }

            

            // 四、棋盘位置排序

            sort(position) {

                // 1. 按y坐标排序

                position = position.sort((arg1, arg2) => {

                    return arg1.style.top > arg2.style.top ? 1 : -1;

                });

                

                // 2. 设置位置标记

                position = this.setMark('left', position);

                

                // 3. 计算每个位置的唯一坐标标识

                position = position.map((item, index) => {

                    let { left, top } = item.style;

                    let length = (Math.sqrt(3) * left + top - this.rotateY / 2) / 2;

                    let unit = 2 * this.width / 12 * Math.sqrt(3) / 2;

                    let num = Math.round((length / unit).toFixed(2)) + 1;

                    item.locate += `${num}-`;

                    length = (Math.sqrt(3) * left - top + 2 * this.rotateY * 3 / 4) / 2;

                    num = Math.round((length / unit).toFixed(2)) + 1;

                    item.locate += `${num}`;

                    return item;

                });

                return position;

            }

            

            // 五、设置位置标记

            setMark(prop, arr) {

                let lastTop = arr[0].style[prop], y = 0;

                let sortArr = arr.map((item, index) => {

                    let { top } = item.style;

                    item.locate = item.locate || '';

                    if (top != lastTop) {

                        y++;

                        item.locate += `${y}-`;

                    } else {

                        item.locate += `${y}-`;

                    }

                    lastTop = top;

                    return item;

                });

                return sortArr;

            }

            

            // 六、设置目标区域

            setTarget(position) {

                position.map((item, index) => {

                    if (item.isChess) {

                        let color = item.style.background;

                        if (this.setTargets[color]) {

                            let targetColor = this.setTargets[color]['targetColor'];

                            this.setTargets[targetColor].targetArray.push(JSON.parse(JSON.stringify(item)));

                        }

                    }

                });

            }

            

            // 七、判断位置是否被占用

            isOccupy(position) {

                let boards = position.filter((item) => {

                    return !item.isChess;

                });

                let chesses = position.filter((item) => {

                    return item.isChess;

                });

                boards = boards.map(item => {

                    let isOccupy = chesses.filter((chess) => {

                        return chess.locate === item.locate;

                    });

                    isOccupy.length > 0 ? item.isOccupy = true : item.isOccupy = false;

                    return item;

                });

                return boards.concat(chesses);

            }

            

            // 八、渲染棋盘

            renderBoard() {

                const board = document.getElementById('board');

                board.innerHTML = '';

                

                // 1. 计算缩放比例和偏移量

                const scale = Math.min(board.offsetWidth / (this.width * 2), board.offsetHeight / (this.rotateY * 2));

                const offsetX = (board.offsetWidth - this.width * 2 * scale) / 2;

                const offsetY = (board.offsetHeight - this.rotateY * 2 * scale) / 2;

                

                // 2. 渲染每个位置

                this.position.forEach(item => {

                    if (item.isChess) {

                        // 2.1 渲染棋子

                        const chess = document.createElement('div');

                        chess.className = 'chess';

                        chess.key = item.key;

                        chess.style.left = (item.style.left * scale + offsetX - 9) + 'px';

                        chess.style.top = (item.style.top * scale + offsetY - 9) + 'px';

                        chess.style.background = item.style.background;

                        chess.dataset.locate = item.locate;

                        chess.dataset.key = item.key;

                        chess.addEventListener('click', () => this.handleChessClick(item));

                        board.appendChild(chess);

                    } else {

                        // 2.2 渲染棋盘位置

                        const pos = document.createElement('div');

                        pos.className = 'position';

                        pos.key = item.key;

                        pos.style.left = (item.style.left * scale + offsetX - 10) + 'px';

                        pos.style.top = (item.style.top * scale + offsetY - 10) + 'px';

                        pos.dataset.locate = item.locate;

                        pos.dataset.key = item.key;

                        pos.addEventListener('click', () => this.handlePositionClick(item));

                        board.appendChild(pos);

                    }

                });

            }

            

            // 九、棋子点击处理

            handleChessClick(item) {

                if (!this.gameActive || this.moveInProgress) return;

                

                const currentPlayer = this.players[this.currentPlayerIndex];

                if (item.style.background !== currentPlayer.color) {

                    this.showMessage(`请${currentPlayer.name}走!`);

                    return;

                }

                

                this.clearSelection();

                this.selectedPiece = item;

                

                // 1. 高亮选中的棋子

                const chessElement = document.querySelector(`.chess[data-key="${item.key}"]`);

                if (chessElement) {

                    chessElement.classList.add('selected');

                }

                

                // 2. 计算有效移动

                this.calculateValidMoves(item);

            }

            

            // 十、棋盘位置点击处理

            handlePositionClick(item) {

                if (!this.gameActive || this.moveInProgress || !this.selectedPiece) return;

                

                const isValidMove = this.validMoves.some(move => move.locate === item.locate);

                if (isValidMove) {

                    this.moveChess(this.selectedPiece, item);

                }

            }

            

            // 十一、计算有效移动

            calculateValidMoves(itemMove) {

                let path = [];

                let { locate } = itemMove;

                let axises = locate.split('-');

                let allPath = [];

                let passNode = [];

                

                // 1. 获取相邻的空位

                let aroundPathLocate = [

                    `${axises[0] * 1}-${axises[1] * 1 - 1}-${axises[2] * 1 - 1}`,

                    `${axises[0] * 1}-${axises[1] * 1 + 1}-${axises[2] * 1 + 1}`,

                    `${axises[0] * 1 - 1}-${axises[1] * 1}-${axises[2] * 1 + 1}`,

                    `${axises[0] * 1 + 1}-${axises[1] * 1}-${axises[2] * 1 - 1}`,

                    `${axises[0] * 1 - 1}-${axises[1] * 1 - 1}-${axises[2] * 1}`,

                    `${axises[0] * 1 + 1}-${axises[1] * 1 + 1}-${axises[2] * 1}`

                ];

                

                this.position.forEach(item => {

                    if (!item.isChess && !item.isOccupy) {

                        if (aroundPathLocate.indexOf(item.locate) > -1) {

                            item['parent'] = [itemMove.locate];

                            path.push(item);

                        }

                    }

                });

                

                // 2. 计算跳跃路径

                this.getValidPoint(itemMove, this.position, allPath, passNode);

                path = path.concat(passNode);

                

                // 3. 去重

                path = this.uniqPath(path);

                this.validMoves = path;

                

                // 4. 高亮有效移动位置

                path.forEach(move => {

                    const posElement = document.querySelector(`.position[data-locate="${move.locate}"]`);

                    if (posElement) {

                        posElement.classList.add('valid-move');

                    }

                });

            }

            

            // 十二、获取有效跳跃点

            getValidPoint(itemMove, position, allPath, passNode) {

                let path = [];

                let { locate } = itemMove;

                let axises = locate.split('-');

                let nextJump = null;

                let arrs = [[], [], []];

                

                // 1. 按坐标轴分组

                position.forEach(item => {

                    if (!item.isChess && item.locate != itemMove.locate) {

                        let { locate } = item;

                        let itemAxises = locate.split('-');

                        if (itemAxises[0] == axises[0]) {

                            arrs[0].push(item);

                        } else if (itemAxises[1] == axises[1]) {

                            arrs[1].push(item);

                        } else if (itemAxises[2] == axises[2]) {

                            arrs[2].push(item);

                        }

                    }

                });

                

                // 2. 排序并查找跳跃点

                arrs = arrs.map((arr) => {

                    arr.push(itemMove);

                    arr = arr.sort((arg1, arg2) => {

                        return arg1.locate.split('-').slice(0, 2).join('') * 1 > arg2.locate.split('-').slice(0, 2).join('') * 1 ? 1 : -1;

                    });

                    return arr;

                });

                

                // 3. 查找跳跃路径

                arrs.forEach((arr, index) => {

                    let pos = -1;

                    arr.filter((item, i) => {

                        return item.locate == itemMove.locate && (pos = i);

                    });

                    

                    let left = pos - 1, right = pos + 1;

                    

                    // 3.1 向左查找

                    for (; left >= 0;) {

                        if (arr[left].isOccupy) {

                            let flag = false;

                            let end = left * 2 - pos;

                            if (end < 0 || end >= arr.length) {

                                break;

                            }

                            for (let start = left + (end - left) / Math.abs(end - left);

                                start >= Math.min(left, end) && start <= Math.max(left, end);

                                start = start + (end - left) / Math.abs(end - left)) {

                                if (arr[start].isOccupy) {

                                    flag = true;

                                    break;

                                }

                            }

                            if (!flag) {

                                path.push(arr[end]);

                            }

                            flag = false;

                            break;

                        } else {

                            left--;

                        }

                    }

                    

                    // 3.2 向右查找

                    for (; right < arr.length;) {

                        if (arr[right].isOccupy) {

                            let flag = false;

                            let end = right * 2 - pos;

                            if (end < 0 || end >= arr.length) {

                                break;

                            }

                            for (let start = right + (end - right) / Math.abs(end - right);

                                start >= Math.min(right, end) && start <= Math.max(right, end);

                                start = start + (end - right) / Math.abs(end - right)) {

                                if (arr[start].isOccupy) {

                                    flag = true;

                                    break;

                                }

                            }

                            if (!flag) {

                                path.push(arr[end]);

                            }

                            flag = false;

                            break;

                        } else {

                            right++;

                        }

                    }

                });

                

                // 4. 记录路径

                path.forEach(node => {

                    if (!node['parent']) {

                        node['parent'] = [];

                    }

                    node['parent'].push(itemMove.locate);

                });

                

                allPath.push(...path);

                

                // 5. 递归查找更多跳跃点

                if (allPath.length >= 1) {

                    nextJump = allPath[0];

                    passNode.push(nextJump);

                    allPath.splice(0, 1);

                    return nextJump ? this.getValidPoint(nextJump, position, allPath, passNode) : passNode;

                }

                

                return passNode;

            }

            

            // 十三、路径去重

            uniqPath(path) {

                let newPath = [];

                if (path.length > 0) {

                    path.forEach(pathNode => {

                        let index;

                        let tempoPath = newPath.filter((keyPathNode, i) => {

                            if (pathNode.key === keyPathNode.key) {

                                index = i;

                                return true;

                            } else {

                                return false;

                            }

                        });

                        

                        if (tempoPath.length === 0) {

                            if (!pathNode['parent']) pathNode['parent'] = [];

                            newPath.push(pathNode);

                        } else {

                            let firstPathNode = JSON.parse(JSON.stringify(newPath[index]));

                            for (let i = 0; i < tempoPath.length; i++) {

                                firstPathNode['parent'] = firstPathNode['parent'].concat(tempoPath[i]['parent']);

                                firstPathNode['parent'] = [...new Set(firstPathNode['parent'])];

                            }

                            newPath[index] = firstPathNode;

                        }

                    });

                }

                return newPath;

            }

            

            // 十四、移动棋子

            moveChess(fromItem, toItem) {

                if (this.moveInProgress) return;

                this.moveInProgress = true;

                

                const fromElement = document.querySelector(`.chess[data-key="${fromItem.key}"]`);

                const toPosition = document.querySelector(`.position[data-locate="${toItem.locate}"]`);

                

                if (!fromElement || !toPosition) return;

                

                // 1. 更新位置数据

                fromItem.locate = toItem.locate;

                

                // 2. 动画移动棋子

                fromElement.classList.add('moving');

                fromElement.style.left = (parseInt(toPosition.style.left) + 1) + 'px';

                fromElement.style.top = (parseInt(toPosition.style.top) + 1) + 'px';

                fromElement.dataset.locate = toItem.locate;

                

                // 3. 移动完成后的处理

                setTimeout(() => {

                    fromElement.classList.remove('moving');

                    this.clearSelection();

                    this.moveInProgress = false;

                    

                    // 3.1 更新占用状态

                    this.position = this.isOccupy(this.position);

                    

                    // 3.2 检查胜利

                    if (this.checkWin(fromItem.style.background)) {

                        this.endGame(fromItem.style.background);

                        return;

                    }

                    

                    // 3.3 切换玩家

                    this.nextTurn();

                }, 600);

            }

            

            // 十五、检查胜利条件

            checkWin(color) {

                let target = this.setTargets[color];

                if (!target) return false;

                

                let colorChess = this.position.filter(item => {

                    return item.style.background === color;

                });

                let targetArray = target['targetArray'];

                let count = 0;

                

                // 1. 统计在目标区域的棋子数量

                targetArray.forEach(item => {

                    let { locate } = item;

                    colorChess.forEach(chess => {

                        if (locate === chess.locate) {

                            count++;

                        }

                    });

                });

                

                // 2. 全部棋子到达目标区域则获胜

                return count === targetArray.length;

            }

            

            // 十六、切换回合

            nextTurn() {

                this.currentPlayerIndex = (this.currentPlayerIndex + 1) % this.players.length;

                this.updatePlayerIndicators();

                

                const currentPlayer = this.players[this.currentPlayerIndex];

                this.showMessage(`${currentPlayer.name}的回合`);

                

                // 1. AI回合处理

                if (currentPlayer.isAI) {

                    this.showAIThinking();

                    setTimeout(() => this.makeAIMove(), 1500);

                }

            }

            

            // 十七、AI移动逻辑

            makeAIMove() {

                const currentPlayer = this.players[this.currentPlayerIndex];

                const aiPieces = this.position.filter(item => 

                    item.isChess && item.style.background === currentPlayer.color

                );

                

                let bestMove = null;

                let maxMoves = 0;

                

                // 1. 选择能移动最远的棋子

                aiPieces.forEach(piece => {

                    this.calculateValidMoves(piece);

                    if (this.validMoves.length > maxMoves) {

                        maxMoves = this.validMoves.length;

                        bestMove = { piece, moves: [...this.validMoves] };

                    }

                    this.clearSelection();

                });

                

                // 2. 执行移动

                if (bestMove && bestMove.moves.length > 0) {

                    const targetMove = bestMove.moves[Math.floor(Math.random() * bestMove.moves.length)];

                    this.selectedPiece = bestMove.piece;

                    this.moveChess(bestMove.piece, targetMove);

                } else {

                    this.nextTurn();

                }

            }

            

            // 十八、清除选择状态

            clearSelection() {

                document.querySelectorAll('.chess.selected').forEach(el => {

                    el.classList.remove('selected');

                });

                document.querySelectorAll('.position.valid-move').forEach(el => {

                    el.classList.remove('valid-move');

                });

                this.selectedPiece = null;

                this.validMoves = [];

            }

            

            // 十九、更新玩家指示器

            updatePlayerIndicators() {

                document.querySelectorAll('.player-indicator').forEach((el, index) => {

                    if (index < this.players.length) {

                        if (index === this.currentPlayerIndex) {

                            el.classList.add('current-player');

                        } else {

                            el.classList.remove('current-player');

                        }

                        el.style.background = this.players[index].color;

                    }

                });

            }

            

            // 二十、显示消息

            showMessage(text) {

                const messageEl = document.getElementById('message');

                messageEl.textContent = text;

                messageEl.classList.remove('winner-message');

            }

            

            // 二十一、显示AI思考状态

            showAIThinking() {

                const messageEl = document.getElementById('message');

                messageEl.innerHTML = `AI思考中<div class="ai-thinking"><span></span><span></span><span></span></div>`;

            }

            

            // 二十二、游戏结束处理

            endGame(color) {

                this.gameActive = false;

                const winner = this.players.find(p => p.color === color);

                const messageEl = document.getElementById('message');

                messageEl.textContent = `🎉 ${winner.name} 获胜!`;

                messageEl.classList.add('winner-message');

            }

            

            // 二十三、开始游戏

            startGame() {

                this.gameActive = true;

                this.currentPlayerIndex = 0;

                this.initBoard();

                this.updatePlayerIndicators();

                this.showMessage('游戏开始!你的回合');

            }

            

            // 二十四、重置游戏

            resetGame() {

                this.gameActive = false;

                this.currentPlayerIndex = 0;

                this.selectedPiece = null;

                this.validMoves = [];

                this.moveInProgress = false;

                this.initBoard();

                this.updatePlayerIndicators();

                this.showMessage('点击"开始游戏"开始对战');

            }

            

            // 二十五、设置事件监听

            setup

            setupEventListeners() {

                document.getElementById('startBtn').addEventListener('click', () => this.startGame());

                document.getElementById('resetBtn').addEventListener('click', () => this.resetGame());

            }

        }

        

        // 二十六、初始化游戏

        document.addEventListener('DOMContentLoaded', () => {

            new ChineseCheckersGame();

        });

    </script>

</body>

</html>

 

http://www.dtcms.com/a/596486.html

相关文章:

  • uni-app:实现快递的节点功能
  • 使用虚拟机搭建简易K8s实验环境的一种方法
  • 构建下一代临床AI诊断系统:基于CPC-Bench基准的工程化路线图(上)
  • Electron 原理浅析
  • Git 命令全攻略:从入门到实战
  • React底层原理
  • tensorflow 图像分类 之四
  • GEO优化:针对生成式AI内容分发逻辑的四大维度优化策略
  • 做a手机视频在线观看网站网页程序开发采购
  • USP-Ulysses+Ring-Attention技术原理
  • mirage 接口mock 拦截
  • flash网站设计教程北京建设网上银行
  • 高端网站建设设计公司有哪些wordpress网站迁移后插件
  • redis进阶 - 底层数据结构
  • 【自然语言处理】语料库:自然语言处理的基石资源与发展全景
  • Rust: 量化策略回测与简易线程池构建、子线程执行观测
  • 基于systemd的系统负载控制与检测方案
  • 闲谈-三十而已
  • LangChain 是一个 **大语言模型(LLM)应用开发框架**
  • 从RAM/ROM到Redis:项目架构设计的存储智慧
  • 高中课程免费教学网站网页塔防游戏排行榜
  • Access导出带图表的 HTML 报表:技术实现详解
  • 郑州上海做网站的公司嘉兴网站建设有前途吗
  • 学习JavaScript进阶记录(二)
  • 优化用户体验的小点:乐观更新链路 双数据库查询
  • C++—list:list的使用及模拟实现
  • EasyExcel 与 Apache POI 版本冲突导致的 `NoSuchMethodError` 异常
  • WebServer04
  • 品牌网站建设技术网站搜索引擎优化诊断
  • 优秀企业网站设计WordPress评论楼层