<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Kevin's Minefield</title> <style>
#minesweeper{ position:relative; background-color:lightgrey; text-align:center; font-size:1em; width:500px; height:500px; user-select:none; font-family:sans-serif; margin-left:auto;margin-right:auto; } .ms_outline_lose{animation: ms_outline_lose 0.25s linear 0s infinite alternate;} @keyframes ms_outline_lose{ from{outline:5px solid darkred;} to{outline:10px solid red;} } .ms_outline_win{animation: ms_outline_win 0.25s linear 0s infinite alternate;} @keyframes ms_outline_win{ from{outline:5px solid green;} to{outline:10px solid lime;} } .ms_helpCursor,.ms_helpCursor div{cursor:help;} #ms_header{ position:absolute; width:75%; height:21%; left:1%; top:1%; overflow:hidden; border:1px solid black; cursor:pointer; } #ms_title{ font-weight:bold; font-style:italic; font-size:2em; color:lightgrey; text-shadow:0 0 2px black; } .ms_winText{ color:green; font-weight:bold; animation: ms_winning 1s linear 0s infinite alternate, ms_winning2 0.5s linear 0s infinite alternate; font-size:1.5em; } @keyframes ms_winning{ from{color:darkgreen;} to{color:lime;} } @keyframes ms_winning2{ from{font-size:1.5em;} to{font-size:1.8em;} } .ms_loseText{ color:rgb(170, 128, 128); font-weight:bold; font-style:italic; animation: ms_losing 1s ease-out 0s infinite alternate; font-size:1.5em; } @keyframes ms_losing{ from{font-size:1.5em;} to{font-size:1.8em;} } #ms_gameBoard{ position:absolute; width:75%; height:75%; top:23%; left:1%; font-weight:bold; } .ms_cell{ position:absolute; width:6.25%; height:6.25%; background-color:lightgrey; border:1px solid black; overflow:hidden; } .ms_num1{color:grey;} .ms_num2{color:darkblue;} .ms_num3{color:darkred;} .ms_num4{color:darkgreen;} .ms_num5{color:darkviolet;} .ms_num6,.ms_num7,.ms_num8{text-shadow:0 0 2px black,0 0 2px black;color:white;} .ms_overlay{ position:absolute; width:6.25%; height:6.25%; background-color:grey; border:1px solid black; overflow:hidden; cursor:pointer; } .ms_overlay_hidden{ display:none; } .ms_error{ background-color:red; animation: ms_errors 0.25s ease-in 0s infinite alternate; } @keyframes ms_errors{ from{background-color:red;} to{background-color:rgb(64,0,0);} } .ms_cell_flagged{ text-shadow:0 0 2px black; color:yellow; } #ms_flagStore{ position:absolute; width:22%; height:75%; top:23%; right:1%; color:yellow; text-shadow:0 0 2px black; } .ms_f{ position:absolute; border:1px solid black; background-color:rgb(32,32,32); cursor:default; overflow:hidden; } #ms_diffButtons{ position:absolute; width:22%; height:21%; top:1%; right:1%; } .ms_diffButton{ position:absolute; border:1px solid black; background-color:lightgrey; cursor:pointer; overflow:hidden; width:95%; height:30%; text-align:left; padding:0 0 0 5%; } .ms_diffButtonSelected{ font-weight:bold; outline: 1px solid black; } .ms_bomb{ color:black; background-color:rgb(139, 117, 117); } .ms_overlay_redZone{ background-color:rgb(139, 117, 117); } #ms_autoplayCursor{ position:absolute; left:50%; top:50%; width:20px; height:20px; background-color:white; border-radius: 0 99px 99px 99px; box-shadow: 5px 5px 10px 0px black; display:none; } #ms_autoplayer{ position:absolute; width:100%; top:100%; text-align:center; background-color:lightgrey; } #ms_autoplayer fieldset{ border-radius:10px; margin: 0 20px 15px 20px; border-color:grey; text-align:left; } #ms_autoplayer div{ display:inline-block; height:1.5em; width:49%; } #ms_auto_moveButton{ width:90%; } #ms_auto_speed{ width:70%; margin-left:5px; }
</style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script>
"use strict"; const ICON_TIMER = "⌚"; const ICON_BOMB = "💣"; const ICON_FLAG = "🚩"; const ICON_TROPHY = "🏆"; let controls=false; let gameTimer; let gameTimerInt=0; let bombCount=30; let bombMax=80; $(document).ready(function(){ Startup(); StartNewGame_step2(0); }); function Startup(){ let hhh = "<div id='ms_header' onmousedown='StartNewGame(event)'>"; hhh += "<span id='ms_title'></span><br>"; hhh += "<span id='ms_subtitle'></span>"; hhh += "</div>"; hhh += "<div id='ms_gameBoard'>"; let style, pos; for(let yyy=0;yyy<16;yyy++){ for(let xxx=0;xxx<16;xxx++){ pos = "left:"+6.25*xxx+"%; top:"+6.25*yyy+"%;"; style = "style='"+pos+"'"; hhh += "<div class='ms_cell' "+style+" id='ms_cell"+xxx+"_"+yyy+"'></div>"; hhh += "<div class='ms_overlay ms_overlay_hidden' "+style+" id='ms_overlay"+xxx+"_"+yyy+"' onmousedown='CellClick(this,event)'></div>"; } } hhh += "<div id='ms_autoplayCursor'></div>";/* autoplay cursor */ hhh += "</div>"; hhh += "<div id='ms_flagStore'>"; let iii=0; let flagCols=5; let flagRows=Math.ceil(bombMax/flagCols); let flagw=100.0/flagCols; let flagh=Math.min(100.0/flagRows,6.25); for(let yyy=0;yyy<flagRows;yyy++){ for(let xxx=0;xxx<flagCols;xxx++){ pos = "style='left:"+flagw*xxx+"%;top:"+flagh*yyy+"%;"; pos += "width:"+flagw+"%;height:"+flagh+"%;'" hhh += "<div id='ms_f"+iii+"' class='ms_f' "+pos+"></div>"; iii++; } } hhh += "</div>"; hhh+="<div id='ms_diffButtons'>"; hhh+="<div id='ms_diffButton1' class='ms_diffButton' style='top:0%;' onmousedown='ClickDiffButton(this,event)'></div>"; hhh+="<div id='ms_diffButton2' class='ms_diffButton' style='top:33%' onmousedown='ClickDiffButton(this,event)'></div>"; hhh+="<div id='ms_diffButton3' class='ms_diffButton' style='top:66%' onmousedown='ClickDiffButton(this,event)'></div>"; hhh+="</div>"; /* hidden input keyboard detection */ hhh +="<input id='ms_hiddenInput' type='text' style='width:0;height:0;opacity:0;'>"; hhh+=GetAutoplayerHtml(); $("#minesweeper").html(hhh); $("#minesweeper").attr("oncontextmenu","return false;");/* so right-click does not open a menu */ $("#ms_title").text("Kevin's Minefield"); $("#ms_subtitle").text("Click here to play"); ShowDiffButtons(); /* hidden input keyboard detection */ $("#minesweeper").attr("onclick","EnterFocusFromClick()"); $("#ms_hiddenInput").attr("onkeydown","KeyDown(event)"); $("#ms_hiddenInput").attr("onkeyup","KeyUp(event)"); $("#ms_hiddenInput").blur(ExitFocus); keyboardTimer=setInterval(function(){ if(GetKey("z")){ $("#minesweeper").addClass("ms_helpCursor"); }else{ $("#minesweeper").removeClass("ms_helpCursor"); } },1000/10); SetupAutoplayerHtml(); } let keys=[];/* keyboard */ let keyboardTimer; function EnterFocusFromClick(){ let active=document.activeElement; if(active === document.getElementById("ms_auto_setting") || active === document.getElementById("ms_auto_speed")){ return; } EnterFocus(); } function EnterFocus(){ $("#ms_hiddenInput").focus(); } function ExitFocus(){ $("#minesweeper").removeClass("ms_helpCursor"); for(let x=0;x<keys.length;x++){/* set all keys to false */ keys[x]=false; } } function KeyDown(event){ event.preventDefault(); SetKey(event.key,true); $(this).val(""); } function KeyUp(event){ event.preventDefault(); SetKey(event.key,false); $(this).val(""); } function GetKeyId(sss){ switch(sss){ case "z":return 0; default:return 8;/* dump */ } } function GetKey(sss){ return keys[GetKeyId(sss)]; } function SetKey(sss,bbb){ keys[GetKeyId(sss)]=bbb; } /* ################################# */ function ClickDiffButton(element,event){ let vvv = parseInt($(element).text().substr(0,2)); if(vvv!=bombCount){ bombCount=vvv; ShowDiffButtons(); } StartNewGame(event); } function ShowDiffButtons(){ let diffs=[ "20 Easy", "30 Normal", "40 Normal", "50 Hard", "60 Hard", "70 Extreme", "80 Extreme" ]; let slot = (bombCount/10)-2; let selectedText = diffs[slot]; if(slot==0)slot++; else if(slot==diffs.length-1)slot--; $("#ms_diffButton1").text(diffs[slot-1]); $("#ms_diffButton2").text(diffs[slot]); $("#ms_diffButton3").text(diffs[slot+1]); $(".ms_diffButtonSelected").each(function(){$(this).removeClass("ms_diffButtonSelected");}); if(diffs[slot-1]==selectedText)$("#ms_diffButton1").addClass("ms_diffButtonSelected"); else if(diffs[slot]==selectedText)$("#ms_diffButton2").addClass("ms_diffButtonSelected"); else if(diffs[slot+1]==selectedText)$("#ms_diffButton3").addClass("ms_diffButtonSelected"); } function StartNewGame(event){ event.preventDefault(); StartNewGame_step2(event.button); usedRobot=false; SetAutoSetting(GetAutoSetting());/* force autoplayer to reset */ } function StartNewGame_step2(clickType){ let iii,xxx,yyy; /* reset board */ controls=true; for(xxx=0;xxx<16;xxx++){ for(yyy=0;yyy<16;yyy++){ GetCell(xxx,yyy).text(""); GetCell(xxx,yyy).attr("class","ms_cell"); GetOverlay(xxx,yyy).text(""); GetOverlay(xxx,yyy).attr("class","ms_overlay"); if(clickType>1){ GetOverlay(xxx,yyy).addClass("ms_overlay_hidden"); } } } for(xxx=0;xxx<bombMax;xxx++){ $("#ms_f"+xxx).text(""); } for(xxx=0;xxx<bombCount;xxx++){ $("#ms_f"+xxx).text(ICON_FLAG); } /* spread mines */ for(iii=0;iii<bombCount;iii++){ xxx=Math.floor(Math.random()*16); yyy=Math.floor(Math.random()*16); if(GetCell(xxx,yyy).text()==ICON_BOMB){ iii--; }else{ GetCell(xxx,yyy).text(ICON_BOMB); GetCell(xxx,yyy).attr("class","ms_cell ms_bomb"); /* increase the value of neighbors */ TryIncrease(xxx-1,yyy-1); TryIncrease(xxx ,yyy-1); TryIncrease(xxx+1,yyy-1); TryIncrease(xxx-1,yyy); /* TryIncrease(xxx ,yyy); */ TryIncrease(xxx+1,yyy); TryIncrease(xxx-1,yyy+1); TryIncrease(xxx ,yyy+1); TryIncrease(xxx+1,yyy+1); } } /* reset timer stuff */ clearInterval(gameTimer); gameTimer=null; gameTimerInt=-1; ShowGameTimer(); $("#minesweeper").removeClass("ms_outline_win"); $("#minesweeper").removeClass("ms_outline_lose"); CalculateHardness(); function TryIncrease(xxx,yyy){ if(xxx<0 || xxx>15)return; if(yyy<0 || yyy>15)return; let value=GetCell(xxx,yyy).text(); if(value==ICON_BOMB)return; if(value=="")value=1; else value=parseInt(value)+1; GetCell(xxx,yyy).text(value); GetCell(xxx,yyy).addClass("ms_num"+value); } } function GetCell(xxx,yyy){ return $("#ms_cell"+xxx+"_"+yyy); } function GetOverlay(xxx,yyy){ return $("#ms_overlay"+xxx+"_"+yyy); } function CellClick(element,event){ event.preventDefault(); if(controls==false)return; CellClick_step2($(element),event.button); } function CellClick_step2(element,clickType){ if(gameTimer==null){ /* ensure first click isnt a bomb */ let sss = $(element).attr("id").substring(10); let cell = $("#ms_cell"+sss); while(cell.text()==ICON_BOMB){ StartNewGame_step2(clickType); } /* start the timer */ gameTimer=setInterval(ShowGameTimer,1000); } if(clickType==0){ if($(element).text()!=ICON_FLAG){ CellLeftClick(element); if(controls==true)LookForWin(); } }else{ if($(element).text()==ICON_FLAG){ RemoveFlag(); }else TryAddFlag(); } function TryAddFlag(){ let iii=$(".ms_cell_flagged").length; if($("#ms_f"+(bombCount-1)).text()=="")return; $(element).text(ICON_FLAG); $(element).addClass("ms_cell_flagged"); $("#ms_f"+iii).text(""); } function RemoveFlag(){ let iii=$(".ms_cell_flagged").length; $(element).text(""); $(element).removeClass("ms_cell_flagged"); $("#ms_f"+(iii-1)).text(ICON_FLAG); } function LookForWin(){ let left=$(".ms_overlay").not(".ms_overlay_hidden").length; if(left>bombCount)return; controls=false; clearInterval(gameTimer); let message=ICON_TROPHY+" YOU WIN" + (usedRobot ? "*" : ""); $("#ms_subtitle").append("<br><span class='ms_winText'>"+message+"</span>"); $(".ms_cell").addClass("ms_cell_win"); $("#minesweeper").addClass("ms_outline_win"); } } function CellLeftClick(element){ if($(element).hasClass("ms_overlay_hidden"))return; $(element).addClass("ms_overlay_hidden"); if($(element).text()==ICON_FLAG)RemoveFlag(); let sss = $(element).attr("id").substring(10); let vvv = $("#ms_cell"+sss).text(); if(vvv==""){ let xxx = parseInt(sss.substring(0,sss.indexOf("_"))); let yyy = parseInt(sss.substring(sss.indexOf("_")+1)); TryOpen(xxx-1,yyy-1); TryOpen(xxx ,yyy-1); TryOpen(xxx+1,yyy-1); TryOpen(xxx-1,yyy); /* TryOpen(xxx ,yyy); */ TryOpen(xxx+1,yyy); TryOpen(xxx-1,yyy+1); TryOpen(xxx ,yyy+1); TryOpen(xxx+1,yyy+1); }else if(vvv==ICON_BOMB){ controls=false; $("#ms_cell"+sss).addClass("ms_error"); LookForErrorFlags(); ShowBombs(); ShowRedZones(); clearInterval(gameTimer); $("#ms_subtitle").append("<br><span class='ms_loseText'>You lose.</span>"); $("#minesweeper").addClass("ms_outline_lose"); CheckAutoRestart(); }; function RemoveFlag(){ let iii=$(".ms_cell_flagged").length; $(element).text(""); $(element).removeClass("ms_cell_flagged"); $("#ms_f"+(iii-1)).text(ICON_FLAG); } function TryOpen(xxx,yyy){ if(xxx<0 || xxx>15)return; if(yyy<0 || yyy>15)return; CellLeftClick(GetOverlay(xxx,yyy)); } function LookForErrorFlags(){ $(".ms_cell_flagged").each(function(){ let sss = $(this).attr("id").substring(10); let vvv = $("#ms_cell"+sss).text(); if(vvv!=ICON_BOMB){ $(this).addClass("ms_error"); } }); } function ShowBombs(){ $(".ms_bomb").each(function(){ let sss = $(this).attr("id").substring(7); let vvv = $("#ms_overlay"+sss).text(); if(vvv==""){ $("#ms_overlay"+sss).addClass("ms_overlay_hidden"); } }); } function ShowRedZones(){ $(".ms_num1").each(function(){ let sss = $(this).attr("id").substring(7); $("#ms_overlay"+sss).addClass("ms_overlay_redZone"); }); } } function ShowGameTimer(){ gameTimerInt++; let min=Math.floor(gameTimerInt/60); let sec=gameTimerInt-(min*60); if(sec<10)sec="0"+sec; $("#ms_subtitle").text(ICON_TIMER+min+":"+sec); } /*##################################################*/ let autoplayAnimating=false; let autoplayTimer; let autoplayRestartTimer; let usedRobot=false;/* did you use the robot during this game? */ function Autoplay(allowGuessing){ if(autoplayAnimating)return; if(controls==false)return; let action = GetAutoplayAction(allowGuessing); if(action==null)return; usedRobot=true; let xxx=action.cell.css("left"); let yyy=action.cell.css("top"); xxx=AddOffset(xxx); yyy=AddOffset(yyy); let cursor = $("#ms_autoplayCursor"); let speed; switch(action.actionType){ case "easy": cursor.css("background-color","white");break; case "advanced": cursor.css("background-color","lawngreen");break; case "guessFast": case "guess": cursor.css("background-color","red");break; } if(GetAutoSetting()=="off"){ speed={move:500,sit:500};/* single move */ }else{ switch(GetAutoSpeed()){ case "slow": speed={move:500,sit:1500};break; case "medium": switch(action.actionType){ case "easy": speed={move:500,sit:200};break; case "advanced": speed={move:500,sit:1000};break; case "guessFast": speed={move:500,sit:200};break; case "guess": speed={move:500,sit:1500};break; }break; case "fast": switch(action.actionType){ case "easy": speed={move:200,sit:100};break; case "advanced": speed={move:200,sit:500};break; case "guessFast": speed={move:200,sit:100};break; case "guess": speed={move:200,sit:1000};break; }break; case "super": speed={move:0,sit:0};break; } } autoplayAnimating=true; cursor.stop(true,false); cursor.show().css("opacity",1); cursor.animate({left:xxx,top:yyy},speed.move,"swing") .animate({left:xxx,top:yyy},speed.sit, function(){ CellClick_step2(action.cell,action.clickType); autoplayAnimating=false; }) .fadeOut(1000); function AddOffset(nnn){ let lastChar=nnn.charAt(nnn.length-1); if(lastChar=="%"){ nnn=parseFloat(nnn)+(6.25/2)+"%"; }else if(lastChar=="x"){ nnn=parseFloat(nnn)+10+"px"; }else alert("lastChar not recognized: "+lastChar+" in "+nnn); return nnn; } } function GetCoordString(element){ let id=element.attr("id"); if(id.indexOf("cell")!=-1){ return id.substring(7); }else{ return id.substring(10); } } function GetAutoplayAction(allowGuessing){ let ccc; let value; let neighbors; let workable; let flagged; let advancedMove=null; let elements=$(".ms_overlay_hidden"); let element; for(let x=0;x<elements.length;x++){ element=elements.eq(x); /* ignore ones that are "done" */ if(element.hasClass("ms_autodone"))continue; /* mark zeroes as "done" */ value=parseInt(GetCellInstead(element).text());if(isNaN(value))value=0; if(value==0){ element.addClass("ms_autodone"); continue; } ccc=GetCoords(element); neighbors=GetNeighbors(ccc.x,ccc.y); workable=neighbors.not(".ms_overlay_hidden").not(".ms_cell_flagged"); flagged=neighbors.filter(".ms_cell_flagged"); if(workable.length==0){ element.addClass("ms_autodone"); continue; } /* CHECK: obvious flags */ /* all workable cells are bombs. */ if(workable.length==value-flagged.length){ return {cell:workable.first(),clickType:1,actionType:"easy"}; } /* CHECK: obvious safes */ /* all workable cells are safe. */ if(value==flagged.length){ return {cell:workable.first(),clickType:0,actionType:"easy"}; } if(advancedMove!=null)continue; /* CHECK: advanced */ if(value-flagged.length==1){ let advancedResult; advancedResult=AdvancedCheckNeighbor(ccc.x,ccc.y-1); if(advancedResult){advancedMove=advancedResult;continue;} advancedResult=AdvancedCheckNeighbor(ccc.x,ccc.y+1); if(advancedResult){advancedMove=advancedResult;continue;} advancedResult=AdvancedCheckNeighbor(ccc.x-1,ccc.y); if(advancedResult){advancedMove=advancedResult;continue;} advancedResult=AdvancedCheckNeighbor(ccc.x+1,ccc.y); if(advancedResult){advancedMove=advancedResult;continue;} } } if(advancedMove!=null)return advancedMove; /* ####################### educated guessing */ if(allowGuessing==false)return null; let currentChance=0; let chances=new Array(256); let id=0; /* calculate chances */ elements=$(".ms_overlay_hidden"); for(let x=0;x<elements.length;x++){ element=elements.eq(x); if(element.hasClass("ms_autodone"))continue; ccc=GetCoords(element); neighbors=GetNeighbors(ccc.x,ccc.y); workable=neighbors.not(".ms_overlay_hidden").not(".ms_cell_flagged"); value=parseInt(GetCellInstead(element).text());if(isNaN(value))value=0; flagged=neighbors.filter(".ms_cell_flagged"); currentChance=1.0-((value-flagged.length)/workable.length); /* for each workable, put the chance in slot only if it's lower */ for(let w=0;w<workable.length;w++){ element=workable.eq(w); ccc=GetCoords(element); id=(ccc.y*16)+ccc.x; if(!chances[id]){ chances[id]=currentChance; }else chances[id]=Math.min(chances[id],currentChance); } } /* find the best option */ let bestValue=0.0; let bestElement; let randomizingCondition=false; let y=0; for(let i=0;i<chances.length;i++){ if(!chances[i])continue; randomizingCondition=Math.random()<0.5 ? true : false; if((randomizingCondition==true && chances[i]>bestValue) || (randomizingCondition==false && chances[i]>=bestValue)){ bestValue=chances[i]; y=Math.floor(i/16); bestElement=GetOverlay(i-(y*16),y); } } let tryRandomZero=false; let bestValueFlaggedZero=0; if($(".ms_cell_flagged").length<3){ if(bestValue < 0.74){ tryRandomZero=true; } }else{ if(bestValue < 0.74){ /* find a zero (value:0.0) with nearby flags */ elements=$(".ms_overlay").not(".ms_overlay_hidden").not(".ms_cell_flagged"); for(let i=0;i<elements.length;i++){ element=elements.eq(i); ccc=GetCoords(element); id=(ccc.y*16)+ccc.x; if(!chances[id]){/* if chance is zero */ neighbors=GetNeighbors(ccc.x,ccc.y); flagged=neighbors.filter(".ms_cell_flagged"); /*if(flagged.length>bestValueFlaggedZero){ bestValueFlaggedZero=flagged.length; bestElement=element; }*/ if(flagged.length>0){/* pick one with nearby flags, at random */ if(bestValueFlaggedZero==0 || Math.random()>=0.5){ bestValueFlaggedZero=flagged.length; bestElement=element; } } } } if(bestValueFlaggedZero==0){/* if there are no flaggedZeroes */ if(bestValue < 0.66){ tryRandomZero=true; } } } } if(tryRandomZero){ let zeroArray=new Array(); elements=$(".ms_overlay").not(".ms_overlay_hidden").not(".ms_cell_flagged"); for(let i=0;i<elements.length;i++){ element=elements.eq(i); ccc=GetCoords(element); id=(ccc.y*16)+ccc.x; if(!chances[id]){ zeroArray[zeroArray.length]=element; } } if(zeroArray.length>0){ bestElement=zeroArray[Math.floor(Math.random()*zeroArray.length)]; } } if($(".ms_cell_flagged").length==0){ return {cell:bestElement,clickType:0,actionType:"guessFast"}; }else{ return {cell:bestElement,clickType:0,actionType:"guess"}; } function GetCellInstead(element){ let sss=GetCoordString(element); return $("#ms_cell"+sss); } function GetOverlayInstead(element){ let sss=GetCoordString(element); return $("#ms_overlay"+sss); } function GetCoords(element){ let sss=GetCoordString(element); let xxx=parseInt(sss.substring(0,sss.indexOf("_"))); let yyy=parseInt(sss.substring(sss.indexOf("_")+1)); return {x:xxx,y:yyy}; } function GetNeighbors(xxx,yyy){ let nArray=[]; let element; element=GetOverlay(xxx-1,yyy-1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx ,yyy-1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx+1,yyy-1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx-1,yyy );if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx+1,yyy );if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx-1,yyy+1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx ,yyy+1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); element=GetOverlay(xxx+1,yyy+1);if(element.length!=0)nArray[nArray.length]="#"+element.attr("id"); return $(nArray.join(",")); } function AdvancedCheckNeighbor(xxx,yyy){ let child=GetOverlay(xxx,yyy); if(child.length==0)return null;/* could be out of bounds */ if(child.hasClass("ms_overlay_hidden")==false)return null; let childNeigh=GetNeighbors(xxx,yyy); let childWorkable=childNeigh.not(".ms_overlay_hidden").not(".ms_cell_flagged"); let childWorkableStrict=childWorkable.not(neighbors); let childValue=parseInt(GetCellInstead(child).text());if(isNaN(childValue))childValue=0; let childFlags=childNeigh.filter(".ms_cell_flagged"); let workableStrict=workable.not(childNeigh); if(childWorkableStrict.length>0 && childWorkableStrict.length == childValue-childFlags.length-1){ return {cell:childWorkableStrict.first(),clickType:1,actionType:"advanced"}; } if(childWorkableStrict.length==0 && childValue-childFlags.length-1 == 0 && workableStrict.length!=0){ return {cell:workableStrict.first(),clickType:0,actionType:"advanced"}; } return null; } } function GetAutoplayerHtml(){ let html=""+ "<div id='ms_autoplayer'>"+ "<fieldset><legend>Robo-Player</legend>"+ "<div><button id='ms_auto_moveButton'>Make a move</button></div>"+ "<div><span>Automatic:</span><input type='checkbox' id='ms_auto_setting' checked='false'/></div>"+ "<div><span>Allow guessing:</span><input type='checkbox' id='ms_auto_guessing' checked='true'/></div>"+ "<div><span>Speed:</span><select id='ms_auto_speed'>"+ "<option value='slow'>slow</option>"+ "<option value='medium'>medium</option>"+ "<option value='fast'>fast</option>"+ "<option value='super'>super</option>"+ "</select></div>"+ "</fieldset>"+ "</div>"; return html; } function SetupAutoplayerHtml(){ $("#ms_auto_moveButton").click(function(){ if(autoplayAnimating==false){ if(document.getElementById("ms_auto_guessing").checked){ if(controls==false)StartNewGame_step2(0); Autoplay(true); }else{ Autoplay(false); } } }); $("#ms_auto_setting").change(function(){ let vvv=GetAutoSetting(); autoplayAnimating=false; $("#ms_autoplayCursor").stop(true,false).hide().css("opacity",0); clearInterval(autoplayTimer); clearTimeout(autoplayRestartTimer); autoplayTimer=null; if(vvv=="moving"){ autoplayTimer=setInterval(function(){ Autoplay(false); },100); }else if(vvv=="guessing"){ autoplayTimer=setInterval(function(){ Autoplay(true); },100); } }); $("#ms_auto_guessing").change(function(){ $("#ms_auto_setting").change(); }); SetAutoSetting("off"); SetAutoSpeed("medium"); } function GetAutoSetting(){ if(document.getElementById("ms_auto_setting").checked){ if(document.getElementById("ms_auto_guessing").checked){ return "guessing"; }else{ return "moving"; } }else{ return "off"; } } function SetAutoSetting(sss){ document.getElementById("ms_auto_setting").checked = (sss=="off") ? null : true; if(sss!="off"){ document.getElementById("ms_auto_guessing").checked = (sss=="guessing") ? true : null; } $("#ms_auto_setting").change(); } function GetAutoSpeed(){ return document.getElementById("ms_auto_speed").value; } function SetAutoSpeed(sss){ document.getElementById("ms_auto_speed").value=sss; } function CheckAutoRestart(){ if(GetAutoSetting()=="guessing"){ autoplayRestartTimer=setTimeout(function(){ StartNewGame_step2(0); },GetAutoSpeed()=="super" ? 500 : 2000); } } function CalculateHardness(){ let x,y; let hardness=0; let eachCardinal=1; let eachDiagonal=0; for(let y=0;y<16;y++){ for(let x=0;x<16;x++){ if(IsBomb(x,y)==false)continue; if(IsBomb(x-1,y-1))hardness+=eachDiagonal; if(IsBomb(x+0,y-1))hardness+=eachCardinal; if(IsBomb(x+1,y-1))hardness+=eachDiagonal; if(IsBomb(x-1,y+0))hardness+=eachCardinal; if(IsBomb(x+1,y+0))hardness+=eachCardinal; if(IsBomb(x-1,y+1))hardness+=eachDiagonal; if(IsBomb(x+0,y+1))hardness+=eachCardinal; if(IsBomb(x+1,y+1))hardness+=eachDiagonal; } } hardness*=0.5; $("#hardness").text("Cardinality: "+hardness); function IsBomb(x,y){ let ccc=GetCell(x,y); if(!ccc)return false; let vvv=ccc.text(); return vvv==ICON_BOMB; } }
</script> <style>
body{ background-color:rgb(78, 56, 87); }
</style> </head> <body> <div id="minesweeper"></div> <div id="hardness" style="color:white;margin-top:100px;text-align:center"></div> </body> </html>
0000