|
@@ -1,209 +1,209 @@
|
|
|
var canvas = document.getElementById('planoDeFundo');
|
|
|
- var context = canvas.getContext('2d');
|
|
|
- var towerA = [], towerB = [], towerC = [];
|
|
|
- var toMove = null;
|
|
|
- var idF=" ", idT= " ";
|
|
|
- var nMovements = 0, nWrongMoves=0, nDisks;
|
|
|
- var moves="";
|
|
|
- var acertou=0;
|
|
|
- var optimalSolution;
|
|
|
-
|
|
|
- var colors = ["#000080","#00FF00", "#FF00FF", "yellow", "#FFA500", "#B0C4DE","red"];
|
|
|
- var start = Date.now(), startOfMove, totalTime, moveTime;
|
|
|
-
|
|
|
- function inicio (QntityDisks){
|
|
|
- nDisks = QntityDisks;
|
|
|
- optimalSolution= Math.pow(2,nDisks)-1;
|
|
|
- var x = 0;
|
|
|
- var y = 558;
|
|
|
- var w = 330;
|
|
|
- moves="";
|
|
|
- startOfMove=Date.now();
|
|
|
- for (var i = 0; i < nDisks; i++) {
|
|
|
- var disk = new Disk(x,y,w,40,colors[i]);
|
|
|
- towerA.push(disk);
|
|
|
- x+=20;
|
|
|
- y-=42;
|
|
|
- w-=40;
|
|
|
- }
|
|
|
- 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(){
|
|
|
- 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 reinicio (){
|
|
|
- while(towerA.length>0){
|
|
|
- towerA.pop();
|
|
|
- }
|
|
|
- while(towerB.length>0){
|
|
|
- towerB.pop();
|
|
|
- }
|
|
|
- while(towerC.length>0){
|
|
|
- towerC.pop();
|
|
|
- }
|
|
|
- nMovements=0;
|
|
|
- idF = " ";
|
|
|
- idT=" ";
|
|
|
- toMove=null;
|
|
|
- inicio();
|
|
|
- }
|
|
|
- function drawTowers (){
|
|
|
- context.beginPath();
|
|
|
-
|
|
|
- context.fillStyle = 'black';
|
|
|
- context.fillRect(160, 260, 10, 340);
|
|
|
-
|
|
|
-
|
|
|
- context.fillRect(0, 600, 330, 15);
|
|
|
-
|
|
|
-
|
|
|
- context.fillRect(505, 260 ,10, 340);
|
|
|
-
|
|
|
-
|
|
|
- context.fillRect(345, 600, 330, 15);
|
|
|
-
|
|
|
-
|
|
|
- context.fillRect(850, 260, 10, 340);
|
|
|
-
|
|
|
-
|
|
|
- context.fillRect(690, 600, 330, 15);
|
|
|
- }
|
|
|
-
|
|
|
- function drawDisks (){
|
|
|
- for(i=0; i<towerA.length; i++){
|
|
|
- towerA[i].draw();
|
|
|
- }
|
|
|
- for(i=0; i<towerB.length; i++){
|
|
|
- towerB[i].draw();
|
|
|
- }
|
|
|
- for(i=0; i<towerC.length; i++){
|
|
|
- towerC[i].draw();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function drawScene (){
|
|
|
- context.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
- drawTowers();
|
|
|
- drawDisks();
|
|
|
- drawFromTo();
|
|
|
- }
|
|
|
-
|
|
|
- function buttonClick (id){
|
|
|
- if(toMove == null && getTower(id).length>0){
|
|
|
- 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("Move from "+idF+" to "+idT, 50, 50);
|
|
|
- context.fillText("Movements: "+nMovements, 50, 100);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- function moveDisk (origin, destiny){
|
|
|
- var originTower = getTower(origin), destinyTower = getTower(destiny), topDiskOrigin, topDiskDestiny;
|
|
|
- moveTime = Math.floor( (Date.now()- startOfMove) /1000);
|
|
|
- moves+="\n"+origin+" "+destiny+" "+moveTime;
|
|
|
- startOfMove = Date.now();
|
|
|
- console.clear();
|
|
|
- console.log(moves);
|
|
|
- nMovements++;
|
|
|
-
|
|
|
- topDiskOrigin = originTower[originTower.length-1];
|
|
|
- if(destinyTower.length>0){
|
|
|
- topDiskDestiny = destinyTower[destinyTower.length-1];
|
|
|
- if(topDiskOrigin.w<topDiskDestiny.w){
|
|
|
- topDiskOrigin.x += 345*(destiny-origin);
|
|
|
- topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
|
|
|
- originTower.pop();
|
|
|
- destinyTower.push(topDiskOrigin);
|
|
|
- drawScene();
|
|
|
- } else{
|
|
|
- nWrongMoves++;
|
|
|
- alert("Movimento Inválido");
|
|
|
- idF =" ";
|
|
|
- idT =" ";
|
|
|
- drawScene();
|
|
|
- }
|
|
|
- }else{
|
|
|
- topDiskOrigin.x += 345*(destiny-origin);
|
|
|
- topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
|
|
|
- originTower.pop();
|
|
|
- destinyTower.push(topDiskOrigin);
|
|
|
- nMovements++;
|
|
|
- drawScene();
|
|
|
- }
|
|
|
- if(towerC.length == nDisks && nDisks!=0){
|
|
|
- acertou=1;
|
|
|
- totalTime= Date.now() - start;
|
|
|
- if(nMovements==optimalSolution){
|
|
|
- alert("You Won in the least amount of movements!!!\nCongratulations!!!");
|
|
|
- }else{
|
|
|
- alert("You Won!!!\nCongratulations!!");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- 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();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+var context = canvas.getContext('2d');
|
|
|
+var towerA = [], towerB = [], towerC = [];
|
|
|
+var toMove = null;
|
|
|
+var idF=" ", idT= " ";
|
|
|
+var nMovements = 0, nWrongMoves=0, nDisks;
|
|
|
+var moves="";
|
|
|
+var acertou=0;
|
|
|
+var optimalSolution;
|
|
|
+
|
|
|
+var colors = ["#000080","#00FF00", "#FF00FF", "yellow", "#FFA500", "#B0C4DE","red"];
|
|
|
+var start = Date.now(), startOfMove, totalTime, moveTime;
|
|
|
+
|
|
|
+function inicio (QntityDisks){
|
|
|
+ nDisks = QntityDisks;
|
|
|
+ optimalSolution= Math.pow(2,nDisks)-1;
|
|
|
+ var x = 0;
|
|
|
+ var y = 558;
|
|
|
+ var w = 330;
|
|
|
+ moves="";
|
|
|
+ startOfMove=Date.now();
|
|
|
+ for (var i = 0; i < nDisks; i++) {
|
|
|
+ var disk = new Disk(x,y,w,40,colors[i]);
|
|
|
+ towerA.push(disk);
|
|
|
+ x+=20;
|
|
|
+ y-=42;
|
|
|
+ w-=40;
|
|
|
+ }
|
|
|
+ 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(){
|
|
|
+ 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 reinicio (){
|
|
|
+ while(towerA.length>0){
|
|
|
+ towerA.pop();
|
|
|
+ }
|
|
|
+ while(towerB.length>0){
|
|
|
+ towerB.pop();
|
|
|
+ }
|
|
|
+ while(towerC.length>0){
|
|
|
+ towerC.pop();
|
|
|
+ }
|
|
|
+ nMovements=0;
|
|
|
+ idF = " ";
|
|
|
+ idT=" ";
|
|
|
+ toMove=null;
|
|
|
+ inicio();
|
|
|
+}
|
|
|
+function drawTowers (){
|
|
|
+ context.beginPath();
|
|
|
+
|
|
|
+ context.fillStyle = 'black';
|
|
|
+ context.fillRect(160, 260, 10, 340);
|
|
|
+
|
|
|
+
|
|
|
+ context.fillRect(0, 600, 330, 15);
|
|
|
+
|
|
|
+
|
|
|
+ context.fillRect(505, 260 ,10, 340);
|
|
|
+
|
|
|
+
|
|
|
+ context.fillRect(345, 600, 330, 15);
|
|
|
+
|
|
|
+
|
|
|
+ context.fillRect(850, 260, 10, 340);
|
|
|
+
|
|
|
+
|
|
|
+ context.fillRect(690, 600, 330, 15);
|
|
|
+}
|
|
|
+
|
|
|
+function drawDisks (){
|
|
|
+ for(i=0; i<towerA.length; i++){
|
|
|
+ towerA[i].draw();
|
|
|
+ }
|
|
|
+ for(i=0; i<towerB.length; i++){
|
|
|
+ towerB[i].draw();
|
|
|
+ }
|
|
|
+ for(i=0; i<towerC.length; i++){
|
|
|
+ towerC[i].draw();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function drawScene (){
|
|
|
+ context.clearRect(0, 0, canvas.width, canvas.height);
|
|
|
+ drawTowers();
|
|
|
+ drawDisks();
|
|
|
+ drawFromTo();
|
|
|
+}
|
|
|
+
|
|
|
+function buttonClick (id){
|
|
|
+ if(toMove == null && getTower(id).length>0){
|
|
|
+ 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("Move from "+idF+" to "+idT, 50, 50);
|
|
|
+ context.fillText("Movements: "+nMovements, 50, 100);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+function moveDisk (origin, destiny){
|
|
|
+ var originTower = getTower(origin), destinyTower = getTower(destiny), topDiskOrigin, topDiskDestiny;
|
|
|
+ moveTime = Math.floor( (Date.now()- startOfMove) /1000);
|
|
|
+ moves+="\n"+origin+" "+destiny+" "+moveTime;
|
|
|
+ startOfMove = Date.now();
|
|
|
+ console.clear();
|
|
|
+ console.log(moves);
|
|
|
+ nMovements++;
|
|
|
+
|
|
|
+ topDiskOrigin = originTower[originTower.length-1];
|
|
|
+ if(destinyTower.length>0){
|
|
|
+ topDiskDestiny = destinyTower[destinyTower.length-1];
|
|
|
+ if(topDiskOrigin.w<topDiskDestiny.w){
|
|
|
+ topDiskOrigin.x += 345*(destiny-origin);
|
|
|
+ topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
|
|
|
+ originTower.pop();
|
|
|
+ destinyTower.push(topDiskOrigin);
|
|
|
+ drawScene();
|
|
|
+ } else{
|
|
|
+ nWrongMoves++;
|
|
|
+ alert("Movimento Inválido");
|
|
|
+ idF =" ";
|
|
|
+ idT =" ";
|
|
|
+ drawScene();
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ topDiskOrigin.x += 345*(destiny-origin);
|
|
|
+ topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
|
|
|
+ originTower.pop();
|
|
|
+ destinyTower.push(topDiskOrigin);
|
|
|
+ nMovements++;
|
|
|
+ drawScene();
|
|
|
+ }
|
|
|
+ if(towerC.length == nDisks && nDisks!=0){
|
|
|
+ acertou=1;
|
|
|
+ totalTime= Date.now() - start;
|
|
|
+ if(nMovements==optimalSolution){
|
|
|
+ alert("You Won in the least amount of movements!!!\nCongratulations!!!");
|
|
|
+ }else{
|
|
|
+ alert("You Won!!!\nCongratulations!!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+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();
|
|
|
+ }
|
|
|
+}
|
|
|
+inicio(4);
|