HTML实现 扫雷游戏

ops/2024/11/26 10:15:47/

前言:

游戏起源与发展

  • 扫雷游戏的雏形可追溯到 1973 年的 “方块(cube)” 游戏,后经改编出现了 “rlogic” 游戏,玩家需为指挥中心探出安全路线避开地雷。在此基础上,开发者汤姆・安德森编写出了扫雷游戏的雏形.

  • 1992 年,微软在 windows3.1 系统中首次预装了《扫雷》,将其作为训练用户鼠标操作能力的软件.

  • 虽从 windows8 开始,系统不再默认安装扫雷游戏,但它依旧凭借自身魅力受到众多玩家喜爱,甚至有玩家不断刷新时间记录来挑战自我.

游戏规则

  • 胜利条件:找出所有地雷且不踩到地雷,或者在规定时间内尽可能多地找出地雷.

  • 失败条件:翻开了埋有地雷的方块.

  • 基础操作:左键点击未打开的格子可将其打开;右键点击可标雷 / 取消标雷;双击(左右键同时点击)已打开的数字,若该数字周围标的雷数量等于该数字,会同时打开该数字周围剩余所有格子.

游戏界面及信息

  • 剩余雷数:显示在游戏界面左上角,为总雷数减去已标雷数,可据此了解雷区剩余雷的大致情况.

  • 计时器:位于右上角,从本局游戏第一次操作为 0.001 秒开始计时,可用于记录游戏所用时间及玩家挑战自我时作为参考

技巧与策略

  • 数字推理:数字代表其周围 8 个方格中的雷数,若数字为 0,游戏会自动打开周围所有格子;若一个方格周围已标记的雷数等于该方格上的数字,那么其周围未标记的方格都可安全打开.

  • 常见阵型判断:如 “111”“22”“112” 等常见数字组合,可依据特定规律快速判断雷的位置.

  • 边缘优先:可先从雷区边缘开始点击,因为边缘方格的周围方格数量相对较少,更容易判断雷的位置,降低推理难度7.

  • 标记问号:当无法确定方格是否有雷时,可右键点击两次标记问号,后续再根据其他信息进一步判断.

游戏变化与创新

  • 在线多人模式:如《一起来扫雷》,玩家可与世界各地的玩家合作或竞争,共同清除地图上的地雷,还能积累积分兑换装饰,装扮游戏界面.

  • VR 版扫雷:扫雷 VR 将平面的扫雷游戏搬到了 3D 场景中,增加了游戏的趣味性和沉浸感.

  • 融合其他元素:《扫雷俄罗斯方块》结合了扫雷和俄罗斯方块的元素,雷区不断向上生长,找到所有地雷时行才会被清除

以上内容由ai生成

正文:
1.自己实现一个扫雷游戏

