随机生成数据,每个单元格只需要存是不是雷就行。
第一次点的时候保证不能死,如果踩雷就随机找个安全的格子互换。
状态:0-8代表翻开的,数字表示周围的雷数,9代表初始,10是问号,11是插旗;后面是结束才用得上的:12是揭晓雷,13是误插旗。
左键翻开,右键插旗或标问号,插好旗后左右键一起点数字,翻开周围每一个。
没有框架,就一个文件,打开就能玩。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css"> <style> #top{ height: 100px; font-size: 48px; display: grid; text-align: center; margin: 0 auto; } #top .fa-smile-o{ color: goldenrod; } #top .fa-frown-o{ color: red; } #result{ margin-top: 8px; } #bottom{ display: grid; margin: 0 auto; font-size: 18px; } .cell{ background-color: lightgrey; display: table-cell; border-width: 0.5px; border-style: solid; border-color: gray; vertical-align: middle; user-select: none; } .cell .fa{ margin-top: 5px;; } .state1{ color: blue; } .state2{ color: green; } .state3{ color: red; } .state4{ color: darkblue; } .state5{ color: darkred; } .state6{ color: darkturquoise; } .state7{ color: black; } .state8{ color: gray; } .state9{ background-color: darkgray; border-style: outset; border-width: 5px; border-top-color: white; border-left-color: white; } .state10{ color: black; } .state11,.state13{ color: red; } </style> </head> <body> <div style="text-align: center;"> <div id="top"> <span id="count">0</span> <i id="result" class="fa fa-smile-o"></i> <span id="time">0</span> </div> <div id="bottom"></div> </div> </body> <script> var state_to_text=['','1','2','3','4','5','6','7','8','','?']; var playing=false; var mimeCount=99; var width=30; var height=16; var cellSize=30; var realData=Array.from(new Array(width*height)); var state=realData.slice(); $('#bottom').css('width',width*cellSize+'px'); $('#top').css('width',width*cellSize+'px'); $('#top').css('grid-template-columns','repeat(3,'+cellSize*width/3+'px'); $('#bottom').css('grid-template-columns','repeat('+width+','+cellSize+'px'); $('#bottom').css('grid-template-rows','repeat('+height+','+cellSize+'px'); realData.forEach((v,i)=>$('#bottom').append('<div data-id="'+i+'" class="cell"></div>')); 'CLICK EMOJI TO START'.split('').forEach((s,i)=>$('.cell[data-id='+(parseInt(height/2)*width+i)+']').html(s)); function set_emoji(s){ $('#result').removeClass().addClass('fa fa-'+s); } function set_state(i,v){ state[i]=v; let dom=$('.cell[data-id='+i+']'); dom.removeClass().addClass('cell state'+v); if(v<state_to_text.length) dom.html('<span>'+state_to_text[v]+'</span>'); else{ if(v==11)//flag dom.html('<i class="fa fa-flag"/>'); if(v==12)//mime dom.html('<i class="fa fa-bomb"/>'); if(v==13)//flag but it isn't mime dom.html('<i class="fa fa-times"/>'); } } setInterval(() => { if(playing==false) return; $('#time').html(parseInt($('#time').html())+1); }, 1000); $('#result').click(()=>{ let mime_pos=new Set(); while(mime_pos.size<mimeCount) mime_pos.add(parseInt(Math.random()*realData.length)); for(let i=0;i<realData.length;i++) realData[i]=mime_pos.has(i); state.forEach((v,i)=>set_state(i,9)); playing=true; $('#time').html('0'); $('#count').html(mimeCount); set_emoji('meh-o'); }); var leftDown=false; var rightDown=false; var doubleMouse=false; function getAll(center){ function hasTop(){return center>=width;} function hasBottom(){return center<(height-1)*width;} function hasLeft(){return center%width!=0;} function hasRight(){return center%width!=width-1;} let result=[]; if(hasLeft()){ result.push(center-1); if(hasTop()) result.push(center-1-width); if(hasBottom()) result.push(center-1+width); } if(hasRight()){ result.push(center+1); if(hasTop()) result.push(center+1-width); if(hasBottom()) result.push(center+1+width); } if(hasTop()) result.push(center-width); if(hasBottom()) result.push(center+width); return result; } function doubleMouseUp(i){ doubleMouse=false; if(state[i]<1||state[i]>8) return; let all=getAll(i); if(state[i]!=all.filter(u=>state[u]==11).length) return; all.forEach(open); } function open(i){ if(state[i]!=9&&state[i]!=10) return; if(realData[i]){ if(state.every(u=>u>8)){//open first time let random=parseInt(Math.random()*(state.length-mimeCount)); realData.map((u,i)=>!u?i:undefined).filter(u=>u!=undefined)[random]=true; realData[i]=false; open(i); return; } playing=false; set_emoji('frown-o'); realData.forEach((u,index)=>{ if(u&&state[index]!=11) set_state(index,12); else if(!u&&state[index]==11) set_state(index,13); }); } else{ let all=getAll(i); let mime_count=all.filter(u=>realData[u]).length; set_state(i,mime_count); if(mime_count==0) all.forEach(u=>open(u)); if(state.filter(u=>u<9).length==width*height-mimeCount){ playing=false; set_emoji('smile-o'); } } } $('.cell').mousedown(e=>{ if(e.which==1){ leftDown=true; if(rightDown) doubleMouse=true; } else if(e.which==3){ rightDown=true; if(leftDown) doubleMouse=true; } }); $('.cell').mouseup(e=>{ let id=parseInt($(e.currentTarget).data('id')); if(id==undefined||!playing) return; if(e.which==1){ leftDown=false; if(rightDown==false){ if(doubleMouse) doubleMouseUp(id); else open(id); } } else if(e.which==3){ rightDown=false; if(leftDown==false){ if(doubleMouse) doubleMouseUp(id); else if(state[id]>=9&&state[id]<=11){ set_state(id,(state[id]-1)%3+9); $('#count').html(mimeCount-state.filter(u=>u==11).length); } } } }); document.getElementById('bottom').oncontextmenu=e=>e.preventDefault(); </script> </html>