var w,h,my={};function battleshipMain(){var version='0.52';w=360;h=500;my.shipSets=[[2,3,4,5],[2,3,3,4,5],[2,3,4,5,6],[6]];my.shipSetN=2 my.bdSzs=[8,10,12];my.playerTypes=[{name:'Human',aiQ:false},{name:'Computer (Beginner)',aiQ:true,levelMax:1,timeMax:3000},{name:'Computer (Medium)',aiQ:true,levelMax:3,timeMax:3000},{name:'Computer (Challenging)',aiQ:true,levelMax:4,timeMax:10000},{name:'Computer (Hard)',aiQ:true,levelMax:6,timeMax:10000}];my.clrs0=[["Light Blue Grey",'#D8D8e8'],["Silver",'#d0d0d0'],["Grey 1",'#a898a8'],["Grey 2",'#b8a8a8']];my.clrs1=[["Blue 1",'#bDD8E6'],["Sky Blue",'#97CEEB'],["Aqua",'#aaffff'],["Antique White",'#FAEBD7'],["Blue 2",'#7A9ACD']];my.players=[new Player('Human','blue','rgba(0,0,255,0.3)','board0',my.clrs0),new Player('Computer','red','rgba(255,0,0,0.4)','board1',my.clrs1)] my.playerN=0 my.playerStartN=0 my.borderTp=123 var s='';my.sndHome=(document.domain=='localhost')?'/mathsisfun/images/sounds/':'/images/sounds/' s+='';s+='';s+='';s+='';s+='';my.snds=[];s+='' s+='
';s+='
' s+='
' s+='' s+='' my.soundQ=true s+=' ' s+=soundBtnHTML() s+='
' s+='' s+='' s+='
' s+='
Player X
' s+='
' s+='
';s+='
';s+=optPopHTML();s+='
© 2020 MathsIsFun.com v'+version+'
';s+='
';document.write(s);document.getElementById('scores').innerHTML='Human:0 Computer:0' gameNew()} function gameNew(){my.placedQ=false my.activeQ=false my.nextQ=false my.bdSz=Math.floor(document.querySelector('input[name="bdSz"]:checked').value) console.log('bdSz',my.bdSz) var id=document.querySelector('input[name="shipSet"]:checked').id my.shipSetN=(id.match(/\d+$/)||[]).pop();console.log('my.shipSetN',my.shipSetN) my.boxWd=Math.min(70,(Math.min(w,h-90))/my.bdSz) for(var i=0;i0)s+='Ship Outside! ' if(collideN>0)s+='Ship Collision!' msg(s) if(s.length>0){btnVis('readyBtn',false)}else{btnVis('readyBtn',true)} console.log('placeCheck',s)} function bdMake(clr,bdName,clrs){my.borderLt=(w-my.bdSz*my.boxWd)/2 var pts=getRandomPts(my.bdSz,my.bdSz,3,clrs);var bd=[] for(var xn=0;xn=my.bdSz)return-1 if(yn>=my.bdSz)return-1 return bd[xn][yn]} function bdFmt(bd){var s='' for(var yn=0;yn';s+='';} s+='';return s;} function randomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min;} function optPopHTML(){var s='';s+='
';s+='
';for(var i=0;i';s+='
'+p.name+' player:
';s+='Type: ';s+=dropdownHTML(my.playerTypes,'','playerType'+i,i);s+='
';} s+='
';s+='
';s+=radioHTML('Board Size','bdSz',my.bdSzs,'',0);s+='
' s+='
';s+=radioHTML('Ships','shipSet',my.shipSets,'',0);s+='
' s+='
';s+='(starts new game)' s+='';s+=' ' s+='';s+='
';s+='';return s;} function optPop(){var pop=document.getElementById('optpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=12;pop.style.left=(w-400)/2+'px';} function optYes(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';gameNew()} function optNo(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';} function dropdownHTML(opts,funcName,id,chkN){var s='';s+='';return s;} function soundBtnHTML(){var s='' s+='' s+='
' return s} function soundToggle(){var btn='sound' if(my.soundQ){my.soundQ=false document.getElementById(btn).classList.add("mute")}else{my.soundQ=true document.getElementById(btn).classList.remove("mute")}} function soundPlay(name,simulQ){if(!my.soundQ)return simulQ=typeof simulQ!=='undefined'?simulQ:true if(simulQ){if(name.length>0){var div=document.getElementById(name) if(div.currentTime>0&&div.currentTime0)soundPlayQueue();};} function Tile(wd,ht,lt,tp,clr,bdName){this.wd=wd this.ht=ht this.xn=Math.round(lt/my.boxWd) this.yn=Math.round(tp/my.boxWd) this.bgClr=clr this.fgClr='black' this.status='clear' this.sunkQ=false var div=document.createElement("div");div.style.width=wd+'px' div.style.height=ht+'px' div.style.position='absolute' div.style.top=tp+'px' div.style.left=lt+'px' this.div=div var me=this div.addEventListener('mouseover',function(){if(!my.activeQ)return if(me.status!='clear')return me.drawStatus('over')}) div.addEventListener('mouseleave',function(){if(!my.activeQ)return if(me.status!='clear')return if(!me.onQ)return me.drawStatus()}) div.addEventListener('click',function(){if(!my.activeQ)return if(me.status!='clear')return my.activeQ=false update(me)}) var can=document.createElement('canvas');can.style.position="absolute";can.style.top='0px' can.style.left='0px' can.style.width='100%' can.style.height='100%' can.width=wd can.height=ht this.g=can.getContext("2d");div.appendChild(can) document.getElementById(bdName).appendChild(div);this.draw()} Tile.prototype.hit=function(onQ){if(onQ){this.status='hit' soundPlay('sndHit')}else{this.status='miss' soundPlay('sndMiss')} this.draw()} Tile.prototype.draw=function(onQ){this.onQ=typeof onQ!=='undefined'?onQ:true if(this.onQ){this.div.style.pointerEvents="auto";var fgClr=(this.playerN==0)?'darkblue':'darkred' this.drawStatus(this.status,fgClr)}else{var g=this.g g.clearRect(0,0,g.canvas.width,g.canvas.height) this.div.style.pointerEvents="none";}} Tile.prototype.drawStatus=function(status,fgClr){status=typeof status!=='undefined'?status:this.status this.fgClr=typeof fgClr!=='undefined'?fgClr:'black' var g=this.g g.clearRect(0,0,g.canvas.width,g.canvas.height) g.fillStyle=this.bgClr g.beginPath() g.rect(0,0,this.wd,this.ht) g.fill() g.strokeStyle=this.fgClr switch(status){case 'over':g.strokeStyle='blue' g.lineWidth=2 g.beginPath() g.arc(this.wd/2,this.ht/2,this.wd/3,0,2*Math.PI) g.stroke() break case 'hit':g.strokeStyle='black' g.fillStyle='red' g.lineWidth=3 g.beginPath() g.arc(this.wd/2,this.ht/2,this.wd/3,0,2*Math.PI) g.stroke() g.fill() break case 'miss':g.strokeStyle='rgba(255,255,255,0.3)' g.fillStyle='rgba(0,0,255,0.2)' g.lineWidth=3 g.beginPath() g.arc(this.wd/2,this.ht/2,this.wd/3,0,2*Math.PI) g.stroke() g.fill() break case 'x':g.lineWidth=2 var edge=this.wd*0.2 g.beginPath() g.moveTo(edge,edge) g.lineTo(this.wd-edge,this.wd-edge) g.stroke() g.beginPath() g.moveTo(edge,this.wd-edge) g.lineTo(this.wd-edge,edge) g.stroke() break default:}} Tile.prototype.win=function(){this.bgClr='#ffe' this.draw()} Tile.prototype.setxy=function(lt,tp){this.div.style.left=lt+'px';this.div.style.top=tp+'px';} function Player(name,clr,bgClr,bdName,clrs){this.name=name this.clr=clr this.clrs=clrs this.bgClr=bgClr this.bdName=bdName this.score=0 this.ships=[];this.bd=[];} Player.prototype.bestMove=function(){var dirs=[[0,-1],[1,0],[0,1],[-1,0]] var best={score:-9,xn:0,yn:0} for(var i=0;ibest.score)best={score:scoreTot,xn:i,yn:j}}} return best} function tileType(bd,xn,yn){if(xn<0)return 0 if(yn<0)return 0 if(xn>=my.bdSz)return 0 if(yn>=my.bdSz)return 0 var tile=bd[xn][yn] if(tile.sunkQ)return 9 if(tile.status=='hit')return 1 if(tile.status=='miss')return 2 return 0} Player.prototype.autoPlace=function(){this.ships=[];my.zIndex=1;var shipLens=my.shipSets[my.shipSetN];for(var i=0;i=this.sz){this.sunkQ=true soundPlay('sndSunk') this.show(true) console.log('ship just sunk') for(var i=0;imy.bdSz)return false if(this.pos.y+this.yn>my.bdSz)return false return true} Ship.prototype.intersectsQ=function(ships){for(var i=0;ir.rt)return false if(yr.bt)return false return true} function intersectRect(r1,r2){return!(r2.lt>r1.rt||r2.rtr1.bt||r2.bt