let el,w,h,my={};function spreadMain(wd,ht){let version='0.38';w=typeof wd!=='undefined'?wd:'500';h=typeof ht!=='undefined'?ht:'400';my.opts={gameN:2}
let ltBG='background: radial-gradient(#bbb 15%, transparent 16%) 0 0,radial-gradient(#bbb 15%, transparent 16%) 6px 6px, radial-gradient(rgba(240,240,240,.1) 15%, transparent 20%) 0 1px, radial-gradient(rgba(240,240,240,.1) 15%, transparent 20%) 6px 6px; background-color:#abc; background-size:12px 12px;';my.mates=[{name:'Blue',bgClr:'rgba(120,250,128,0.1)',fgClr:'rgba(120,250,128,0.1)',ai:1},{name:'Red',bgClr:'rgba(255,0,0,1)',fgClr:'rgba(120,250,128,0.1)',ai:0},{name:'Green',bgClr:'rgba(0,255,0,1)',fgClr:'rgba(120,250,128,0.1)',ai:1}];my.mateMax=2;my.vals=[{clr:'rgba(66,88,255,1)'},{clr:'rgba(255,0,0,1)'},{clr:'rgba(0,255,0,1)'},{clr:'rgba(0,255,255,1)'},{clr:'rgba(255,155,255,1)'},{clr:'rgba(0,0,0,1)'},]
my.hards=[{title:'Easy',worst:4},{title:'Basic',worst:2},{title:'Hard',worst:0}];my.gameN=optGet('gameN')
my.games=[{name:'10x9 (3)',xn:10,yn:9,allEdgesQ:true,clrN:3,clickMax:6},{name:'14x12 (3)',xn:14,yn:12,allEdgesQ:true,clrN:3,clickMax:7},{name:'14x12 (4)',xn:14,yn:12,allEdgesQ:true,clrN:4,clickMax:11},{name:'16x14 (4)',xn:16,yn:14,allEdgesQ:true,clrN:4,clickMax:11},{name:'17x15 (4)',xn:17,yn:15,allEdgesQ:true,clrN:4,clickMax:12},{name:'17x15 (5)',xn:17,yn:15,allEdgesQ:true,clrN:5,clickMax:14},{name:'17x15 (6)',xn:17,yn:15,allEdgesQ:true,clrN:6,clickMax:17},{name:'20x18 (6)',xn:20,yn:18,allEdgesQ:true,clrN:6,clickMax:19},{name:'24x22 (6)',xn:24,yn:22,allEdgesQ:true,clrN:6,clickMax:21},{name:'28x25 (6)',xn:28,yn:25,allEdgesQ:true,clrN:6,clickMax:24},{name:'33x28 (6)',xn:33,yn:28,allEdgesQ:true,clrN:6,clickMax:27},]
my.game=my.games[my.gameN]
let s='';my.sndHome=(document.domain=='localhost')?'/mathsisfun/images/sounds/':'/images/sounds/'
s+=' '
s+=' '
s+='
';s+='
0
';s+='
';s+='
Completed
';s+='
✔ ';s+='
✘ ';s+='
';s+='
';s+='New Game ';s+='Resize ';my.soundQ=true
s+=soundBtnHTML()
s+='
';s+='
© 2021 MathsIsFun.com v'+version+'
';s+='
';s+='
';s+=optPopHTML();s+='
';document.write(s);el=document.getElementById('can1');canResize(el,w,h);g=el.getContext("2d");el2=document.getElementById('can2');canResize(el2,w,h);g2=el2.getContext("2d");this.clrs=[["Blue",'#0000FF'],["Red",'#FF0000'],["Black",'#000000'],["Green",'#00cc00'],["Violet",'#EE82EE'],["Orange",'#FFA500'],["Light Salmon",'#FFA07A'],["Slate Blue",'#6A5ACD'],["Yellow",'#FFFF00'],["Aquamarine",'#7FFFD4'],["Pink",'#FFC0CB'],["Coral",'#FF7F50'],["Lime",'#00FF00'],["Pale Green",'#98FB98'],["Spring Green",'#00FF7F'],["Teal",'#008080'],["Hot Pink",'#FF69B4'],["Yellow",'#ffff00'],["Aqua",'#00ffff'],["Gold",'#ffd700'],["Khaki",'#F0E68C'],["Thistle",'#D8BFD8'],["Med Purple",'#aa00aa'],["Light Blue",'#ADD8E6'],["Sky Blue",'#87CEEB'],["Navy",'#000080'],["Purple",'#800080'],["Wheat",'#F5DEB3'],["Tan",'#D2B48C'],["Silver",'#C0C0C0']];el2=document.getElementById('can2');el2.addEventListener('touchstart',touchStart,false);el2.addEventListener('touchmove',touchMove,false);window.addEventListener('touchend',touchEnd,false);el2.addEventListener("mousedown",mouseDown,false);el2.addEventListener("mousemove",mouseMove,false);window.addEventListener("mouseup",mouseUp,false);my.holesQ=false;my.turn=0;my.turnQ=true;my.turns=[0,0,0];my.bd=new Board();my.maxQ=false;window.addEventListener('resize',resize,false);window.addEventListener('orientationchange',resize,false);mateMaxChg(0,0);optPop();}
function hardChg(n){my.hard=my.hards[n];console.log('hardChg',n,my.hard);}
function sizeToggle(){my.maxQ=!my.maxQ;resize();}
function resize(){let wd=500;let ht=400;let tpGap=50
let gap=20
if(my.maxQ){wd=window.innerWidth
ht=window.innerHeight-tpGap}
let xSz=(wd-gap)/((my.game.xn+0.5)*2*0.866)
let ySz=(ht-gap)/(my.game.yn*1.5)
my.cellWd=Math.min(xSz,ySz)
let xExcess=wd-my.cellWd*(my.game.xn+0.5)*2*0.866
my.bd.lt=my.cellWd+xExcess/2
my.bd.tp=my.cellWd
console.log("resize",xExcess,my.maxQ,xSz,ySz,my.cellWd,wd,ht);let div=document.getElementById('main');let dadStyle=getComputedStyle(div.parentNode);let dadWd=parseInt(dadStyle.width)
div.style.left=(dadWd-wd)/2+"px";div.style.top=2+"px";div.style.width=(wd<<0)+"px";div.style.height=((ht+tpGap)<<0)+"px";canResize(el,0,tpGap,wd,ht);canResize(el2,0,tpGap,wd,ht);my.bd.redraw();}
function canResize(can,lt,tp,wd,ht){ratio=2;can.left=lt;can.top=tp;can.style.left=lt+"px";can.style.top=tp+"px";can.width=wd*ratio;can.height=ht*ratio;can.style.width=wd+"px";can.style.height=ht+"px";can.getContext("2d").setTransform(ratio,0,0,ratio,0,0);}
function turnNext(){return
g2.clearRect(0,0,el.width,el.height);if(my.bd.getLeft()<=0){my.bd.redraw();win();return;}
my.turn=loop(my.turn,0,my.mateMax-1);let player=my.mates[my.turn];console.log('turnNext',player,my)
let val=player.rounds[player.roundN++];val=Math.max(1,Math.min(val,20));my.turns[my.turn]+=val;my.bd.redraw();if(my.mates[my.turn].ai==1){my.turnQ=false;setTimeout(aimove,1000);}}
function aimove(){my.bd.aimove();my.turnQ=true;}
class Cell{constructor(xn,yn,val){this.xn=xn
this.yn=yn
this.val=val
this.typ=-1}
draw(g,setClrQ=true){let jig=0;if(this.yn%2)jig=my.cellWd*(0.866);let xc=this.xn*my.cellWd*2*0.866+jig;let yc=this.yn*my.cellWd*1.5;if(setClrQ){g.strokeStyle='#99a';if(this.typ>=-1){g.lineWidth=1;if(this.typ==-1){g.fillStyle=my.vals[this.val].clr;}else{g.fillStyle=my.mates[my.turn].bgClr
g.strokeStyle=my.mates[my.turn].fgClr}}}
if(this.typ==-2){g.lineWidth=0;g.strokeStyle='transparent';g.fillStyle='transparent';}
for(let i=0;i<1;i++){drawHex(g,my.bd.lt+xc,my.bd.tp+yc,my.cellWd-i);g.fill();g.stroke();}
let s=(this.typ==-1)?'':'😀'
if(s.length>0){g.textAlign='center';g.font=((my.cellWd*0.8)<<0)+'px Arial';let endClr=g.fillStyle;g.fillStyle='black';g.fillText(s,my.bd.lt+xc,my.bd.tp+yc+my.cellWd*0.3);g.fillStyle=endClr}}
click(){if(my.soundQ)document.getElementById('sndmove').play();my.mates[my.turn].clickN+=1
this.typ=my.turn
console.log('Cell click',my.turn,this)
this.draw(g)
if(my.game.allEdgesQ){let edges=[]
do{edges=my.bd.chgEdges(this.val)}while(edges.length>0)}else{this.nborChg(this.val)}
my.bd.redraw()
let leftN=my.bd.getLeft()
if(leftN==0&&my.mates[my.turn].clickN<=my.mates[my.turn].clickMax){win(true)
return}
if(my.mates[my.turn].clickN>=my.mates[my.turn].clickMax){win(false)}}
nborChg(v){let nbors=my.bd.getNbors(this.xn,this.yn);for(let i=0;i99){if(1==0){this.edges=this.getEdges()
if(this.edges.length>0){let n=(Math.random()*this.edges.length)<<0
let edge=this.edges[n];edge.click()}}
if(1==0){if(my.game.allEdgesQ){for(let i=0;i0)
my.bd.cells=backup.slice(0)
my.bd.redraw()}}}
console.log('yippee',this.frame)
this.frame=0
if(this.getLeft()<=0)return}
requestAnimationFrame(this.aiLoop.bind(this));}
aimove(){let orig=copy2d(this.cells);let bests=[];for(let i=0;i=my.game.xn)return;if(yn>=my.game.yn)return;let edgeQ=false
for(let i=0;i=my.game.xn)return false;if(yn>=my.game.yn-1)return false;return true;}
hilite(xn,yn){g2.clearRect(0,0,el2.width,el2.height);if(!this.inq(xn,yn))return;let edgeQ=false
for(let i=0;i-1)edgeQ=true}
if(edgeQ)edges.push(cell)}}}
return edges}
chgEdges(val){let edges=[]
for(let i=0;i-1&&cell.val==val)edgeQ=true}
if(edgeQ)edges.push(cell)}}}
for(let i=0;i of '+my.mates[my.turn].clickMax+' ';s+='';document.getElementById('score').innerHTML=s;}}
function drawHex(g,xc,yc,r){g.beginPath();for(let i=0;i<6;i++){a=(i+0.5)*Math.PI/3;x=Math.cos(a)*r;y=Math.sin(a)*r;if(i==0){g.moveTo(xc+x,yc+y);}else{g.lineTo(xc+x,yc+y);}}
g.closePath();}
function touchStart(evt){let touch=evt.targetTouches[0];evt.clientX=touch.clientX;evt.clientY=touch.clientY;evt.touchQ=true;mouseDown(evt)}
function touchMove(evt){let touch=evt.targetTouches[0];evt.clientX=touch.clientX;evt.clientY=touch.clientY;evt.touchQ=true;mouseMove(evt)}
function touchEnd(){draggingQ=false;}
function mouseDown(evt){let bRect=el.getBoundingClientRect();mouseX=(evt.clientX-bRect.left)*(el.width/ratio/bRect.width);mouseY=(evt.clientY-bRect.top)*(el.height/ratio/bRect.height);if(my.turnQ)my.bd.click(mouseX,mouseY);draggingQ=true;frames=0;evt.preventDefault();return false;}
function mouseMove(evt){let bRect=el.getBoundingClientRect();mouseX=(evt.clientX-bRect.left)*(el.width/ratio/bRect.width);mouseY=(evt.clientY-bRect.top)*(el.height/ratio/bRect.height);if(my.turnQ)my.bd.hiCell(mouseX,mouseY);if(evt.preventDefault){evt.preventDefault();}
return false;}
function mouseUp(){draggingQ=false;}
function holesToggle(){my.holesQ=!my.holesQ;btnToggle("holesBtn",my.holesQ);}
function btnToggle(btn,onq){console.log('btnToggle',btn,onq)
if(onq){document.getElementById(btn).classList.add("hi");document.getElementById(btn).classList.remove("lo");}else{document.getElementById(btn).classList.add("lo");document.getElementById(btn).classList.remove("hi");}}
function optPopHTML(){let s='';s+='';s+='';s+=radioHTML('Game','game',my.games,my.gameN,'radioClick');s+='
';s+='New game? '
s+='✔ ';s+=' '
s+='✘ ';s+='
';s+='
';return s;}
function optPop(){console.log("optpop");var pop=document.getElementById('optpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=102;pop.style.left=(w-340)/2+'px';}
function optYes(){var 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(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';}
function optGet(name){var val=localStorage.getItem(`yacht.${name}`)
if(val==null)val=my.opts[name]
return val}
function optSet(name,val){localStorage.setItem(`yacht.${name}`,val)
my.opts[name]=val}
function radioHTML(prompt,id,lbls,checkN,func){let s='';s+='';s+='
';s+=prompt;s+='
';s+='
';for(let i=0;i';s+=''+lbl.name+' ';s+=' ';}
s+='
';s+='
';return s;}
function mateTypChg(n,i){console.log("mateTyp",n,i);my.mates[n].ai=i;}
function mateMaxChg(n,i){console.log("mateMaxChg",i);my.mateMax=i+2;}
function gameNew(){g.clearRect(0,0,el.width,el.height);g2.clearRect(0,0,el.width,el.height);winClose();my.turn=0;my.turns=[0,0,0];my.mates.map(mate=>{mate.clickN=0})
my.cellWd=(w-15)/(my.game.xn*2*0.866);my.bd.lt=my.cellWd
my.bd.tp=my.cellWd
my.bd.fill()
let cell=my.bd.setRand(my.turn)
let far=Math.abs(cell.xn-my.game.xn/2)+Math.abs(cell.yn-my.game.yn/2)
console.log('far',far)
my.mates[my.turn].clickMax=my.game.clickMax+(far/4)<<0
my.bd.redraw()
resize();}
function roundsNew(){let roundN=my.bd.getLeft()/my.mateMax;let rounds=[];for(let i=1;i<=roundN;i++){let n=Math.ceil(20*i/roundN);rounds.push(n);}
for(let i=0;i'
if(winQ){s+='You wIn'}else{s+='You have run out of moves :)'}
s+='';document.getElementById('winTxt').innerHTML=s;}
function winClose(newQ){console.log('winClose',newQ)
div=document.getElementById('win');div.style.opacity=0;div.style.left='-999px';if(newQ)gameNew()}
function copy2d(a){let b=[];for(let i=0;imaxNo){currNo=minNo+(currNo-minNo)%range;}
return currNo;}
Array.prototype.shuffle=function(){let counter=this.length,temp,index;while(counter>0){index=(Math.random()*counter--)|0;temp=this[counter];this[counter]=this[index];this[index]=temp;}};function soundBtnHTML(){let s=''
s+=''
s+='
'
return s}
function radioClick(n){}
function radioNGet(name){var div=document.querySelector('input[name="'+name+'"]:checked')
var id=div.id
var n=(id.match(/\d+$/)||[]).pop();return n}
function soundToggle(){let btn='sound'
if(my.soundQ){my.soundQ=false
document.getElementById(btn).classList.add("mute")}else{my.soundQ=true
document.getElementById(btn).classList.remove("mute")}}