2.使用HTML实现

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>扫雷游戏</title><linkhref="https://fonts.googleapis.com/css?family=Space+Mono:400,700"rel="stylesheet"/><linkrel="stylesheet"href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"/><style>@charset "UTF-8";*,*:before,*:after {box-sizing: inherit;}html {box-sizing: border-box;}body {text-align: center;color: #333;padding: 20px 20px 100px;background-color: #efefef;font-family: 'Space Mono', monospace;}h1 {margin: 0 0 32px;}p {font-size: 1em;line-height: 1.25em;}a {color: inherit;}img {height: auto;max-width: 100%;}.wrap {text-align: center;position: relative;display: inline-block;}.legend {font-size: 14px;margin: 0 auto 32px;}.legend h4,.legend p {margin: 0 0 6px;}.legend code {background: #e3e3e3;}.legend code .key {color: #ec433c;}.legend code .click {color: #2a48ec;}.top {border: 6px solid #e3e3e3;background-color: #e3e3e3;}#scoreboard {display: flex;padding-bottom: 12px;justify-content: space-between;}#scoreboard .select-wrap {font-weight: 700;vertical-align: top;display: inline-block;}#scoreboard .select-wrap select {margin: 0;height: 36px;border-radius: 0;border-width: 3px;border-style: solid;background-color: #d1d1d1;border-color: white #9e9e9e #9e9e9e white;}#scoreboard .select-wrap select:hover,#scoreboard .select-wrap select:focus {backgroudn-color: #ebebeb;}#scoreboard .reset {padding: 0 4px;font-size: 24px;cursor: pointer;font-weight: 700;line-height: 30px;border-width: 3px;border-style: solid;background-color: #d1d1d1;border-color: white #9e9e9e #9e9e9e white;}#scoreboard .reset:hover,#scoreboard .reset:focus {outline: none;background-color: #ebebeb;}#scoreboard .counter {padding: 0 4px;color: #ec433c;border: 3px inset;line-height: 30px;letter-spacing: 0.08em;display: inline-block;background: #333;text-shadow: 0 0 2px #ec433c;}#scoreboard .counter:first-of-type {margin-right: 20px;}#scoreboard .counter:last-of-type {margin-left: 20px;}#grid {margin: 0 auto;position: relative;display: inline-block;}#grid ::-moz-selection {background-color: transparent;}#grid ::selection {background-color: transparent;}#grid.disabled .cell {pointer-events: none;}#grid.disabled .status-indicator {top: 50%;left: 50%;z-index: 11;width: 8vw;height: 8vw;font-size: 4vw;cursor: pointer;line-height: 8vw;position: absolute;border-radius: 50%;pointer-events: auto;background-color: #d1d1d1;transform: translate(-50%, -50%);border: 1px solid rgba(51, 51, 51, 0.25);}#grid.disabled .status-indicator::after {content: '';}#grid.disabled.win .status-indicator::after {content: '😎';}#grid.disabled.lose .status-indicator::after {content: '☹️';}#grid .row {display: flex;}#grid .cell {cursor: pointer;width: 24px;height: 24px;position: relative;background-color: #d1d1d1;border-width: 3px;border-style: solid;border-color: white #9e9e9e #9e9e9e white;}#grid .cell i {left: 0;bottom: 0;margin: 0;width: 100%;font-size: 14px;font-weight: 700;font-style: normal;position: absolute;line-height: 24px;}#grid .cell::before {top: 0;left: 0;right: 0;bottom: 0;z-index: 1;content: '';position: absolute;background-color: #d1d1d1;}#grid .cell::after {top: 50%;left: 50%;content: '';position: absolute;transform: translate(-50%, -50%);}#grid .cell:hover::before {background-color: #ebebeb;}#grid .cell.revealed {border: 1px solid #b8b8b8;}#grid .cell.revealed::before {display: none;}#grid .cell.revealed .flag {display: none;}#grid .cell .flag {top: 50%;left: 50%;z-index: 1;width: 10px;height: 4px;position: absolute;border-style: solid;border-width: 4px 0 4px 10px;transform: translate(-50%, -50%);border-color: transparent transparent transparent #ec433c;}#grid .cell.maybe .flag {border-color: transparent transparent transparent #d7af42;}#grid .cell.mine {background-color: #ec433c;}#grid .cell.mine::after {border-radius: 50%;width: 12px;height: 12px;background-color: #333;}#grid .cell.incorrect .flag::before,#grid .cell.incorrect .flag::after {top: 50%;z-index: 1;left: -13px;height: 2px;width: 16px;content: '';position: absolute;background-color: black;}#grid .cell.incorrect .flag::before {transform: rotate(-45deg);}#grid .cell.incorrect .flag::after {transform: rotate(45deg);}#grid .cell.mousedown {border: none;}#leaderboard {margin-top: 20px;text-align: center;}#leaderboard h4 {margin: 0 0 10px;}#leaderboard ul {margin: 0;padding: 10px;display: inline-block;background-color: rgba(209, 209, 209, 0.5);}#leaderboard ul li {padding: 2px;list-style: none;}#leaderboard ul li span {font-weight: 900;text-transform: capitalize;}#leaderboard ul li.highlight {background-color: #fef178;}#leaderboard button {border: none;outline: none;cursor: pointer;font-size: 12px;font-weight: 700;-webkit-appearance: none;-moz-appearance: none;appearance: none;background: none;text-decoration: underline;}.cell.white {color: #fff;}.cell.gray-light {color: #efefef;}.cell.gray-mid {color: #e3e3e3;}.cell.gray {color: #d1d1d1;}.cell.gray-dark {color: #808080;}.cell.black {color: #333;}.cell.red {color: #ec433c;}.cell.maroon {color: #a6070f;}.cell.purple {color: #a42887;}.cell.yellow {color: #d7af42;}.cell.yellow-light {color: #fef178;}.cell.blue {color: #2a48ec;}.cell.blue-dark {color: #233db7;}.cell.green {color: #2bb13d;}.cell.turquoise {color: #28907d;}#devbox {top: 10px;right: 10px;position: fixed;text-align: left;max-width: 300px;color: #fff;background-color: #333;}#devbox p {margin: 0;font-size: 12px;padding: 10px 20px;}#devbox p + p {padding-top: 5px;}</style></head><body><header class="site-header" role="banner"><div class="wrap"><h1>扫雷</h1><div class="legend"><p><strong>插旗:</strong><code><span class="key">alt</span>+<span class="click">click(单击)</span></code></p></div></div></header><main class="site-main" role="main"><div class="wrap"><div id="board"><div class="top"><div id="scoreboard"><div id="minecounter" class="counter"></div><div><div class="select-wrap"><select name="level" id="level"><option value="beginner">初级</option><option value="intermediate">中级</option><option value="expert" selected>高级</option></select></div><button class="reset">🙂</button></div><div id="timer" class="counter"></div></div><div id="grid"></div></div><div class="bottom"></div></div></div></main><script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script>$(document).ready(function () {var $body, $document, $board, $grid, timer, time, unstarted;function _init() {// Cache some common DOM queries$document = $(document);$body = $('body');$body.addClass('loaded');// Start Minesweeper$board = $('#board');$grid = $('#grid');var $timer = $('#timer');var $mineCounter = $('#minecounter');var $levelSelect = $('#level');var levels = {beginner: '9x9x10',intermediate: '16x16x44',expert: '16x30x99',};var level = $levelSelect.val();var levelParams,rows,$rows,columns,cellCount,mines,freeCells,mineTally,pauseTime,beginnerHighScore = 999,intermediateHighScore = 999,expertHighScore = 999;var countColors = {0: '',1: 'blue',2: 'green',3: 'red',4: 'blue-dark',5: 'maroon',6: 'turquoise',7: 'purple',8: 'gray-dark',};time = 0;timer = false;unstarted = true;var statusIndicator = '<div class="status-indicator"></div>';// Check for existing high score// if (localStorage.getItem('beginner')) {//   beginnerHighScore = localStorage.getItem('beginner');//   populateHighScore('beginner', localStorage.getItem('beginner'));// }// if (localStorage.getItem('intermediate')) {//   intermediateHighScore = localStorage.getItem('intermediate');//   populateHighScore('intermediate', localStorage.getItem('intermediate'));// }// if (localStorage.getItem('expert')) {//   expertHighScore = localStorage.getItem('expert');//   populateHighScore('expert', localStorage.getItem('expert'));// }function setLevel(level) {levelParams = levels[level];rows = parseInt(levelParams.split('x')[0]);columns = parseInt(levelParams.split('x')[1]);cellCount = rows * columns;mines = levelParams.split('x')[2];freeCells = cellCount - mines;}function setBoard(level) {// Clear Grid$grid.html(statusIndicator).removeClass('disabled lose win').addClass('unstarted');// Set Up GridsetLevel(level);// Set unstartedunstarted = true;// Build Rowsfor (r = 0; r < rows; r++) {var newCells = '';// Build Cellsfor (c = 0; c < columns; c++) {newCells += '<div class="cell"></div>';}$grid.append('<div class="row">' + newCells + '</div>');}// Set MinecountermineTally = mines;$mineCounter.html(mineTally);// Set TimerresetTimer();}// Set initiallysetBoard(level);// Set on reset$('html').on('mousedown', '.reset', function () {$(this).text('😮');}).on('mouseup', '.reset', function () {$(this).text('🙂');stopTimer();level = $levelSelect.val();setBoard(level);});// Set when clicking status indicator$('html').on('click', '.status-indicator', function () {level = $levelSelect.val();setBoard(level);});// Set on level change$levelSelect.on('change', function () {stopTimer();resetTimer();level = $levelSelect.val();setBoard(level);});// Lay Minesfunction layMines(level, clickedCellIndex) {$rows = $('.row');var freeCells = $('.cell');var takenCells = [clickedCellIndex];// Lay Minesfor (m = 0; m < mines; m++) {var mineCell = Math.floor(Math.random() * Math.floor(freeCells.length));// If it happens to be the clicked cell, skip itif ($.inArray(mineCell, takenCells) > -1) {m--;continue;}takenCells.push(mineCell);$(freeCells[mineCell]).addClass('mine');}// Identify Cell Numbersvar $cells = $('.cell');for (c = 0; c < $cells.length; c++) {var $cell = $($cells[c]);$cell.attr('data-cell', c);// Skip if it's a mineif ($cell.is('.mine')) {continue;}var mineCount = 0;var rowPos = Math.floor(c / columns);var $currentRow = $cell.closest('.row');$currentRow.attr('data-row', rowPos);var rowCells = $currentRow.find('.cell');var cellPos = c % columns;if ($(rowCells[cellPos - 1]).is('.mine')) {mineCount++;}if ($(rowCells[cellPos + 1]).is('.mine')) {mineCount++;}if (rowPos > 0) {var prevRowCells = $($rows[rowPos - 1]).find('.cell');if ($(prevRowCells[cellPos - 1]).is('.mine')) {mineCount++;}if ($(prevRowCells[cellPos]).is('.mine')) {mineCount++;}if ($(prevRowCells[cellPos + 1]).is('.mine')) {mineCount++;}}if (rowPos < rows - 1) {var nextRowCells = $($rows[rowPos + 1]).find('.cell');if ($(nextRowCells[cellPos - 1]).is('.mine')) {mineCount++;}if ($(nextRowCells[cellPos]).is('.mine')) {mineCount++;}if ($(nextRowCells[cellPos + 1]).is('.mine')) {mineCount++;}}if (mineCount > 0) {$cell.html('<i>' + mineCount + '</i>');// Styling classesvar colorClass = countColors[mineCount];$cell.addClass(colorClass);} else {$cell.addClass('zero');}}}// Click cell to start game$('html').off('click', '#grid.unstarted .cell').on('click', '#grid.unstarted .cell', function (e) {$grid.removeClass('unstarted');if (unstarted && !$(e.target).is('.mine')) {layMines(level, $('.cell').index(this));timer = window.setInterval(startTimer, 1000);unstarted = false;}});// Timer Functionsfunction resetTimer() {$timer.html('000');time = 0;}function startTimer() {time++;if (time < 10) {$timer.html('00' + time);} else if (time > 9 && time < 100) {$timer.html('0' + time);} else {$timer.html(time);}}function stopTimer() {window.clearInterval(timer);}function pauseTimer() {stopTimer();pauseTime = parseInt($('#timer').html());}function unpauseTimer() {time = pauseTime;timer = window.setInterval(startTimer, 1000);pauseTime = false;}// Pause when window loses focus$(window).on('blur', function () {pauseTimer();}).on('focus', function () {if (pauseTime) {unpauseTimer();}});// Check Cellfunction checkCell($cell) {if (!$cell.is('.mine') && !$cell.is('.revealed')) {cellClick($cell, 'reveal');if ($cell.is('.zero')) {$cell.trigger('click');}}}// Clicking on a cellfunction cellClick($cell, action) {// If Flaggingif (action === 'flag' && !$cell.is('.revealed')) {if ($cell.is('.flagged')) {$cell.removeClass('flagged');$cell.addClass('maybe');mineTally++;updateMinecounter(mineTally);} else if ($cell.is('.maybe')) {$cell.removeClass('maybe');var flag = $cell.find('.flag');flag.remove();} else {$cell.addClass('flagged');$cell.append('<span class="flag"></span>');mineTally--;updateMinecounter(mineTally);}// If Revealing} else if (action === 'reveal') {$cell.addClass('revealed');// If it's a mine you lose!if ($cell.is('.mine')) {lose();}statusCheck();} else if (action === 'clear') {if (!$cell.is('.revealed') || $cell.is('.zero')) {return;}clearClick($cell);}}// Update Minecounterfunction updateMinecounter(mineTally) {if (mineTally < 10) {$mineCounter.html('0' + mineTally);} else {$mineCounter.html(mineTally);}}// Clicking on a Zero cellfunction zeroClick($cell) {var cellPos = $cell.prevAll().length;var $currentRow = $cell.closest('.row');var rowPos = parseInt($currentRow.attr('data-row'));var rowCells = $currentRow.find('.cell');checkCell($(rowCells[cellPos - 1]));checkCell($(rowCells[cellPos + 1]));if (rowPos > 0) {var prevRowCells = $($rows[rowPos - 1]).find('.cell');checkCell($(prevRowCells[cellPos - 1]));checkCell($(prevRowCells[cellPos]));checkCell($(prevRowCells[cellPos + 1]));}if (rowPos < rows) {var nextRowCells = $($rows[rowPos + 1]).find('.cell');checkCell($(nextRowCells[cellPos - 1]));checkCell($(nextRowCells[cellPos]));checkCell($(nextRowCells[cellPos + 1]));}}// Clicking on a number to clear free cellsfunction clearClick($cell) {var cellPos = $cell.prevAll().length;var $currentRow = $cell.closest('.row');var rowPos = parseInt($currentRow.attr('data-row'));var rowCells = $currentRow.find('.cell');var adjacentCells = [];var correctClear = true;var adjacentMines = 0;var adjacentFlags = 0;var i;adjacentCells.push($(rowCells[cellPos - 1]));adjacentCells.push($(rowCells[cellPos + 1]));if (rowPos > 0) {var prevRowCells = $($rows[rowPos - 1]).find('.cell');adjacentCells.push($(prevRowCells[cellPos - 1]));adjacentCells.push($(prevRowCells[cellPos]));adjacentCells.push($(prevRowCells[cellPos + 1]));}if (rowPos < rows) {var nextRowCells = $($rows[rowPos + 1]).find('.cell');adjacentCells.push($(nextRowCells[cellPos - 1]));adjacentCells.push($(nextRowCells[cellPos]));adjacentCells.push($(nextRowCells[cellPos + 1]));}for (i = 0; i < adjacentCells.length; i++) {// add to mine countif ($(adjacentCells[i]).is('.mine')) {adjacentMines++;}// add to flag coutif ($(adjacentCells[i]).is('.flagged')) {adjacentFlags++;}}if (adjacentFlags === adjacentMines) {for (i = 0; i < adjacentCells.length; i++) {if ($(adjacentCells[i]).is('.mine')) {if ($(adjacentCells[i]).is('.flagged')) {continue;} else {$(adjacentCells[i]).addClass('revealed');correctClear = false;}} else if ($(adjacentCells[i]).is('.flagged')) {correctClear = false;$(adjacentCells[i]).addClass('incorrect');lose();}}if (correctClear) {for (i = 0; i < adjacentCells.length; i++) {if (!$(adjacentCells[i]).is('.mine')) {if ($(adjacentCells[i]).is('.zero')) {zeroClick($(adjacentCells[i]));}cellClick($(adjacentCells[i]), 'reveal');}}}} else {return;}}// Check statusfunction statusCheck() {if ($('.cell.revealed').length == freeCells) {stopTimer();var winTime = $('#timer').html();$grid.addClass('disabled win');resetHighScore(level, winTime);}}function lose() {$grid.addClass('disabled lose');stopTimer();}// Clicking on a cell$('html').on('click', '.cell', function (e) {e.preventDefault();var action = 'reveal';var $cell = $(this);if (e.altKey || e.which === 3) {action = 'flag';} else if ($cell.is('.revealed') ||(e.which === 1) & (e.which === 3)) {action = 'clear';}if ($cell.is('.flagged') && !e.altKey) {return;}if ($cell.is('.zero')) {zeroClick($cell);}cellClick($cell, action);});// Mouse down on a cell$('html').on('mousedown', '.cell:not(.revealed,.flagged)', function (e) {if (!e.altKey && e.which !== 3) {$(this).addClass('mousedown');}}).on('mouseup mouseleave', '.cell.mousedown', function () {$(this).removeClass('mousedown');});// Scoreboard functionalityfunction resetHighScore(level, winTime) {if (localStorage.getItem(level)) {if (winTime < localStorage.getItem(level)) {localStorage.setItem(level, winTime);populateHighScore(level, winTime, true);}} else {localStorage.setItem(level, winTime);populateHighScore(level, winTime, true);}}function populateHighScore(level, highScore, highlight) {if (!$('#leaderboard').length) {$board.find('.bottom').append('<div id="leaderboard"><h4>High Scores</h4><ul><li class="beginner"></li><li class="intermediate"></li><li class="expert"></li></ul><div><button id="score-reset" class="score-reset">Clear Scores</button></div></div>');}if (highlight === true) {$('#leaderboard .highlight:not(.' + level + ')').removeClass('highlight');$('#leaderboard .' + level).addClass('highlight');}var highScoreDisplay = parseInt(highScore, 10);$('#leaderboard .' + level).html('<span>' + level + '</span>: ' + highScoreDisplay + ' seconds');}function clearScores() {localStorage.clear();$('#leaderboard').remove();}// Clicking on score reset to clear scores$('html').on('click', '#score-reset', clearScores);}_init();});</script></body>
</html>

