日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js实现扫雷-算法分析

發(fā)布時(shí)間:2024/1/8 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js实现扫雷-算法分析 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

掃雷實(shí)現(xiàn)及其算法分析

本文主要是通過使用Javascript,通過對掃雷游戲中用到的算法分析,一步步實(shí)現(xiàn)用到的算法,進(jìn)而實(shí)現(xiàn)掃雷過程,本文沒有對實(shí)際游戲進(jìn)行完善,主要是針對于算法分析,幫助小伙伴應(yīng)對免試或者求職時(shí)遇到的算法;

1. 隨機(jī)生成雷區(qū)

這里我們使用經(jīng)典的洗牌算法來實(shí)現(xiàn)雷區(qū)的隨機(jī)化,盡量保證每個(gè)格子生成雷的概率相等;每次從當(dāng)前坐標(biāo)點(diǎn)之后的二維數(shù)組中隨機(jī)選擇一個(gè)坐標(biāo),并將生成的隨機(jī)坐標(biāo)(randx,randy)與當(dāng)前選擇的坐標(biāo)互換,實(shí)現(xiàn)一次隨機(jī)選擇;

function shuffle(arr){for(var i=0;i<n*m;i++){// 從[i,n)區(qū)間隨機(jī)選擇元素var number=Math.floor(Math.random()*(n*m-i))+i;var x=parseInt(i/m); var y=parseInt(i%m)var randx=parseInt(number/m);var randy=parseInt(number%m);swap(arr,x,y,randx,randy); }}

2.計(jì)算每個(gè)格子周圍的雷的數(shù)量

以當(dāng)前坐標(biāo)點(diǎn)為中心,對周圍八個(gè)點(diǎn)進(jìn)行遍歷,每個(gè)雷的位置table[x][y]值為1,isArea()函數(shù)用于判斷當(dāng)前遍歷的坐標(biāo)點(diǎn)是否在二維數(shù)組范圍內(nèi),函數(shù)實(shí)現(xiàn)會(huì)在下面給出,將每個(gè)點(diǎn)周圍的雷的數(shù)量存儲(chǔ)在一個(gè)新的二維數(shù)組numbers中;

// 計(jì)算每個(gè)格子周圍的雷的數(shù)量function cauletenum(){for(var i=0;i<n;i++)for(var j=0;j<m;j++){// 如果檢測到雷,將這個(gè)點(diǎn)的數(shù)值記為-1;表示游戲結(jié)束if(table[i][j]==1)numbers[i][j]=-1;else{//遍歷八個(gè)點(diǎn),并將雷的數(shù)量累加計(jì)算出來for(var ii=i-1;ii<=i+1;ii++)for(var jj=j-1;jj<=j+1;jj++){if(isArea(ii,jj)&&table[ii][jj]==1)numbers[i][j]++;}}}}

3.點(diǎn)擊空白打開一片雷區(qū)的算法(floodfill)

對當(dāng)前是空白的坐標(biāo)點(diǎn),對其周圍上下左右四個(gè)方向進(jìn)行深度優(yōu)先遍歷,碰到數(shù)字或者雷時(shí)停止向下的遍歷;

// 當(dāng)點(diǎn)擊的位置是空的,則進(jìn)行深度優(yōu)先遍歷,進(jìn)而打開一片區(qū)域,//碰到數(shù)字停止;function open(x,y){if(!isArea(x,y)){//如果當(dāng)前位置不在數(shù)組范圍,則返回return;}if(table[i][j]==1){//點(diǎn)到雷,游戲結(jié)束return;}open[x][y]=true;// 如果點(diǎn)到的是帶有數(shù)字的格,表示周圍有雷,直接返回if(numbers[x][y]>0)return;for(var i=x-1;i<=x+1;i++)for(var j=y-1;j<=y+1;j++)// 在有效區(qū)域,并且沒有打開過,并且不是雷,則打開該區(qū)域if(isArea(i,j)&&!open[i][j]&&table[i][j]!=1)open(i,j);//進(jìn)行深度優(yōu)先遍歷}

以下為案例源碼:
每個(gè)函數(shù)都有詳細(xì)注釋,不明白的地方歡迎留言,有更好的意見也歡迎指導(dǎo);
GitHub-starfishing
Blog-ForYou

var n=10,m=10,war=20;//n行 m列 war雷//生成二維數(shù)組,初始沒有雷,所有都為0var table=new Array();//游戲區(qū)域var numbers=new Array();//每個(gè)格子周圍雷的數(shù)量var open=new Array();//是否被打開過// 數(shù)組的初始化for(var i=0;i<n;i++){numbers[i]=new Array(m);table[i]=new Array(m);open[i]=new Array(m);for(var j=0;j<m;j++){numbers[i][j]=0;table[i][j]=0;open[i][j]=false;}}// 雷區(qū)初始化完成渲染到窗口function render(){for(var i=0;i<n;i++){for(var j=0;j<m;j++){document.write(table[i][j]+" ")}document.write("<br>")}}//初始化雷區(qū)function init(arr){reset(arr);shuffle(arr);// render();} // 將雷順序排在二唯數(shù)組中function reset(arr){for(var i=0;i<war;i++){var x=parseInt(i/m); var y=parseInt(i%m)arr[x][y]=1;}}// 隨機(jī)排列function shuffle(arr){for(var i=0;i<n*m;i++){// 從[i,n)區(qū)間隨機(jī)選擇元素var number=Math.floor(Math.random()*(n*m-i))+i;var x=parseInt(i/m); var y=parseInt(i%m)var randx=parseInt(number/m);var randy=parseInt(number%m);swap(arr,x,y,randx,randy); }}// 將隨機(jī)產(chǎn)生的位置與順序位置交換function swap(arr,x,y,randx,randy){var t=arr[x][y];arr[x][y]=arr[randx][randy];arr[randx][randy]=t;}// 判斷坐標(biāo)是否在數(shù)組中function isArea(x,y){if(x>=0&&x<n&&y>=0&&y<m)return true;elsereturn false;}// 計(jì)算每個(gè)格子周圍的雷的數(shù)量function cauletenum(){for(var i=0;i<n;i++)for(var j=0;j<m;j++){// 如果檢測到雷,將這個(gè)點(diǎn)的數(shù)值記為-1;表示游戲結(jié)束if(table[i][j]==1)numbers[i][j]=-1;else{//遍歷八個(gè)點(diǎn),并將雷的數(shù)量累加計(jì)算出來for(var ii=i-1;ii<=i+1;ii++)for(var jj=j-1;jj<=j+1;jj++){if(isArea(ii,jj)&&table[ii][jj]==1)numbers[i][j]++;}}}}// 當(dāng)點(diǎn)擊的位置是空的,則進(jìn)行深度優(yōu)先遍歷,進(jìn)而打開一片區(qū)域,碰到數(shù)字停止;function open(x,y){if(!isArea(x,y)){//如果當(dāng)前位置不在數(shù)組范圍,則返回return;}if(table[i][j]==1){//點(diǎn)到雷,游戲結(jié)束return;}open[x][y]=true;// 如果點(diǎn)到的是帶有數(shù)字的格,表示周圍有雷,直接返回if(numbers[x][y]>0)return;for(var i=x-1;i<=x+1;i++)for(var j=y-1;j<=y+1;j++)// 在有效區(qū)域,并且沒有打開過,并且不是雷,則打開該區(qū)域if(isArea(i,j)&&!open[i][j]&&table[i][j]!=1)open(i,j);//進(jìn)行深度優(yōu)先遍歷}// document.write("<br>")// 將生成的雷區(qū)用表格的形式渲染出來function rendertable(){var tmp="<table>"// console.log(numbersfor(var i=0;i<n;i++){tmp+="<tr>";for(var j=0;j<m;j++){if(numbers[i][j]==-1)tmp+="<td>"+"?"+"</td>"elsetmp+="<td>"+numbers[i][j]+"</td>"// document.write(numbers[i][j]+" ")}tmp+="</tr>";document.write("<br>")}tmp+="</table>";document.write(tmp);}init(table);cauletenum();rendertable();

總結(jié)

以上是生活随笔為你收集整理的js实现扫雷-算法分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。