iHanoiFunctions.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. var canvas = document.getElementById('planoDeFundo');
  2. var context = canvas.getContext('2d');
  3. var towerA = [], towerB = [], towerC = [];
  4. var toMove = null;
  5. var idF=" ", idT= " ";
  6. var nMovements = 0, nWrongMoves=0, nDisks;
  7. var moves=""; //string to save movements
  8. var acertos;
  9. var optimalSolution;
  10. //NavyBlue Lime Fuchsia yellow Orange LightSteelBlue red
  11. var colors = ["#000080","#00FF00", "#FF00FF", "yellow", "#FFA500", "#B0C4DE","red"];
  12. var start = Date.now(), startOfMove, totalTime, moveTime; //timing vars
  13. function inicio (QntityDisks){
  14. nDisks = QntityDisks;
  15. optimalSolution= Math.pow(2,nDisks)-1;
  16. var x = 0;
  17. var y = 558;
  18. var w = 330;
  19. moves="";
  20. startOfMove=Date.now();
  21. for (var i = 0; i < nDisks; i++) {
  22. var disk = new Disk(x,y,w,40,colors[i]);
  23. towerA.push(disk);
  24. x+=20; //moves to the right
  25. y-=42; //moves up, +1 to separate disks
  26. w-=40; //reduces disk width
  27. }
  28. drawScene();
  29. }
  30. class Disk{
  31. constructor(x,y,w,h,fill){
  32. this.x=x;
  33. this.y=y;
  34. this.w=w;
  35. this.h=h;
  36. this.fill=fill;
  37. }
  38. draw(){//(ctx, x, y, width, height, radius, fill, stroke)
  39. context.fillStyle = this.fill;
  40. context.strokeStyle = "black";
  41. roundRect(context, this.x, this.y, this.w, this.h, 20, 20, true);
  42. }
  43. clear(){
  44. context.clearRect(this.x, this.y, this.w, this.h);
  45. }
  46. }
  47. function reinicio (){
  48. while(towerA.length>0){
  49. towerA.pop();
  50. }
  51. while(towerB.length>0){
  52. towerB.pop();
  53. }
  54. while(towerC.length>0){
  55. towerC.pop();
  56. }
  57. nMovements=0;
  58. idF = " ";
  59. idT=" ";
  60. toMove=null;
  61. inicio();
  62. }
  63. function drawTowers (){
  64. context.beginPath();
  65. <!-- torre 1 -->
  66. context.fillStyle = 'black';
  67. context.fillRect(160, 260, 10, 340);//x, y, largura, altura
  68. <!--Base t1-->
  69. context.fillRect(0, 600, 330, 15);
  70. <!-- torre 2 -->
  71. context.fillRect(505, 260 ,10, 340);
  72. <!--Base t2-->
  73. context.fillRect(345, 600, 330, 15);
  74. <!-- torre 3 -->
  75. context.fillRect(850, 260, 10, 340);
  76. <!--Base t3-->
  77. context.fillRect(690, 600, 330, 15);
  78. }
  79. function drawDisks (){
  80. for(i=0; i<towerA.length; i++){
  81. towerA[i].draw();
  82. }
  83. for(i=0; i<towerB.length; i++){
  84. towerB[i].draw();
  85. }
  86. for(i=0; i<towerC.length; i++){
  87. towerC[i].draw();
  88. }
  89. }
  90. function drawScene (){
  91. context.clearRect(0, 0, canvas.width, canvas.height);
  92. drawTowers();
  93. drawDisks();
  94. drawFromTo();
  95. }
  96. function buttonClick (id){
  97. if(toMove == null && getTower(id).length>0){
  98. toMove = id;
  99. idF= String.fromCharCode(65+id);
  100. idT= " ";
  101. drawScene();
  102. } else if(toMove != null && toMove != id){
  103. idT = String.fromCharCode(65+id);
  104. moveDisk(toMove, id);
  105. toMove=null;
  106. }
  107. }
  108. function getTower (id){
  109. switch(id){
  110. case 0:
  111. return towerA;
  112. case 1:
  113. return towerB;
  114. case 2:
  115. return towerC;
  116. }
  117. }
  118. function drawFromTo (){
  119. context.font = "50px Arial";
  120. context.fillStyle = "black";
  121. context.fillText("Move from "+idF+" to "+idT, 50, 50);
  122. context.fillText("Movements: "+nMovements, 50, 100);
  123. }
  124. function moveDisk (origin, destiny){
  125. var originTower = getTower(origin), destinyTower = getTower(destiny), topDiskOrigin, topDiskDestiny;
  126. moveTime = Math.floor( (Date.now()- startOfMove) /1000);
  127. moves+="\n"+origin+" "+destiny+" "+moveTime;
  128. startOfMove = Date.now();//update start of movement
  129. console.clear();
  130. console.log(moves);
  131. nMovements++;
  132. topDiskOrigin = originTower[originTower.length-1];
  133. if(destinyTower.length>0){
  134. topDiskDestiny = destinyTower[destinyTower.length-1];
  135. if(topDiskOrigin.w<topDiskDestiny.w){
  136. topDiskOrigin.x += 345*(destiny-origin);
  137. topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
  138. originTower.pop();
  139. destinyTower.push(topDiskOrigin);
  140. drawScene();
  141. } else{
  142. nWrongMoves++;
  143. alert("Movimento Inválido");
  144. idF =" ";
  145. idT =" ";
  146. drawScene();
  147. }
  148. }else{
  149. topDiskOrigin.x += 345*(destiny-origin);
  150. topDiskOrigin.y += 42*(originTower.length-destinyTower.length-1);
  151. originTower.pop();
  152. destinyTower.push(topDiskOrigin);
  153. nMovements++;
  154. drawScene();
  155. }
  156. acertos=0;
  157. if(towerC.length == nDisks && nDisks!=0){
  158. acertos=1;
  159. totalTime= Date.now() - start;
  160. if(nMovements==optimalSolution){
  161. alert("You Won in the least amount of movements!!!\nCongratulations!!!");
  162. }else{
  163. alert("You Won!!!\nCongratulations!!");
  164. }
  165. }
  166. }
  167. function roundRect(ctx, x, y, width, height, radius, fill, stroke) {
  168. if (typeof stroke == "undefined" ) {
  169. stroke = true;
  170. }
  171. if (typeof radius === "undefined") {
  172. radius = 5;
  173. }
  174. ctx.beginPath();
  175. ctx.moveTo(x + radius, y);
  176. ctx.lineTo(x + width - radius, y);
  177. ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
  178. ctx.lineTo(x + width, y + height - radius);
  179. ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
  180. ctx.lineTo(x + radius, y + height);
  181. ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
  182. ctx.lineTo(x, y + radius);
  183. ctx.quadraticCurveTo(x, y, x + radius, y);
  184. ctx.closePath();
  185. if (stroke) {
  186. ctx.stroke();
  187. }
  188. if (fill) {
  189. ctx.fill();
  190. }
  191. }
  192. inicio(4);