3.电脑单机就可玩耍

最后:

你今天扫雷了吗?后台回复“扫雷”获取在线连接。
扫雷游戏


http://www.ppmy.cn/ops/136805.html

相关文章

Python学习——猜拳小游戏

import random player int(input(“请输入&#xff1a;剪刀 0&#xff0c;石头 1&#xff0c;布2”)) computer random.randint(0,2)# print(“玩家输入的是%d&#xff0c;电脑输入的是%d” %(player,computer)) 用于测试 if (player 0) and (computer 0) or (player 1) a…

自由学习记录(23)

Lua的学习 table.concat(tb,";") 如果表里带表&#xff0c;则不能拼接&#xff0c;表里带nil也不能&#xff0c;都会报错 true和false也不可以&#xff0c;数字和字符串可以 if要和一个end配对&#xff0c;所以 if a>b then return true end end 两个end …

前端工程化18-邂逅Promise(待更新)

6、邂逅Promise 6.1、函数对象与实例对象 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>准备_函数对象与实例对象</title> </head> <body><script>/* 函数对象、实例对象…

Android 性能优化:内存优化(理论篇)

内存作为App程序运行最重要的资源之一&#xff0c;需要运行过程中做到合理的资源分配与回收&#xff0c;不合理的内存占用轻则使得用户应用程序运行卡顿、ANR、黑屏&#xff0c;重则导致用户应用程序发生 OOM&#xff08;out of memory&#xff09;崩溃。喜马直播随着近些年的业…

【手写一个spring】spring源码的简单实现--BeanPostProcessor(实现AOP)以及JDK动态代理/CGLIB动态代理

文章目录 BeanPostProcessor概念BeanPostProcessor接口中的两个方法BeanPostProcessor的实例化与注册BeanPostProcessor的执行时机实现AOP动态代理技术JDK动态代理&#xff1a;CGLIB动态代理&#xff1a; JDK动态代理和CGLIB动态代理的区别JDK动态代理CGLIB动态代理使用场景性能…

一个全面的Vue 3组件通信演示展示

✍️ 记录 一、Vue2 中组件通信方式 props: 实现父子组件、子父组件、甚至兄弟组件通信自定义事件: 可以实现子父组件通信全局事件总线$bus: 可以实现任意组件通信pubsub: 发布订阅模式实现任意组件通信vuex: 集中状态管理容器&#xff0c;实现任意组件通信ref: 父组件获取子…

【C语言】野指针问题详解及防范方法

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 &#x1f4af;前言&#x1f4af;什么是野指针&#xff1f;&#x1f4af;未初始化的指针代码示例问题分析解决方法 &#x1f4af;指针越界访问代码示例问题分析解决方法 &#x1f4af;指向已释放内存的…

简单的爬虫脚本编写

一、数据来源分析 想爬取一个网站的数据&#xff0c;我们首先要进行数据分析。通过浏览器F12开发者工具栏进行抓包&#xff0c;可以分析我们想要的数据来源。 通过关键字搜索&#xff0c;可以找到相对应的数据包 二、爬虫实现 需要用到的模块为&#xff1a;request&#xf…