这个扫雷还可以

这个扫雷还可以

图片[1]|这个扫雷还可以|不死鸟资源网
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>扫雷游戏</title>
    <link href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-100-M/font-awesome/6.0.0/css/all.min.css"  rel="stylesheet">
    <link href="https://s2.ssl.qhres2.com/static/56662140ef7d5d03.css"  rel="stylesheet">
    <style>
        :root {
            --primary-color: #3b82f6;
            --bg-color: #ffffff;
            --text-color: #1f2937;
            --border-color: #e5e7eb;
            --cell-bg: #f9fafb;
            --cell-hover: #f3f4f6;
            --flag-color: #ef4444;
            --mine-color: #6b7280;
            --revealed-color: #e5e7eb;
            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
            --input-bg: #ffffff;
            --input-color: #1f2937;
            --input-border: #e5e7eb;
        }

        .dark {
            --primary-color: #60a5fa;
            --bg-color: #1f2937;
            --text-color: #f9fafb;
            --border-color: #374151;
            --cell-bg: #111827;
            --cell-hover: #1e40af;
            --flag-color: #f87171;
            --mine-color: #9ca3af;
            --revealed-color: #374151;
            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.25), 0 2px 4px -1px rgba(0, 0, 0, 0.2);
            --input-bg: #1f2937;
            --input-color: #f9fafb;
            --input-border: #374151;
        }

        body {
            font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
            background-color: var(--bg-color);
            color: var(--text-color);
            transition: background-color 0.3s ease, color 0.3s ease;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            padding: 2rem;
        }

        /* 修改输入框样式 */
        input {
            padding: 0.5rem;
            border-radius: 0.375rem;
            border: 1px solid var(--input-border);
            background-color: var(--input-bg);
            color: var(--input-color);
            transition: all 0.2s ease;
        }

        /* 修改自定义控件的间距 */
        #customControls {
            display: none;
            gap: 0.5rem;
        }

        .container {
            max-width: 800px;
            width: 100%;
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 2rem;
            padding-bottom: 1rem;
            border-bottom: 1px solid var(--border-color);
        }

        .title {
            font-size: 2rem;
            font-weight: 700;
            letter-spacing: -0.025em;
        }

        .theme-toggle {
            position: relative;
            width: 60px;
            height: 30px;
            border-radius: 15px;
            background-color: var(--border-color);
            cursor: pointer;
            transition: background-color 0.3s ease;
            display: flex;
            align-items: center;
            padding: 0 7px;
            justify-content: space-between;
        }

        .theme-toggle i {
            font-size: 14px;
            color: var(--text-color);
            transition: color 0.3s ease;
            z-index: 1;         /* 设置层级在圆圈之上 */
        }

        .theme-toggle::before {
            content: '';
            position: absolute;
            width: 24px;
            height: 24px;
            border-radius: 50%;
            background-color: var(--primary-color);
            left: 3px;
            transition: transform 0.3s ease, background-color 0.3s ease;
        }

        .dark .theme-toggle::before {
            transform: translateX(30px);
        }

        .controls {
            display: flex;
            gap: 1rem;
            margin-bottom: 1.5rem;
        }

        select, button {
            padding: 0.5rem 1rem;
            border-radius: 0.375rem;
            border: 1px solid var(--border-color);
            background-color: var(--cell-bg);
            color: var(--text-color);
            font-weight: 500;
            transition: all 0.2s ease;
            cursor: pointer;
        }

        select:hover, button:hover {
            border-color: var(--primary-color);
        }

        select:focus, button:focus {
            outline: none;
            box-shadow: 0 0 0 2px var(--primary-color);
        }

        .game-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 1rem;
            font-size: 1.1rem;
        }

        .minesweeper-board {
            display: grid;
            grid-template-columns: repeat(var(--cols, 10), 1fr);
            gap: 2px;
            margin: 0 auto;
            width: fit-content;
            background-color: var(--border-color);
            border: 2px solid var(--border-color);
            border-radius: 0.375rem;
            overflow: hidden;
            box-shadow: var(--shadow);
        }

        .cell {
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: var(--cell-bg);
            font-weight: 700;
            cursor: pointer;
            user-select: none;
            transition: all 0.2s ease;
        }

        .cell:hover {
            background-color: var(--cell-hover);
        }

        .cell.revealed  {
            background-color: var(--revealed-color);
            cursor: default;
        }

        .cell.mine  {
            background-color: var(--mine-color);
            color: white;
        }

        .cell.flagged  {
            color: var(--flag-color);
        }

        .cell-1 { color: #3b82f6; }
        .cell-2 { color: #10b981; }
        .cell-3 { color: #ef4444; }
        .cell-4 { color: #7c3aed; }
        .cell-5 { color: #f59e0b; }
        .cell-6 { color: #06b6d4; }
        .cell-7 { color: #000000; }
        .cell-8 { color: #64748b; }

        .game-over {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.7);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 100;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s ease;
        }

        .game-over.show  {
            opacity: 1;
            pointer-events: all;
        }

        .game-over-content {
            background-color: var(--bg-color);
            padding: 2rem;
            border-radius: 0.5rem;
            text-align: center;
            max-width: 400px;
            width: 90%;
            box-shadow: var(--shadow);
        }

        .game-over h2 {
            font-size: 1.5rem;
            margin-bottom: 1rem;
        }

        .game-over button {
            margin-top: 1rem;
            background-color: var(--primary-color);
            color: white;
            border: none;
        }

        .game-over button:hover {
            background-color: var(--cell-hover);
        }

        @media (max-width: 640px) {
            .cell {
                width: 25px;
                height: 25px;
                font-size: 0.8rem;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1 class="title">扫雷</h1>
        <div class="theme-toggle" id="themeToggle">
            <i class="fas fa-sun"></i>
            <i class="fas fa-moon"></i>
        </div>
    </div>

    <div class="controls">
        <select id="difficulty">
            <option value="easy">简单 (9×9, 10雷)</option>
            <option value="medium" selected>中等 (16×16, 40雷)</option>
            <option value="hard">困难 (30×16, 99雷)</option>
            <option value="custom">自定义</option>
        </select>

        <div id="customControls" style="display: none;">
            <input type="number" id="customWidth" min="5" max="30" placeholder="宽度" style="width: 80px;">
            <input type="number" id="customHeight" min="5" max="30" placeholder="高度" style="width: 80px;">
            <input type="number" id="customMines" min="1" placeholder="雷数" style="width: 80px;">
        </div>

        <button id="newGame">新游戏</button>
    </div>

    <div class="game-info">
        <div>剩余雷数: <span id="minesLeft">40</span></div>
        <div>时间: <span id="time">0</span>秒</div>
    </div>

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

<div class="game-over" id="gameOver">
    <div class="game-over-content">
        <h2 id="gameOverMessage">游戏结束!</h2>
        <button id="restartGame">重新开始</button>
    </div>
</div>

<script>
    // 游戏状态
    let board = [];
    let revealed = [];
    let flagged = [];
    let gameOver = false;
    let gameWon = false;
    let minesLeft = 40;
    let timer = null;
    let seconds = 0;
    let firstClick = true;
    let darkMode = false;

    // 难度设置
    const difficulties = {
        easy: { width: 9, height: 9, mines: 10 },
        medium: { width: 16, height: 16, mines: 40 },
        hard: { width: 30, height: 16, mines: 99 }
    };
    let currentDifficulty = 'medium';
    let width = 16;
    let height = 16;
    let mines = 40;

    // DOM 元素
    const boardElement = document.getElementById('board');
    const minesLeftElement = document.getElementById('minesLeft');
    const timeElement = document.getElementById('time');
    const difficultySelect = document.getElementById('difficulty');
    const customControls = document.getElementById('customControls');
    const newGameButton = document.getElementById('newGame');
    const gameOverElement = document.getElementById('gameOver');
    const gameOverMessage = document.getElementById('gameOverMessage');
    const restartButton = document.getElementById('restartGame');
    const themeToggle = document.getElementById('themeToggle');
    const customWidth = document.getElementById('customWidth');
    const customHeight = document.getElementById('customHeight');
    const customMines = document.getElementById('customMines');

    // 初始化游戏
    function initGame() {
        // 清除之前的游戏状态
        clearInterval(timer);
        seconds = 0;
        timeElement.textContent  = seconds;
        firstClick = true;
        gameOver = false;
        gameWon = false;
        minesLeft = mines;
        minesLeftElement.textContent  = minesLeft;

        // 初始化数组
        board = Array(height).fill().map(() => Array(width).fill(0));
        revealed = Array(height).fill().map(() => Array(width).fill(false));
        flagged = Array(height).fill().map(() => Array(width).fill(false));

        // 渲染棋盘
        renderBoard();

        // 隐藏游戏结束界面
        gameOverElement.classList.remove('show');
    }

    // 生成雷区
    function generateMines(firstX, firstY) {
        // 确保第一次点击的位置及其周围没有雷
        const safeZone = [];
        for (let y = Math.max(0,  firstY - 1); y <= Math.min(height  - 1, firstY + 1); y++) {
            for (let x = Math.max(0,  firstX - 1); x <= Math.min(width  - 1, firstX + 1); x++) {
                safeZone.push(`${x},${y}`);
            }
        }

        // 放置雷
        let minesPlaced = 0;
        while (minesPlaced < mines) {
            const x = Math.floor(Math.random()  * width);
            const y = Math.floor(Math.random()  * height);

            // 确保不在安全区域且没有重复放置
            if (!safeZone.includes(`${x},${y}`)  && board[y][x] !== -1) {
                board[y][x] = -1;
                minesPlaced++;

                // 更新周围单元格的数字
                for (let dy = -1; dy <= 1; dy++) {
                    for (let dx = -1; dx <= 1; dx++) {
                        const nx = x + dx;
                        const ny = y + dy;
                        if (nx >= 0 && nx < width && ny >= 0 && ny < height && board[ny][nx] !== -1) {
                            board[ny][nx]++;
                        }
                    }
                }
            }
        }
    }

    // 渲染棋盘
    function renderBoard() {
        boardElement.style.setProperty('--cols',  width);
        boardElement.innerHTML  = '';

        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                const cell = document.createElement('div');
                cell.className  = 'cell';
                cell.dataset.x  = x;
                cell.dataset.y  = y;

                if (revealed[y][x]) {
                    cell.classList.add('revealed');
                    if (board[y][x] === -1) {
                        cell.classList.add('mine');
                        cell.innerHTML  = '<i class="fas fa-bomb"></i>';
                    } else if (board[y][x] > 0) {
                        cell.textContent  = board[y][x];
                        cell.classList.add(`cell-${board[y][x]}`);
                    }
                } else if (flagged[y][x]) {
                    cell.classList.add('flagged');
                    cell.innerHTML  = '<i class="fas fa-flag"></i>';
                }

                boardElement.appendChild(cell);
            }
        }
    }

    // 揭示单元格
    function revealCell(x, y) {
        if (x < 0 || x >= width || y < 0 || y >= height || revealed[y][x] || flagged[y][x]) {
            return;
        }

        revealed[y][x] = true;

        if (board[y][x] === -1) {
            // 踩到雷,游戏结束
            gameOver = true;
            revealAllMines();
            endGame(false);
            return;
        }

        // 如果是空白单元格,递归揭示周围的单元格
        if (board[y][x] === 0) {
            for (let dy = -1; dy <= 1; dy++) {
                for (let dx = -1; dx <= 1; dx++) {
                    revealCell(x + dx, y + dy);
                }
            }
        }

        // 检查是否获胜
        checkWin();

        // 重新渲染棋盘
        renderBoard();
    }

    // 切换标记
    function toggleFlag(x, y) {
        if (revealed[y][x] || gameOver) {
            return;
        }

        flagged[y][x] = !flagged[y][x];
        minesLeft += flagged[y][x] ? -1 : 1;
        minesLeftElement.textContent  = minesLeft;

        renderBoard();

        // 检查是否获胜
        checkWin();
    }

    // 揭示所有雷
    function revealAllMines() {
        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                if (board[y][x] === -1) {
                    revealed[y][x] = true;
                }
            }
        }
        renderBoard();
    }

    // 检查是否获胜
    function checkWin() {
        let allRevealed = true;
        let allMinesFlagged = true;

        for (let y = 0; y < height; y++) {
            for (let x = 0; x < width; x++) {
                if (board[y][x] !== -1 && !revealed[y][x]) {
                    allRevealed = false;
                }
                if (board[y][x] === -1 && !flagged[y][x]) {
                    allMinesFlagged = false;
                }
            }
        }

        if (allRevealed || allMinesFlagged) {
            gameWon = true;
            endGame(true);
        }
    }

    // 结束游戏
    function endGame(won) {
        gameOver = true;
        clearInterval(timer);

        if (won) {
            gameOverMessage.textContent  = '恭喜你赢了!';
        } else {
            gameOverMessage.textContent  = '游戏结束!';
        }

        gameOverElement.classList.add('show');
    }

    // 开始计时器
    function startTimer() {
        timer = setInterval(() => {
            seconds++;
            timeElement.textContent  = seconds;
        }, 1000);
    }

    // 切换深色模式
    function toggleDarkMode() {
        darkMode = !darkMode;
        document.body.classList.toggle('dark',  darkMode);

        // 保存用户偏好到本地存储
        localStorage.setItem('minesweeperDarkMode',  darkMode);
    }

    // 事件监听
    boardElement.addEventListener('click',  (e) => {
        if (gameOver) return;

        const cell = e.target.closest('.cell');
        if (!cell || cell.classList.contains('revealed')  || cell.classList.contains('flagged'))  {
            return;
        }

        const x = parseInt(cell.dataset.x);
        const y = parseInt(cell.dataset.y);

        if (firstClick) {
            firstClick = false;
            generateMines(x, y);
            startTimer();
        }

        revealCell(x, y);
    });

    boardElement.addEventListener('contextmenu',  (e) => {
        e.preventDefault();

        const cell = e.target.closest('.cell');
        if (!cell || cell.classList.contains('revealed')  || gameOver) {
            return;
        }

        const x = parseInt(cell.dataset.x);
        const y = parseInt(cell.dataset.y);

        toggleFlag(x, y);
    });

    difficultySelect.addEventListener('change',  () => {
        currentDifficulty = difficultySelect.value;

        if (currentDifficulty === 'custom') {
            customControls.style.display  = 'flex';
            customWidth.value  = width;
            customHeight.value  = height;
            customMines.value  = mines;
        } else {
            customControls.style.display  = 'none';
            width = difficulties[currentDifficulty].width;
            height = difficulties[currentDifficulty].height;
            mines = difficulties[currentDifficulty].mines;
            initGame();
        }
    });

    newGameButton.addEventListener('click',  initGame);

    restartButton.addEventListener('click',  () => {
        initGame();
    });

    themeToggle.addEventListener('click',  toggleDarkMode);

    customWidth.addEventListener('change',  updateCustomSettings);
    customHeight.addEventListener('change',  updateCustomSettings);
    customMines.addEventListener('change',  updateCustomSettings);

    function updateCustomSettings() {
        const newWidth = parseInt(customWidth.value)  || width;
        const newHeight = parseInt(customHeight.value)  || height;
        const newMines = parseInt(customMines.value)  || mines;

        // 验证输入
        if (newWidth >= 5 && newWidth <= 30 &&
            newHeight >= 5 && newHeight <= 30 &&
            newMines >= 1 && newMines < newWidth * newHeight) {
            width = newWidth;
            height = newHeight;
            mines = newMines;
            initGame();
        } else {
            alert('无效的自定义设置!宽度和高度应在5-30之间,雷数应小于总单元格数。');
        }
    }

    // 初始化
    function initialize() {
        // 检查本地存储中的深色模式偏好
        const savedDarkMode = localStorage.getItem('minesweeperDarkMode')  === 'true';
        if (savedDarkMode) {
            darkMode = true;
            document.body.classList.add('dark');
        }

        initGame();
    }

    initialize();
</script>
</body>
</html>

扫雷就是点出数字之后,这个数字就是以他为中心九宫格内的雷,比如图中的紫色数字4,说明它为中心,九宫格内有4个雷,已经开出的区域都是正常的,说明另外4个格子都是雷。当你知道这4个是雷之后,就可以看一下4旁边的2,也就是这个2的九宫格内,有2个雷,而4的右上两个格子是雷,和2共用了这两个九宫格,所以2的最上面一行就是左边两个雷,右边一格正常,以此类推

本站资源均为作者提供和网友推荐收集整理而来,仅供学习和研究使用,请在下载后24小时内删除,谢谢合作!
这个扫雷还可以|不死鸟资源网
这个扫雷还可以
此内容为免费阅读,请登录后查看
¥0
限时特惠
¥99
文章采用CC BY-NC-SA 4.0许可协议授权
免费阅读
THE END
点赞5 分享