var my={} var ROWS=6 var COLS=7 my.inARow=4 var WINVAL=100000 var theAnim=new Animation() var moves=0 var gameActive=0 var isdropping=0 var RedNum=1 var BluNum=2 var whosFirst var redScore=0 var bluScore=0 var colcount=[] var board=[] var linecoords=[] var redSpot=new Image() var bluSpot=new Image() var emptySpot=new Image() var emptyPiece=new Image() var redPiece=new Image() var bluPiece=new Image() var whosTurn=RedNum var whosTurnSpot=new Image() var whosTurnPiece=new Image() function init(){let version='0.42' my.mode=getJSQueryVar('mode','4') switch(my.mode){case 'std':ROWS=6 COLS=7 my.inARow=4 break case '3':ROWS=6 COLS=3 my.inARow=3 break case '5':ROWS=8 COLS=12 my.inARow=5 break default:} var 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;' var s='' my.bgClr='#ffd' my.imgName='connect.html' themeChg() window.addEventListener('storage',themeChg) my.imgHome=(document.domain=='localhost'?'/mathsisfun':'')+'/games/images/' my.sndHome=(document.domain=='localhost'?'/mathsisfun':'')+'/images/sounds/' s+='' s+='' s+='
' s+=popHTML() s+=wrap({id:"texter",tag:'out',style:'width:200px; height:20px; text-align:center;'}) s+='' my.soundQ=true s+=soundBtnHTML() s+='
' s+=bdHTML() s+='
' s+='
History
' s+=wrap({cls:'copyrt',style:'margin-top:5px;'},`© 2021 MathsIsFun.com v${version}`) s+='
' docInsert(s) for(var row=0;row' for(var col=0;col' s+='' s+=''} s+=''} return s} function histClear(){console.log('histClear') my.hist=[[],[]] document.getElementById('hist').innerHTML=''} function histAdd(player,col){my.hist[player-1].push(col) histShow()} function histShow(){var s='' for(var p=0;p<2;p++){var h=my.hist[p] s+=playerName(p+1)+': ' for(var i=0;i0)s+=', ' s+=h[i]+1} s+='
'} document.getElementById('hist').innerHTML=s} function soundBtnHTML(){let 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 playerName(player){if(player==RedNum){return 'Red'}else{return 'Blue'}} function loaded(){redPiece.src=imgSlice(my.img,0,0,100,100,50,50) bluPiece.src=imgSlice(my.img,100,0,100,100,50,50) emptyPiece.src=imgSlice(my.img,200,0,100,100,50,50) redSpot.src=imgSlice(my.img,0,100,100,100,50,50) bluSpot.src=imgSlice(my.img,100,100,100,100,50,50) emptySpot.src=imgSlice(my.img,200,100,100,100,50,50) whosTurnSpot.src=redSpot.src whosTurnPiece.src=redPiece.src boardClear()} function imgSlice(img,x,y,wd,ht,toWd,toHt){var can=document.createElement('canvas') var ctx=can.getContext('2d') can.width=toWd can.height=toHt can.style.width=toWd+'px' can.style.height=toHt+'px' ctx.drawImage(img,x,y,wd,ht,0,0,toWd,toHt) return can.toDataURL()} function fill_lines(){linecoords=[] var chgArr=[[-1,1],[0,1],[1,0],[1,1],] for(let row=0;row=0&&col>=0&&rowcolcount[col];i--){tempRow=ROWS-i theAnim.addFrame(tempRow,col,whosTurnSpot.src) theAnim.addFrame(tempRow,col,emptySpot.src)} theAnim.finalcall='checkForWinner('+whosTurn+')' theAnim.addFrame(placeRow,col,whosTurnSpot.src) colcount[col]+=1 if(whosTurn==RedNum){board[colcount[col]-1][col]=RedNum}else{board[colcount[col]-1][col]=BluNum}}}}} function boarddump(){let s='' for(let col=0;col ' for(let row=0;rowStartStupid){if(Math.random()=0){board[row][col]=player var TheVal=MinMove(player,level-1,MaxVal,'Val') board[row][col]=0 if(TheVal==WINVAL)return WINVAL if(TheVal>ParentMin){return TheVal}else{if(TheVal>MaxVal){MaxVal=TheVal MaxCol=col}}}} if(want=='Val'){return MaxVal}else{return MaxCol}}} function MinMove(player,level,ParentMax,want){if(level<=0){return GetBoardVal(player)}else{var MinCol=0 var MinVal=WINVAL*10 for(var col=0;col=0){if(player==RedNum){board[row][col]=BluNum}else{board[row][col]=RedNum} var TheVal=MaxMove(player,level-1,MinVal,'Val') board[row][col]=0 if(TheVal==-WINVAL)return-WINVAL if(TheValMeMaxInARow)MeMaxInARow=MeInARow}else{MeInARow=0} if(posplayer==player2){YouInARow+=1 if(YouInARow>YouMaxInARow)YouMaxInARow=YouInARow}else{YouInARow=0}} x=0 if(MeMaxInARow==1)x+=1 if(MeMaxInARow==2)x+=4 if(MeMaxInARow==3)x+=64-YouMaxInARow*16 if(MeMaxInARow==4)x+=256-YouMaxInARow*50 if(MeMaxInARow==my.inARow)return WINVAL if(YouMaxInARow==1)x-=1 if(YouMaxInARow==2)x-=4 if(YouMaxInARow==3)x-=64-MeMaxInARow*16 if(YouMaxInARow==4)x-=256-MeMaxInARow*50 if(YouMaxInARow==my.inARow)return-WINVAL return x} function isWinner(Clr){var inaRow=my.inARow for(var i=0;i0){setTimeout(this.finalcall,5)}}} function popHTML(){var s='' var wd=330 s+='
' s+='
' s+='
' s+='' s+='' s+='
' var lineStyle='display: block; margin: 2px 30px 2px 0; ' var ltStyle='display: inline-block; width:100px; margin: 0 10px 0 0; font: 16px arial; color: black; text-align: right; ' var rtStyle='display: inline-block; width: 170px; color: black; text-align:center; padding: 3px; background-color: #eeffee; font: bold 16px Arial; border-radius: 10px; ' s+='
' s+='
Difficulty:
' s+='' s+='
' s+='
' s+='
' s+='
Red Player:
' s+='' s+='
' s+='
' s+='
called:
' s+='' s+='
' s+='
' s+='
' s+='
Blue Player:
' s+='' s+='
' s+='
' s+='
called:
' s+='' s+='
' s+='
' s+='
' s+='
Scores:
' s+='
' s+='Red: ' s+='0' s+='  Blue: ' s+='0' s+='
' s+='
' s+='
' s+='
' return s} function popOpen(){console.log('optpop') var pop=document.getElementById('optpop') pop.style.transitionDuration='0.3s' pop.style.opacity=1 pop.style.zIndex=12 pop.style.left='50%'} function popYes(){var pop=document.getElementById('optpop') pop.style.opacity=0 pop.style.zIndex=1 pop.style.left='-100%' gameNew()} function popNo(){var pop=document.getElementById('optpop') pop.style.opacity=0 pop.style.zIndex=1 pop.style.left='-100%'} my.drag={n:0,onq:false,holdX:0,holdY:0} class Mouse{constructor(el){console.log('new moose') el.addEventListener('touchstart',this.onTouchStart.bind(this),false) el.addEventListener('touchmove',this.onTouchMove.bind(this),false) window.addEventListener('touchend',this.onTouchEnd.bind(this),false) el.addEventListener('mousedown',this.onMouseDown.bind(this),false) el.addEventListener('mousemove',this.onMouseMove.bind(this),false) window.addEventListener('mouseup',this.onMouseUp.bind(this),false) this.el=el this.ratio=1} onTouchStart(ev){console.log('onTouchStart',this) let touch=ev.targetTouches[0] ev.clientX=touch.clientX ev.clientY=touch.clientY ev.touchQ=true this.onMouseDown(ev)} onTouchMove(ev){let touch=ev.targetTouches[0] ev.clientX=touch.clientX ev.clientY=touch.clientY ev.touchQ=true this.onMouseMove(ev)} onTouchEnd(ev){my.moose.onMouseUp(ev)} onMouseDown(ev){document.getElementById('angA').focus() let mouse=this.mousePos(ev) console.log('moose doon',mouse.x,mouse.y,my.shapes) my.drag.onQ=false my.drag.n=this.hitFind(my.shapes,mouse) if(my.drag.n>=0){console.log('drrragin!',my.drag.n) let pt=my.shapes[my.drag.n] my.drag.holdX=mouse.x-pt.x my.drag.holdY=mouse.y-pt.y my.shapes[my.drag.n].shadQ=true my.drag.onQ=true} ev.preventDefault()} onMouseMove(ev){let mouse=this.mousePos(ev) if(my.drag.onQ){let shape=my.shapes[my.drag.n] let pt={x:mouse.x-my.drag.holdX,y:mouse.y-my.drag.holdY} shape.x=pt.x shape.y=pt.y shape.div.style.left=pt.x+'px' shape.div.style.top=pt.y+'px' shape.div.style.filter='drop-shadow(3px 3px 3px #229)'}else{if(this.hitFind(my.shapes,mouse)>=0){document.body.style.cursor='pointer'}else{document.body.style.cursor='default'}}} onMouseUp(){if(my.drag.onQ){my.shapes[my.drag.n].div.style.filter='none' my.drag.onQ=false} document.body.style.cursor='default'} mousePos(ev){let bRect=this.el.getBoundingClientRect() return{x:(ev.clientX-bRect.left)*(bRect.width/this.ratio/bRect.width),y:(ev.clientY-bRect.top)*(bRect.height/this.ratio/bRect.height),}} hitFind(pts,mouse){for(let i=0;ishape.x+shape.wd)return false if(mouse.y>shape.y+shape.ht)return false return true}} my.theme=localStorage.getItem('theme') my.lineClr=my.theme=='dark'?'white':'black' my.opts={name:'user'} function optGet(name){let val=localStorage.getItem(`mif.${name}`) if(val==null)val=my.opts[name] return val} function optSet(name,val){localStorage.setItem(`mif.${name}`,val) my.opts[name]=val} function getJSQueryVar(varName,defaultVal){let scripts=document.getElementsByTagName('script') let lastScript=scripts[scripts.length-1] let scriptName=lastScript.src let bits=scriptName.split('?') if(bits.length<2)return defaultVal let query=bits[1] console.log('query: ',query) let vars=query.split('&') for(let i=0;i{if(cls.length==0)cls='btn' return '