home *** CD-ROM | disk | FTP | other *** search
- #newformat
- _title:Towers Of Hanoi
- _author:TJS
- _description:Towers of Hanoi in JavaScript. (Requires v1.1)
-
- _url:URL of images directory
-
- _insert-in:inbody
- <SCRIPT LANGUAGE="JavaScript1.1" TYPE="text/javascript">
- <!--
- // Towers of Hanoi
-
- // Preload images
- function preload() {
- this.length = preload.arguments.length;
- for (var i = 0; i < this.length; i++) {
- this[i] = new Image();
- this[i].src = "¤url_object$(1)¤" + preload.arguments[i];
- }
- }
-
- var pics = new preload("disk1.gif","disk2.gif",
- "disk3.gif","disk4.gif","disk5.gif","disk6.gif",
- "disk7.gif","post.gif", "disk1h.gif","disk2h.gif",
- "disk3h.gif","disk4h.gif","disk5h.gif","disk6h.gif",
- "disk7h.gif","posttop.gif");
-
- // Variables
- var selectedr = null;
- var selectedc = null;
- var maxposts = 3;
- var maxdisks = 7;
- var all_posts = 3;
- var startpost = 1;
- var endpost = (startpost-1 < 0 ? maxposts-1 : startpost-1);
- var disks = 7;
- var imgwidth = 160;
- var imgheight = 14;
- var game_is_over = false;
- var board = new Array(maxposts);
- board[0] = new Array(maxdisks + 1);
- board[1] = new Array(maxdisks + 1);
- board[2] = new Array(maxdisks + 1);
-
- function initboard(startpost, disks) {
- var len = board[0].length;
- selectedc = null;
- selectedr = null;
- game_is_over = false;
- endpost = (startpost-1 < 0 ? maxposts-1 : startpost-1);
-
- for (i = 0; i < len; i++) {
- board[0][i] = 0;
- board[1][i] = 0;
- board[2][i] = 0;
- }
- for (i = len-disks, j = 0; i < len; i++, j++) {
- board[startpost][i] = len - j - 1;
- }
- }
-
- function drawall() {
- for (j=0; j<board.length; j++) {
- for (i=0; i<board[j].length; i++) {
- draw(j,i, getName( board[j][i]));
- }
- }
- message("You may begin! Select a piece to move.");
- }
-
- // restart the game
- function restart(start) {
- startpost = start;
- disks = document.forms[0].disc.options[document.forms[0].disc.selectedIndex].text;
- initboard(startpost,disks);
- drawall();
- }
- // Initialize board
- initboard(startpost, disks);
-
-
- // Helper functions
- // generate the name of the image for .src
- function getName( num ) {
- if (num == 0) return "post.gif";
- return "disk" + num + ".gif";
- }
-
- // put message in message box
- function message(str) {
- if (!game_is_over)
- document.disp.message.value = str;
- }
-
- // is the post empty?
- function isempty(num) {
- for (i = 0; i < board[num].length; i++) {
- if ( board[num][i] != 0) return false;
- }
- return true;
- }
-
- // return the topmost disk of the post
- function topmost(num) {
- for (i = 0; i < board[num].length; i++) {
- if (board[num][i] != 0) return i;
- }
- return -1;
- }
-
- // is the click on a post element?
- function ispost(i,j) {
- return (board[j][i] == 0);
- }
-
- // is click on the top disk?
- function istopdisk(i,j) {
- return (board[j][i-1] == 0);
- }
-
- // draw the board
- function drawboard() {
- document.writeln("<CENTER><h2>The Towers of Hanoi</h2><p>");
- document.writeln("<table cellspacing=0 cellpadding=0 border=0>");
- document.write("<tr>");
- for (j = 0; j < board.length; j++) {
- document.write("<td>");
- document.write("<a href='javascript:clicked("+0+","+j+")'><img src='http://javascript.internet.com/img/hanoi/posttop.gif' border=0></a><br>");
- for (i=0; i< board[0].length; i++) {
- document.write("<a href='javascript:clicked("+i+","+j+")'>");
- document.write("<img src='http://javascript.internet.com/img/hanoi/" + getName(board[j][i]) + "' name='pos"+ j + i + "' border=0><br>");
- document.write("</a>");
- }
- document.writeln("</td>");
- }
- document.write("</tr></table>");
- document.write("<form name='disp'><textarea name='message' wrap=virtual rows=2 cols=40></textarea><br>" +
- "Disks: <select name=\"disc\" size=1><option>3<option>4<option>5<option>6<option selected>7</select><input "
- +"type=button value=\"Start the Game Over\" onClick=\"restart(startpost);\"><input "
- +"type=button value=\"Solve It!\" onClick=\"restart(startpost);setTimeout('hanoi(disks,startpost,endpost)',400)\"></form>");
- }
-
- // draw image "name" at position "x,y"
- function draw(x,y,name) {
- document.images["pos"+x+""+y].src = "http://javascript.internet.com/img/hanoi/" + name;
- }
-
- // process the click
- function clicked(i,j) {
- document.forms[0].message.focus(); // get rid of annoying outline in MSIE
-
- if (game_is_over) restart(startpost = endpost);
- if (!isselection() && ispost(i,j)) { message("Select a piece to move."); return; }
- if (!ispost(i,j)) { toggle(j); return; };
- if (ispost(i,j) && selectedc == j) { message("Move the piece to a different post."); return; }
- if (!legalmove(j)) { message("That is not a legal move. Try again."); return; }
- move(j); return;
- }
-
- // is the move legal?
- function legalmove(j) {
- // is legal if empty
- if (isempty(j)) return true;
- return (board[j][topmost(j)] < board[selectedc][selectedr]);
- }
-
- // is there a piece selected?
- function isselection() {
- return selectedc != null;
- }
-
- // select/deselect the topmost piece on the post
- function toggle( num ) {
- // find the topmost piece
- var toppos = topmost(num);
-
- // toggle off if same column
- if (selectedc == num && selectedr == toppos) {
- selectedc = null; selectedr = null;
- draw(num,toppos,"disk" + board[num][toppos] + ".gif");
- message("Select a piece to move.");
- return;
- }
- // delselect the current selection
- if (isselection()) {
- draw(selectedc,selectedr,"disk" + board[selectedc][selectedr] + ".gif");
- }
- // make new selection
- selectedc = num; selectedr = toppos;
- draw(num,toppos,"disk" + board[num][toppos] + "h.gif");
- message("Click on the post to which you want to move the disk.");
- }
-
- // move the disk to this post
- function move( num ) {
- // find the topmost piece
- var toppos = (!isempty(num) ? topmost(num) : board[num].length);
- board[num][toppos-1] = board[selectedc][selectedr];
- board[selectedc][selectedr] = 0;
- draw(selectedc,selectedr,"post.gif");
- draw(num,toppos-1,"disk" + board[num][toppos-1] + ".gif");
- selectedc = null; selectedr = null;
- message("Select a piece to move.");
- game_over();
- }
-
- // solve the puzzle
- function hanoi(no_of_disks, start_post, goal_post) {
- if (no_of_disks > 0) {
- var free_post = all_posts - start_post - goal_post;
- hanoi (no_of_disks - 1, start_post, free_post);
- toggle(start_post);
- delay(1000);
- move(goal_post);
- delay(1000);
- hanoi (no_of_disks - 1 , free_post, goal_post);
- }
- }
-
- // slow things down
- function delay(num) {
- for (i = 0; i < num; i++) ;
- }
-
- // returns true of the game is over
- function game_over() {
- var filledpost = null;
- var val = 0;
- for (k = 0; k < board.length; k++) {
- val += ( isempty(k) ? 1 : 0 );
- if (!isempty(k)) filledpost = k;
- }
-
- if (val == 2 && isempty(startpost)) {
- message("You won!");
- game_is_over = true;
- endpost = filledpost;
- }
- return game_is_over;
- }
-
-
- drawboard();
- message("You may begin! Select a piece to move.");
-
- // -->
- </SCRIPT>
- _end-insert: