let my={}
function init(){let version='0.89'
let m=getQueryVariable('g')
if(m){this.mode=m}else{this.mode='by6'}
my.opts={gameN:0,bdSz:5}
my.cellWd=46
my.cellHt=26
my.sttClr='white'
my.yesClr='gold'
my.noClr='#cdf'
my.anims=[]
my.games=[{id:'1-100',name:'10 wide, to 100',pos:'list',cols:10,rows:10,stt:1,skip:1,yGap:0,density:0.2},{id:'1-200',name:'10 wide, to 200',pos:'list',cols:10,rows:20,stt:1,skip:1,yGap:0,density:0.2},{id:'by6',name:'6 wide to 60',pos:'list',cols:6,rows:10,stt:1,skip:1,yGap:0,density:0.2},{id:'by12',name:'12 wide to 120',pos:'list',cols:12,rows:10,stt:1,skip:1,yGap:0,density:0.2},{id:'by6',name:'5 wide to 100',pos:'list',cols:5,rows:20,stt:1,skip:1,yGap:0,density:0.2},]
my.game=my.games[my.opts.gameN]
console.log('my.game',my.game)
let s=''
s+='
'
docInsert(s)
my.animNo=0
my.loopNo=0}
function gameNew(){let div=document.getElementById('grid')
div.innerHTML=gridHTML(this.mode)
document.getElementById('info').innerHTML=''
my.animNo=999
my.loopNo=999}
function animStt(){my.animNo=0
my.loopNo=0
console.log('my.anims',my.anims)
animLoop()}
function animLoop(){let div=document.getElementById(my.anims[my.animNo])
div.style.backgroundColor=my.loopNo<2?getRandomClr():typClr(div.getAttribute('data-typ')<<0)
my.animNo++
if(my.animNo>=my.anims.length){my.animNo=0
my.loopNo++}
if(my.loopNo<3)requestAnimationFrame(animLoop)}
function getAns(row,col){let x=0
if(my.game.pos=='units'){x=row*my.game.cols+col+1}else{x=my.game.stt+(row*my.game.cols+col)*my.game.skip}
return x}
function gridHTML(name){let s=''
my.anims=[]
let n=0
for(let i=0;i'
for(let j=0;j'
s+=v
s+=''
my.anims.push(id)
n++}
s+=''}
return s}
function doClick(me){let typ=me.getAttribute('data-typ')<<0
switch(typ){case 0:let id=me.getAttribute('id')
let n=id.substr(1)<<0
console.log('n',n)
if(n==1)break
me.style.backgroundColor=my.yesClr
me.setAttribute('data-typ',1)
for(let i=n*2;i<=my.game.rows*my.game.cols;i=i+n){let div=document.getElementById('v'+i)
div.style.backgroundColor=my.noClr
div.setAttribute('data-typ',2)}
break
case 1:break
case 2:break
default:}
console.log('winQ=',winQ())
if(winQ())winDo()}
function typClr(typ){switch(typ){case 0:return my.sttClr
break
case 1:return my.yesClr
break
case 2:return my.noClr
break
default:}
return 'black'}
function winDo(){document.getElementById('info').innerHTML='Well Done!'
animStt()}
function winQ(){for(let i=2;i<=my.game.rows*my.game.cols;i++){let div=document.getElementById('v'+i)
let typ=div.getAttribute('data-typ')<<0
if(typ==0)return false}
return true}
function doAns(me){let ids=me.id.split('-')
let a=ids.pop()
let div=document.getElementById(ids.join('-'))
div.innerHTML=a
document.getElementById('ansBox').style.visibility='hidden'
let ans=div.getAttribute('ans')<<0
let clr=my.yesClr
if(a!=ans){clr=my.noClr}
div.style.backgroundColor=clr
if(winQ())winDo()}
function getArrowBox(){let s=''
s+=''
return s}
function getRandomInt(min,max){return Math.floor(Math.random()*(max-min+1))+min}
function getRandomClr(){let ltrs='56789ABCDEF'.split('')
let clr='#'
for(let i=0;i<6;i++){clr+=ltrs[Math.round(Math.random()*(ltrs.length-1))]}
return clr}
function getQueryVariable(variable){let query=window.location.search.substring(1)
let vars=query.split('&')
for(let i=0;i'
s+=''
s+=radioHTML('Option:','game',my.games,my.gameN,'radioClick')
s+='
'
s+='Restart? '
s+=''
s+=' '
s+=''
s+='
'
s+=''
return s}
function optPop(){console.log('optpop')
let pop=document.getElementById('optpop')
pop.style.transitionDuration='0.3s'
pop.style.opacity=1
pop.style.zIndex=102
pop.style.left=(pop.parentElement.clientWidth-pop.clientWidth)/2+'px'}
function optYes(){let pop=document.getElementById('optpop')
pop.style.opacity=0
pop.style.zIndex=1
pop.style.left='-999px'
my.gameN=radioNGet('game')
console.log('optYes',my.gameN)
optSet('gameN',my.gameN)
my.game=my.games[my.gameN]
gameNew()}
function optNo(){let pop=document.getElementById('optpop')
pop.style.opacity=0
pop.style.zIndex=1
pop.style.left='-999px'}
function radioHTML(prompt,id,lbls,checkN,func){let s=''
s+='
'
s+='
'
s+=prompt
s+='
'
s+='
'
for(let i=0;i'
s+=''
s+=' '}
s+='
'
s+='
'
return s}
function radioNGet(name){let div=document.querySelector('input[name="'+name+'"]:checked')
let id=div.id
let n=(id.match(/\d+$/)||[]).pop()
return n}
function radioClick(n){}
function docInsert(s){let div=document.createElement('div')
div.innerHTML=s
let script=document.currentScript
script.parentElement.insertBefore(div,script)}
class Can{constructor(id,wd,ht,ratio){this.id=id
this.wd=wd
this.ht=ht
this.ratio=ratio
let el=document.getElementById(id)
el.width=wd*ratio
el.style.width=wd+'px'
el.height=ht*ratio
el.style.height=ht+'px'
this.g=el.getContext('2d')
this.g.setTransform(ratio,0,0,ratio,0,0)
this.el=el
return this}
clear(){this.g.clearRect(0,0,this.wd,this.ht)}
mousePos(ev){let bRect=this.el.getBoundingClientRect()
let mouseX=(ev.clientX-bRect.left)*(this.el.width/this.ratio/bRect.width)
let mouseY=(ev.clientY-bRect.top)*(this.el.height/this.ratio/bRect.height)
return[mouseX,mouseY]}}
function wrap({id='',cls='',pos='rel',style='',txt='',tag='div',lbl='',fn='',opts=[]},...mores){let s=''
s+='\n'
txt+=mores.join('')
s+={btn:()=>{if(cls.length==0)cls='btn'
return '