function inicio (QntityDisks){ nDisks=QntityDisks; optimalSolution= Math.pow(2,QntityDisks)-1; var x = 0; var y = 549.5; var w = 330; start = Date.now(); startOfMove = Date.now(); for (var i = 0; i < QntityDisks; i++) { var disk = new Disk(x,y,w,40,pat[i+1]); towerA.push(disk); x+=20; //moves to the right y-=41; //moves up, +1 to separate disks w-=40; //reduces disk width } drawScene(); } class Disk{ constructor(x,y,w,h,fill){ this.x=x; this.y=y; this.w=w; this.h=h; this.fill=fill; } draw(){//(ctx, x, y, width, height, radius, fill, stroke) context.fillStyle = this.fill; context.strokeStyle = "black"; roundRect(context, this.x, this.y, this.w, this.h, 20, 20, true); } clear(){ context.clearRect(this.x, this.y, this.w, this.h); } } function reset (QntityDisks){ nDisks = QntityDisks; towerA.splice(0,towerA.length); towerB.splice(0,towerB.length); towerC.splice(0,towerC.length); moves.splice(0,moves.length); nMovements = 0; nTotalMovements = 0; idF = " "; idT=" "; toMove=null; inicio(QntityDisks); } function drawTowers (){ context.beginPath(); context.fillStyle = pat[0]; roundRect(context, 160, 260, 20, 340, 5, pat, false);//ctx, x, y, largura, altura, radius, fill, stroke(T/F) roundRect(context, 0, 590, 330, 20, 5, pat, false); roundRect(context, 505, 260, 20, 340, 5, pat, false); roundRect(context, 345, 590, 330, 20, 5, pat, false); roundRect(context, 850, 260, 20, 340, 5, pat, false); roundRect(context, 690, 590, 330, 20, 5, pat, false); } function drawDisks (){ for(i=0; i0){ toMove = id; idF= String.fromCharCode(65+id); idT= " "; drawScene(); } else if(toMove != null && toMove != id){ idT = String.fromCharCode(65+id); moveDisk(toMove, id); toMove=null; } } function getTower (id){ switch(id){ case 0: return towerA; case 1: return towerB; case 2: return towerC; } } function drawFromTo (){ context.font = "50px Arial"; context.fillStyle = "black"; context.fillText("Mover de "+idF+" para "+idT, 50, 50); context.fillText("Movimentos: "+nTotalMovements, 50, 100); } function moveDisk (origin, destiny){ var originTower = getTower(origin), destinyTower = getTower(destiny), topDiskOrigin, topDiskDestiny; moveTime = Math.floor( (Date.now()- startOfMove) /1000); startOfMove = Date.now();//update start of movement if(nMovements< moves.length){ moves.splice(nMovements, moves.length- nMovements); } moves.push(origin+" "+destiny); nMovements++; finishMove(origin, destiny); if(towerC.length == nDisks && nDisks!=0){ acertou=1; totalTime= Date.now() - start; if(nTotalMovements==optimalSolution){ alert("Você ganhou com a quantidade ótima de movimentos "+optimalSolution+"!!!\nParabens!!!"); }else{ alert("Você ganhou com "+nTotalMovements+" movimentos sendo o minimo possível "+optimalSolution); } } } function roundRect(ctx, x, y, width, height, radius, fill, stroke) { if (typeof stroke == "undefined" ) { stroke = true; } if (typeof radius === "undefined") { radius = 5; } ctx.beginPath(); ctx.moveTo(x + radius, y); ctx.lineTo(x + width - radius, y); ctx.quadraticCurveTo(x + width, y, x + width, y + radius); ctx.lineTo(x + width, y + height - radius); ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); ctx.lineTo(x + radius, y + height); ctx.quadraticCurveTo(x, y + height, x, y + height - radius); ctx.lineTo(x, y + radius); ctx.quadraticCurveTo(x, y, x + radius, y); ctx.closePath(); if (stroke) { ctx.stroke(); } if (fill) { ctx.fill(); } } function undo(){ if(nMovements>0){ var res = moves[nMovements-1].split(" "); nMovements--; if (nMovements>1){ var res2 = moves[nMovements-2].split(" "); idf = res2[0]; idt = res2[1]; } else{ idf = " "; idt = " "; } finishMove(parseInt(res[1]), parseInt(res[0])); } } function redo(){ if (nMovements < moves.length){ var res = moves[nMovements].split(" "); nMovements++; finishMove(parseInt(res[0]), parseInt(res[1])); } } function finishMove(origin, destiny){ nTotalMovements++; var originTower = getTower(origin), destinyTower = getTower(destiny), topDiskOrigin, topDiskDestiny; topDiskOrigin = originTower[originTower.length-1]; totalMoves.push(origin+" "+destiny+" "+moveTime); if(destinyTower.length>0){ topDiskDestiny = destinyTower[destinyTower.length-1]; if(topDiskOrigin.w