home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / Internet / jvscript116beta / JvScript / !JvScript / Resources / Scripts / Games / 5 < prev    next >
Encoding:
Text File  |  1999-09-15  |  6.7 KB  |  248 lines

  1. #newformat
  2. _title:Towers Of Hanoi
  3. _author:TJS
  4. _description:Towers of Hanoi in JavaScript. (Requires v1.1)
  5.  
  6. _url:URL of images directory
  7.  
  8. _insert-in:inbody
  9. <SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
  10. <!--
  11. // Towers of Hanoi
  12.  
  13. // Preload images
  14. function preload() {
  15.   this.length = preload.arguments.length;
  16.   for (var i = 0; i < this.length; i++) {
  17.     this[i] = new Image();
  18.     this[i].src = "¤url_object$(1)¤" + preload.arguments[i];
  19.   }
  20. }
  21.  
  22. var pics = new preload("disk1.gif","disk2.gif",
  23.   "disk3.gif","disk4.gif","disk5.gif","disk6.gif",
  24.   "disk7.gif","post.gif", "disk1h.gif","disk2h.gif",
  25.   "disk3h.gif","disk4h.gif","disk5h.gif","disk6h.gif",
  26.   "disk7h.gif","posttop.gif");
  27.  
  28. // Variables
  29. var selectedr = null;
  30. var selectedc = null;
  31. var maxposts = 3;
  32. var maxdisks = 7;
  33. var all_posts = 3;
  34. var startpost = 1;
  35. var endpost = (startpost-1 < 0 ? maxposts-1 : startpost-1);
  36. var disks = 7;
  37. var imgwidth = 160;
  38. var imgheight = 14;
  39. var game_is_over = false;
  40. var board = new Array(maxposts);
  41. board[0] = new Array(maxdisks + 1);
  42. board[1] = new Array(maxdisks + 1);
  43. board[2] = new Array(maxdisks + 1);
  44.  
  45. function initboard(startpost, disks) {
  46.   var len = board[0].length;
  47.   selectedc = null;
  48.   selectedr = null;
  49.   game_is_over = false;
  50.   endpost = (startpost-1 < 0 ? maxposts-1 : startpost-1);
  51.  
  52.   for (i = 0; i < len; i++) {
  53.     board[0][i] = 0;
  54.     board[1][i] = 0;
  55.     board[2][i] = 0;
  56.   }
  57.   for (i = len-disks, j = 0; i < len; i++, j++) {
  58.     board[startpost][i] = len - j - 1;
  59.   }
  60. }
  61.  
  62. function drawall() {
  63.   for (j=0; j<board.length; j++) {
  64.     for (i=0; i<board[j].length; i++) {
  65.       draw(j,i, getName( board[j][i]));
  66.     }
  67.   }
  68.   message("You may begin! Select a piece to move.");
  69. }
  70.  
  71. // restart the game
  72. function restart(start) {
  73.   startpost = start;
  74.   disks = document.forms[0].disc.options[document.forms[0].disc.selectedIndex].text;
  75.   initboard(startpost,disks);
  76.   drawall();
  77. }
  78. // Initialize board
  79. initboard(startpost, disks);
  80.  
  81.  
  82. // Helper functions
  83. // generate the name of the image for .src
  84. function getName( num ) {
  85.   if (num == 0) return "post.gif";
  86.   return "disk" + num + ".gif";
  87. }
  88.  
  89. // put message in message box
  90. function message(str) {
  91.  if (!game_is_over)
  92.   document.disp.message.value = str;
  93. }
  94.  
  95. // is the post empty?
  96. function isempty(num) {
  97.   for (i = 0; i < board[num].length; i++) {
  98.     if ( board[num][i] != 0) return false;
  99.   }
  100.   return true;
  101. }
  102.  
  103. // return the topmost disk of the post
  104. function topmost(num) {
  105.   for (i = 0; i < board[num].length; i++) {
  106.     if (board[num][i] != 0) return  i;
  107.   }
  108.   return -1; 
  109. }
  110.  
  111. // is the click on a post element?
  112. function ispost(i,j) {
  113.   return (board[j][i] == 0);
  114. }
  115.  
  116. // is click on the top disk?
  117. function istopdisk(i,j) {
  118.   return (board[j][i-1] == 0);
  119. }
  120.  
  121. // draw the board
  122. function drawboard() {
  123.   document.writeln("<CENTER><h2>The Towers of Hanoi</h2><p>");
  124.   document.writeln("<table cellspacing=0 cellpadding=0 border=0>");
  125.   document.write("<tr>");
  126.   for (j = 0; j < board.length; j++) {
  127.     document.write("<td>");
  128.     document.write("<a href='javascript:clicked("+0+","+j+")'><img src='http://javascript.internet.com/img/hanoi/posttop.gif' border=0></a><br>");
  129.     for (i=0; i< board[0].length; i++) {
  130.       document.write("<a href='javascript:clicked("+i+","+j+")'>");
  131.       document.write("<img src='http://javascript.internet.com/img/hanoi/" + getName(board[j][i]) + "' name='pos"+ j + i + "' border=0><br>");
  132.       document.write("</a>");
  133.     }
  134.     document.writeln("</td>");
  135.   }
  136.   document.write("</tr></table>");
  137.   document.write("<form name='disp'><textarea name='message' wrap=virtual rows=2 cols=40></textarea><br>" + 
  138.     "Disks: <select name=\"disc\" size=1><option>3<option>4<option>5<option>6<option selected>7</select><input "
  139.     +"type=button value=\"Start the Game Over\" onClick=\"restart(startpost);\"><input "
  140.     +"type=button value=\"Solve It!\" onClick=\"restart(startpost);setTimeout('hanoi(disks,startpost,endpost)',400)\"></form>");
  141. }
  142.  
  143. // draw image "name" at position "x,y"
  144. function draw(x,y,name) {
  145.   document.images["pos"+x+""+y].src = "http://javascript.internet.com/img/hanoi/" + name;
  146. }
  147.  
  148. // process the click
  149. function clicked(i,j) {
  150.   document.forms[0].message.focus(); // get rid of annoying outline in MSIE
  151.  
  152.   if (game_is_over)  restart(startpost = endpost);
  153.   if (!isselection() && ispost(i,j)) { message("Select a piece to move."); return; }
  154.   if (!ispost(i,j)) { toggle(j); return; };
  155.   if (ispost(i,j) && selectedc == j) { message("Move the piece to a different post."); return; }
  156.   if (!legalmove(j)) { message("That is not a legal move. Try again."); return; }
  157.   move(j); return;
  158. }
  159.  
  160. // is the move legal?
  161. function legalmove(j) {
  162.   // is legal if empty
  163.   if (isempty(j)) return true;
  164.   return (board[j][topmost(j)] < board[selectedc][selectedr]);
  165. }
  166.  
  167. // is there a piece selected?
  168. function isselection() {
  169.   return selectedc != null;
  170. }
  171.  
  172. // select/deselect the topmost piece on the post
  173. function toggle( num ) {
  174.   // find the topmost piece
  175.   var toppos = topmost(num);
  176.  
  177.   // toggle off if same column
  178.   if (selectedc == num && selectedr == toppos) {
  179.     selectedc = null; selectedr = null;
  180.     draw(num,toppos,"disk" + board[num][toppos] + ".gif");
  181.     message("Select a piece to move.");
  182.     return;
  183.   }
  184.   // delselect the current selection
  185.   if (isselection()) {
  186.     draw(selectedc,selectedr,"disk" + board[selectedc][selectedr] + ".gif");
  187.   }
  188.   // make new selection
  189.   selectedc = num; selectedr = toppos;
  190.   draw(num,toppos,"disk" + board[num][toppos] + "h.gif");
  191.   message("Click on the post to which you want to move the disk.");
  192. }
  193.  
  194. // move the disk to this post
  195. function move( num ) {
  196.   // find the topmost piece
  197.   var toppos = (!isempty(num) ? topmost(num) : board[num].length);
  198.   board[num][toppos-1] = board[selectedc][selectedr];
  199.   board[selectedc][selectedr] = 0;
  200.   draw(selectedc,selectedr,"post.gif");
  201.   draw(num,toppos-1,"disk" + board[num][toppos-1] + ".gif");
  202.   selectedc = null; selectedr = null;
  203.   message("Select a piece to move.");
  204.   game_over();
  205. }
  206.  
  207. // solve the puzzle
  208. function hanoi(no_of_disks, start_post, goal_post) {
  209.   if (no_of_disks > 0) {
  210.     var free_post = all_posts - start_post - goal_post;
  211.     hanoi (no_of_disks - 1, start_post, free_post);
  212.     toggle(start_post);
  213.     delay(1000);
  214.     move(goal_post);
  215.     delay(1000);
  216.     hanoi (no_of_disks - 1 , free_post, goal_post);
  217.   }
  218. }
  219.  
  220. // slow things down
  221. function delay(num) {
  222.   for (i = 0; i < num; i++) ;
  223. }
  224.  
  225. // returns true of the game is over
  226. function game_over() { 
  227.   var filledpost = null;
  228.   var val = 0;
  229.   for (k = 0; k < board.length; k++)  { 
  230.     val += ( isempty(k) ? 1 : 0 ); 
  231.     if (!isempty(k)) filledpost = k;
  232.   }
  233.  
  234.   if (val == 2 && isempty(startpost)) {
  235.     message("You won!");
  236.     game_is_over = true;
  237.     endpost = filledpost;
  238.   }
  239.   return game_is_over;
  240. }
  241.  
  242.  
  243. drawboard();
  244. message("You may begin! Select a piece to move.");
  245.  
  246. // -->
  247. </SCRIPT>
  248. _end-insert: