拼图游戏edit icon

创建者:
用户3M0qnYRe
Fork(复制)
下载
嵌入
BUG反馈
index.html
style.css
index.js
index.html
            
            <!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>15拼图游戏</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 20px;
            color: #333;
        }
        
        .container {
            background-color: rgba(255, 255, 255, 0.95);
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            padding: 30px;
            max-width: 500px;
            width: 100%;
            text-align: center;
        }
        
        h1 {
            color: #2c3e50;
            margin-bottom: 20px;
            font-size: 28px;
            text-shadow: 1px 1px 2px rgba(0,0,0,0.1);
        }
        
        .instructions {
            background-color: #f8f9fa;
            border-left: 4px solid #3498db;
            padding: 15px;
            margin: 20px 0;
            text-align: left;
            border-radius: 0 8px 8px 0;
            font-size: 15px;
        }
        
        .game-board {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            grid-gap: 8px;
            margin: 25px auto;
            max-width: 350px;
        }
        
        .tile {
            aspect-ratio: 1;
            background: #3498db;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            font-weight: bold;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s ease;
            box-shadow: 0 3px 6px rgba(0,0,0,0.1);
            user-select: none;
        }
        
        .tile:hover {
            transform: scale(1.03);
            background: #2980b9;
        }
        
        .empty {
            background: #ecf0f1;
            box-shadow: inset 0 0 10px rgba(0,0,0,0.1);
        }
        
        .empty:hover {
            background: #ecf0f1;
            transform: none;
            cursor: default;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 15px;
            margin: 20px 0;
        }
        
        button {
            background: #2ecc71;
            color: white;
            border: none;
            padding: 12px 20px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            font-weight: bold;
            transition: all 0.2s;
            box-shadow: 0 3px 6px rgba(0,0,0,0.1);
        }
        
        button:hover {
            background: #27ae60;
            transform: translateY(-2px);
        }
        
        button#reset {
            background: #e74c3c;
        }
        
        button#reset:hover {
            background: #c0392b;
        }
        
        .message {
            margin-top: 20px;
            padding: 15px;
            border-radius: 8px;
            font-weight: bold;
            display: none;
        }
        
        .success {
            background-color: #d4edda;
            color: #155724;
            display: block;
            animation: fadeIn 0.5s;
        }
        
        .key-hint {
            margin-top: 15px;
            font-size: 14px;
            color: #7f8c8d;
        }
        
        @keyframes fadeIn {
            from { opacity: 0; }
            to { opacity: 1; }
        }
        
        @media (max-width: 480px) {
            .container {
                padding: 20px;
            }
            
            .game-board {
                max-width: 300px;
            }
            
            .tile {
                font-size: 20px;
            }
            
            button {
                padding: 10px 15px;
                font-size: 14px;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>15拼图游戏</h1>
        
        <div class="instructions">
            <p>在4×4的16个格中随机填上1-15的数字,剩下一个格为空。</p>
            <p>使用方向键或点击移动空格旁的数字,最终形成以下图案为过关:</p>
            <p>1 2 3 4<br>5 6 7 8<br>9 10 11 12<br>13 14 15</p>
        </div>
        
        <div class="game-board" id="gameBoard">
            <!-- 拼图块将通过JavaScript动态生成 -->
        </div>
        
        <div class="controls">
            <button id="newGame">新游戏</button>
            <button id="reset">重置</button>
        </div>
        
        <div class="message" id="message"></div>
        
        <div class="key-hint">
            使用键盘方向键 ↑ ↓ ← → 也可以移动数字
        </div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const gameBoard = document.getElementById('gameBoard');
            const newGameBtn = document.getElementById('newGame');
            const resetBtn = document.getElementById('reset');
            const messageDiv = document.getElementById('message');
            
            let board = [];
            let emptyPos = {row: 3, col: 3}; // 空格位置
            let initialBoard = []; // 存储初始状态用于重置
            
            // 初始化游戏
            function initGame() {
                // 创建1-15的数字数组
                let numbers = Array.from({length: 15}, (_, i) => i + 1);
                
                // 随机打乱数组(Fisher-Yates洗牌算法)
                for (let i = numbers.length - 1; i > 0; i--) {
                    const j = Math.floor(Math.random() * (i + 1));
                    [numbers[i], numbers[j]] = [numbers[j], numbers[i]];
                }
                
                // 初始化4x4游戏板
                board = [];
                let index = 0;
                for (let i = 0; i < 4; i++) {
                    board[i] = [];
                    for (let j = 0; j < 4; j++) {
                        if (i === 3 && j === 3) {
                            board[i][j] = 0; // 最后一个位置为空
                            emptyPos = {row: i, col: j};
                        } else {
                            board[i][j] = numbers[index++];
                        }
                    }
                }
                
                // 保存初始状态
                initialBoard = JSON.parse(JSON.stringify(board));
                
                renderBoard();
                messageDiv.className = 'message';
            }
            
            // 渲染游戏板
            function renderBoard() {
                gameBoard.innerHTML = '';
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        const tileValue = board[i][j];
                        const tile = document.createElement('div');
                        tile.className = tileValue === 0 ? 'tile empty' : 'tile';
                        tile.textContent = tileValue === 0 ? '' : tileValue;
                        tile.dataset.row = i;
                        tile.dataset.col = j;
                        
                        // 添加点击事件
                        if (tileValue !== 0) {
                            tile.addEventListener('click', function() {
                                const row = parseInt(this.dataset.row);
                                const col = parseInt(this.dataset.col);
                                moveTile(row, col);
                            });
                        }
                        
                        gameBoard.appendChild(tile);
                    }
                }
            }
            
            // 移动拼图块
            function moveTile(row, col) {
                // 检查是否与空格相邻
                if (
                    (Math.abs(row - emptyPos.row) === 1 && col === emptyPos.col) ||
                    (Math.abs(col - emptyPos.col) === 1 && row === emptyPos.row)
                ) {
                    // 交换位置
                    board[emptyPos.row][emptyPos.col] = board[row][col];
                    board[row][col] = 0;
                    emptyPos = {row, col};
                    
                    renderBoard();
                    checkWin();
                }
            }
            
            // 检查是否获胜
            function checkWin() {
                let expectedValue = 1;
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        // 跳过最后一个位置
                        if (i === 3 && j === 3) {
                            if (board[i][j] !== 0) return false;
                        } else {
                            if (board[i][j] !== expectedValue++) return false;
                        }
                    }
                }
                
                // 显示胜利消息
                messageDiv.textContent = '恭喜!您成功完成了拼图!';
                messageDiv.className = 'message success';
            }
            
            // 重置游戏
            function resetGame() {
                board = JSON.parse(JSON.stringify(initialBoard));
                
                // 找到空格位置
                for (let i = 0; i < 4; i++) {
                    for (let j = 0; j < 4; j++) {
                        if (board[i][j] === 0) {
                            emptyPos = {row: i, col: j};
                            break;
                        }
                    }
                }
                
                renderBoard();
                messageDiv.className = 'message';
            }
            
            // 键盘控制
            document.addEventListener('keydown', function(event) {
                let newRow = emptyPos.row;
                let newCol = emptyPos.col;
                
                switch(event.key) {
                    case 'ArrowUp':
                        if (emptyPos.row < 3) newRow++;
                        break;
                    case 'ArrowDown':
                        if (emptyPos.row > 0) newRow--;
                        break;
                    case 'ArrowLeft':
                        if (emptyPos.col < 3) newCol++;
                        break;
                    case 'ArrowRight':
                        if (emptyPos.col > 0) newCol--;
                        break;
                    default:
                        return; // 如果不是方向键,不做任何事
                }
                
                if (newRow !== emptyPos.row || newCol !== emptyPos.col) {
                    moveTile(newRow, newCol);
                }
            });
            
            // 按钮事件监听
            newGameBtn.addEventListener('click', initGame);
            resetBtn.addEventListener('click', resetGame);
            
            // 初始化游戏
            initGame();
        });
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台