手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)
js實現掃雷demo💣
先睹為快:😉
思路:🌀
如果div在地圖中間,周圍有八個相鄰的div,如果div在四個邊界那么分別周圍只有5個相鄰的div,如果div是在地圖四個角落,周圍分別只有3個相鄰的div
例:
在地圖中間
在地圖邊界
在地圖四個角落
根據隨機一個div在這100個div中是第幾個來找出它周圍相鄰的div
例:
中間的div是在這100個div 中的第25個,設它的下標為25,那么它正上發的div就是15,它正右邊的就是26,它右下角的div就是36,依次類推🍄
定義一個數組將它周圍的div的下標存起來,也就是第幾個div,遍歷這個數組,判斷它周圍有幾個div 📏
遍歷這個數組的時候需要分情況,也就是div在地圖邊界和在地圖四個角落
如果div在地圖的上邊界那個遍歷的時候 它的周圍不能有 -11 -10 -9的div。如果div在地圖的左邊界的時候,它的周圍不能有-1,9,-11的div。依次類推…
判斷周圍div下標是不是真正的地雷,遍歷得出他們周圍有幾個雷的個數,放入在div中
將地雷隱藏起來,給每個div綁定點擊事件,左擊排雷,右擊標雷。如果this是雷,地雷全部爆炸(地雷全部標紅,顯示地雷),并將所有雷的數字顯示出來。
左鍵排雷,沒有踩雷的話,就把this周圍的雷的數量顯示出來(顯示綠色)
細節處理: 🚴
- 如果踩雷,將他的內容設為空,而不是undefined。
- 如果踩雷,給所有不是雷的div設置內容顯示(綠色,雷的數量),將雷的div設為紅色
- 判斷自己周圍的div是否是0,把周圍div打開,用遞歸將剛剛打開的div繼續判斷自己是否是0
更多詳細注釋 in 源碼 ?
源碼:?
<!DOCTYPE html> <html><head><meta charset="UTF-8"><title>document</title> </head> <style>.container {width: 500px;height: 500px;margin: 50px auto;border: 3px solid #999;position: relative;} </style><body><div class="container"></div> </body> <script src="./js/tool.js"></script> <script>var container = document.querySelector('.container')// 動態創建100個小div放在container里面var mineWidth = 50;var mineHeight = 50;// 求小div的數量var mineNum = container.clientWidth * container.clientHeight / (mineWidth * mineHeight)// 求一行幾個var mineColNum = container.clientWidth / mineWidth;// 循環創建for (var i = 0; i < mineNum; i++) {var div = document.createElement('div')Tool.setStyle(div, {width: mineWidth - 2 + "px",height: mineHeight - 2 + "px",backgroundColor: "#ccc",border: "1px solid #fff",position: "absolute",left: (i % mineColNum) * mineWidth + "px",top: parseInt(i / mineColNum) * mineHeight + "px",textAlign: "center",lineHeight: "50px"})container.appendChild(div)div.mine = false // 表示所有div初始都不是雷this.show = false; // 表示所有div里面的數字都沒有展開}// 標記雷// 定義一個用來存放雷div的下標的數組var arr = [];for (var i = 0; i < 10; i++) {// 獲取隨機下標var index = Math.floor(Math.random() * 100)// 判斷數組中是否已經有了這個下標if (arr.indexOf(index) < 0) {arr.push(index)} else {i--}}// 遍歷所有雷div的下標數組,給是雷的div標記for (var i = 0; i < arr.length; i++) {container.children[arr[i]].mine = true// container.children[arr[i]].style.backgroundColor = 'red';}// 定義一個數組,將周圍div的下標存起來var brr = [-11, -10, -9, -1, 1, 9, 10, 11];// 遍歷每個div周圍的div// 遍歷這個100個divfor (var i = 0; i < container.children.length; i++) {// 如果當前這個div是雷就統計了if (container.children[i].mine) {continue;}// container.children[i] // 每個div// 查看當前div周圍的所有div// 定義周圍雷數量的變量var num = 0for (var j = 0; j < brr.length; j++) {// 考慮最上面一行 - 不能-11 不能-10 不能-9if (i < mineColNum && (brr[j] === -11 || brr[j] === -10 || brr[j] === -9)) {continue;}// // 最左邊一行過濾掉if (i % mineColNum === 0 && (brr[j] === -11 || brr[j] === -1 || brr[j] === 9)) {continue;}// 最下面一行if (parseInt(i / mineColNum) === mineColNum - 1 && (brr[j] === 9 || brr[j] === 10 || brr[j] === 11)) {continue;}// 最右邊一行if (i % mineColNum === mineColNum - 1 && (brr[j] === -9 || brr[j] === 1 || brr[j] === 11)) {continue;}if (container.children[i + brr[j]].mine) {num++}}// 將雷的數量放在div中container.children[i].num = num}// 點擊for (var i = 0; i < container.children.length; i++) {container.children[i].index = icontainer.children[i].onclick = function () {if (this.mine) {// 如果點擊到雷了for (var j = 0; j < container.children.length; j++) {// 給所有不是雷的div設置內容顯示,雷的數量container.children[j].innerText = container.children[j].num ? container.children[j].num : '';container.children[j].style.backgroundColor = '#0f0';}// 將所有是雷的div設置為紅色for (var j = 0; j < arr.length; j++) {container.children[arr[j]].style.backgroundColor = 'red';}} else {// 如果不是雷// this.innerText = this.num;// this.style.backgroundColor = '#0f0';// this.show = true // 表示當前這個div已經展開了openAround(this.index)}}container.children[i].oncontextmenu = function () {this.style.backgroundColor = 'blue';return false;}}// 打開周圍div的遞歸函數function openAround(index) {container.children[index].innerText = container.children[index].numcontainer.children[index].style.backgroundColor = '#0f0'container.children[index].show = trueif (container.children[index].num === 0) {container.children[index].style.backgroundColor = 'pink';for (let j = 0; j < brr.length; j++) {if (index < mineColNum && (brr[j] === -11 || brr[j] === -10 || brr[j] === -9)) {continue;}// // 最左邊一行過濾掉if (index % mineColNum === 0 && (brr[j] === -11 || brr[j] === -1 || brr[j] === 9)) {continue;}// 最下面一行if (parseInt(index / mineColNum) === mineColNum - 1 && (brr[j] === 9 || brr[j] === 10 || brr[j] === 11)) {continue;}// 最右邊一行if (index % mineColNum === mineColNum - 1 && (brr[j] === -9 || brr[j] === 1 || brr[j] === 11)) {continue;}if (container.children[index + brr[j]].show) {continue}openAround(index + brr[j])}}} </script></html>引入的工具庫 tool.js 源碼:
const Tool = (function () {class Tool {constructor() {if (window.getComputedStyle) {this.flag = true;} else {this.flag = false;}}// 獲取節點屬性getStyle (ele, attr) {if (this.flag) {return window.getComputedStyle(ele)[attr];} else {return ele.currentStyle[attr];}}getStyle (ele, attr) {// 嘗試一段代碼 不知道會不會報錯// 嘗試成功 后面代碼沒有什么事// 嘗試失敗 會報錯 被cathch 捕獲到 會將錯誤信息放到err參數里 catch{} 里可以處理這個錯誤 也可以不處理這個錯誤對上面的錯誤代碼進行補救 錯誤不會再瀏覽器里報錯try {return window.getComputedStyle(ele)[attr];} catch (err) {return ele.currentStyle[attr];}}// 設置節點css屬性setStyle (ele, styleObj) {for (let attr in styleObj) {ele.style[attr] = styleObj[attr];}}// 設置cookiesetCookie (key, value, second, path = '/') {let data = new Date();date.setTime(date.getTime() - 8 * 3600 * 1000 + second * 1000);document.cookie = `${key}=${value};expires=${date};path=${path}`;}}var tool;return (function () {if (!tool) {tool = new Tool();}return tool;})(); })(); // var f = tool(); // var t = f();// var t = Tool(); // console.log(t); // try { // console.log(as);// } catch (err) { // console.log(err);// } // console.log(123);覺得博主總結的不錯的,可以收藏支持一波~ ??? 🐵
總結
以上是生活随笔為你收集整理的手把手教弟弟写了个扫雷demo,弟弟竟拿去跟大学同学装* 附(思路注释+源码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 夸男生帅:
- 下一篇: lin通讯从节点同步间隔场_LIN模块介