»
EnglishFrenchVietnamese

Print - Tower of Hanoi - JavaScriptBank.com

Full version: jsB@nk » Game » Puzzle » Tower of Hanoi
URL: http://www.javascriptbank.com/tower-of-hanoi.html

Tower of Hanoi © JavaScriptBank.comThe Tower of Hanoi is a classic puzzle game where you try to move disks from the left-most pole to the right using the least amount of moves. This DHTML script features full drag-and-drop interface, and 'auto solve' ability.

Full version: jsB@nk » Game » Puzzle » Tower of Hanoi
URL: http://www.javascriptbank.com/tower-of-hanoi.html



JavaScript
<script language="javascript"><!--/************************************************ Tower of Hanoi- by Glenn G. Vergara***********************************************/    var delay = 200; //in milliseconds/***********************************//* Don't change something below!!! *//***********************************/    vardrag=false;    var objDisk=null;    var x = 0;    var y = 0;    var disksOnTower1 = new Array(null,null,null,null,null,null,null,null);    var disksOnTower2 = new Array(null,null,null,null,null,null,null,null);    var disksOnTower3 = new Array(null,null,null,null,null,null,null,null);    var disksOnTowers = new Array(disksOnTower1,disksOnTower2,disksOnTower3);    var offsetleft = 30;    var offsettop = 30;    var offsettower = 20;    var offsethoriz = 30;    var basetop = 0;    var diskheight = 0;    var midhoriztower = 0;    var indexTo=1;    var indexFr=1;    var movectr=0;    var gameOver=false;    var prevIndex=0;    var zindex = 0;    var currTower=1;    var prevTower=1;    var demo=false;    var arrFr = new Array(255);    var arrTo = new Array(255);    var idx = 0;    var pos = 0;    var t=null;    var stop=false;        function init(){        if (document.all){    document.all.footnote.innerHTML='~ Script featured on <a href="http://www.michieru.cjb.net">Michieru!</a> ~';            document.hanoi.diskno.options.selectedIndex = 0;            drawTowers();            drawDisks(parseInt(document.hanoi.diskno.options[document.hanoi.diskno.options.selectedIndex].text));        }        else {    document.write("Sorry, you can play this game using Microsoft Internet Explorer only.");    document.close();    alert("Sorry, you can play this game using Microsoft Internet Explorer only.");}    }        function initVars(){        for (var i=0;i<disksOnTower1.length;i++){            disksOnTower1[i]=null;            disksOnTower2[i]=null;            disksOnTower3[i]=null;        }        drag = false;        indexTo = 1;        indexFr = 1;        movectr = 0;        zindex = 0;        idx = 0;        pos = 0;        t = null;        gameOver=false;        stop=false;        demo=false;        document.hanoi.btnUndo.disabled=true;    }        function drawTowers(){        var titlewidth = parseInt(document.all["title"].style.width);        var titleheight = parseInt(document.all["title"].style.height);        var towerwidth = parseInt(document.all["tower1"].style.width);        var towerheight = parseInt(document.all["tower1"].style.height);        var settingswidth = parseInt(document.all["settings"].style.width);        midhoriztower = parseInt(document.all["horiztower1"].style.width)/2;        diskheight = parseInt(document.all["disk1"].style.height);                document.all["title"].style.left=offsetleft+(1.5*towerwidth)+offsettower-(titlewidth/2);        document.all["title"].style.top=offsettop;        document.all["tower1"].style.left=offsetleft;        document.all["tower1"].style.top=offsettop+titleheight+offsethoriz;        document.all["tower2"].style.left=offsetleft+towerwidth+offsettower;        document.all["tower2"].style.top=offsettop+titleheight+offsethoriz;        document.all["tower3"].style.left=offsetleft+(towerwidth+offsettower)*2;        document.all["tower3"].style.top=offsettop+titleheight+offsethoriz;        document.all["settings"].style.left=offsetleft+(1.5*towerwidth)+offsettower-(settingswidth/2);        document.all["settings"].style.top=parseInt(document.all["tower1"].style.top)+towerheight+offsethoriz;    }        function drawDisks(disknum){        var disktop = parseInt(document.all["tower1"].style.top)+parseInt(document.all["horiztower1"].style.top);        var lefttower1 = parseInt(document.all["tower1"].style.left);        basetop = disktop;        for (var i=disksOnTower1.length;i>=1;i--){    document.all["disk"+i].style.zIndex=++zindex;            if (i<=disknum){                document.all["disk"+i].style.left=lefttower1+midhoriztower-parseInt(document.all["disk"+i].style.width)/2;                document.all["disk"+i].style.top=disktop-diskheight*2-4;                disktop = parseInt(document.all["disk"+i].style.top);                disksOnTowers[0][i-1]=document.all["disk"+i];            }            else {                document.all["disk"+i].style.left=-250;                document.all["disk"+i].style.top=-250;                disksOnTowers[0][i-1]=null;            }        }        document.hanoi.minmove.value=document.hanoi.diskno.options[document.hanoi.diskno.options.selectedIndex].value;        document.hanoi.yourmove.value=0;    }        function newGame(obj){document.all.footnote.style.top=445 //reposition div        if (movectr>0 && !gameOver && !stop){            if (confirm("Current game will be aborted, would you like to continue?")){                initVars();                drawDisks(parseInt(obj.options[obj.options.selectedIndex].text));            }            else document.hanoi.diskno.options.selectedIndex=prevIndex;        }        else {            initVars();            drawDisks(parseInt(obj.options[obj.options.selectedIndex].text));        }    }        function initializeDrag(disk){        if (stop){            alert("You cannot continue solving the puzzle after clicking the 'Stop' button.\nClick 'Restart' button or select no. of disks to continue playing.");            return;        }        indexFr = indexTo;        if (disk.id!=disksOnTowers[indexFr-1][0].id || gameOver || demo) return;        objDisk=disk;        x=event.clientX;        y=event.clientY;        tempx=disk.style.posLeft;        tempy=disk.style.posTop;        document.onmousemove=dragDisk;    }        function dragDisk(){        zindex++;        drag=true;        var posX = tempx+event.clientX-x;        var posY = tempy+event.clientY-y;        var objTower1 = document.all["tower1"];        var objTower2 = document.all["tower2"];        var objTower3 = document.all["tower3"];        objDisk.style.zIndex=zindex;        objDisk.style.posLeft=posX;        objDisk.style.posTop=posY;        if (event.clientX>=document.body.clientWidth || event.clientY>document.body.clientHeight){            indexTo=indexFr;            dropDisk(objDisk);        }        else if (            (parseInt(objTower3.style.left)<=posX) &&             (parseInt(objTower3.style.left)+parseInt(objTower3.style.width)>=posX) &&             (parseInt(objTower3.style.top)+parseInt(objTower3.style.height)>posY)            ){            indexTo=3;        }        else if ((parseInt(objTower2.style.left)<=posX) && (parseInt(objTower2.style.left)+parseInt(objTower3.style.width)>=posX)){            indexTo=2;        }        else if ((parseInt(objTower1.style.left)<=posX) && (parseInt(objTower1.style.left)+parseInt(objTower1.style.width)>=posX)){            indexTo=1;        }        else indexTo = indexFr;        return false;    }    function dropDisk(disk){        document.onmousemove=new Function("return false");        if (!drag) return;        var gameStatus=false;        var topDisk = disksOnTowers[indexTo-1][0];        if (indexFr==indexTo){            getNewTop(indexFr,null);            pushDisk(disk,indexFr);//put disk back to original tower            getNewTop(indexFr,disk);        }        else if (topDisk==null) {            pushDisk(disk,indexTo);            getNewTop(indexFr,null);            getNewTop(indexTo,disk);            movectr++;            currTower=indexTo;            prevTower=indexFr;            document.hanoi.btnUndo.disabled=false;        }        else if (parseInt(disk.style.width)<parseInt(topDisk.style.width)){            pushDisk(disk,indexTo);            getNewTop(indexFr,null);            getNewTop(indexTo,disk);            movectr++;            currTower=indexTo;            prevTower=indexFr;            if (indexTo==3) gameStatus=checkStatus();            document.hanoi.btnUndo.disabled=false;        }        else {            getNewTop(indexFr,null);            pushDisk(disk,indexFr);//put disk back to original tower            getNewTop(indexFr,disk);        }              drag=false;        document.hanoi.yourmove.value=movectr;        if (gameStatus) {            document.hanoi.btnUndo.disabled=true;            minmove = parseInt(document.hanoi.minmove.value);            if (movectr==minmove) msg="\nCongratulations! You got it in "+minmove+" moves."            else if (movectr>minmove) msg="\nYou can do better than that."            else msg="";            alert("Game Over !!!"+msg);            gameOver=true;        }        return;    }              function checkStatus(){        var gameStat = false;        var disks=0;        for (var i=0;i<disksOnTower3.length;i++){            if (disksOnTowers[2][i]!=null) disks++;        }        if (disks==parseInt(document.hanoi.diskno.options[document.hanoi.diskno.options.selectedIndex].text)) gameStat=true;        return gameStat;    }    function pushDisk(disk,index){        var diskWidth = parseInt(disk.style.width);        var towerLeft = parseInt(document.all["tower"+index].style.left);        var topDisk = disksOnTowers[index-1][0];        if (topDisk!=null){            topDiskWidth = parseInt(topDisk.style.width);            topDiskTop = parseInt(topDisk.style.top);            disk.style.left=towerLeft+midhoriztower-diskWidth/2;            disk.style.top=topDiskTop-diskheight*2-4;        }        else {            disk.style.left=towerLeft+midhoriztower-diskWidth/2;            disk.style.top=basetop-diskheight*2-4;        }    }       function getNewTop(index,disk){        if (disk==null){//pop            for (var i=0;i<disksOnTower1.length-1;i++){                disksOnTowers[index-1][i]=disksOnTowers[index-1][i+1];            }            disksOnTowers[index-1][disksOnTower1.length-1]=null;        }        else {//push            for (var i=disksOnTower1.length-1;i>=1;i--){                disksOnTowers[index-1][i]=disksOnTowers[index-1][i-1];            }            disksOnTowers[index-1][0]=disk;        }    }        function solve(btn){        if (btn.value=="Solve"){            if (movectr>0 && !gameOver && !stop)                if (!confirm("Current game will be aborted, would you like to continue?")) return;            btn.value="Stop";            initVars();            stop=false;            demo=true;            frm=document.hanoi;            frm.btnIns.disabled=true;            frm.btnRes.disabled=true;            frm.btnUndo.disabled=true;            disknum = parseInt(frm.diskno.options[frm.diskno.options.selectedIndex].text);            drawDisks(disknum);            getMoves(0, 2, 1, disknum);             t=window.setTimeout("moveDisk()",delay);        }        else {            if (t) {                window.clearTimeout(t);                btn.value="Solve";                frm.btnIns.disabled=false;                frm.btnRes.disabled=false;                t = null;                stop=true;                demo=false;            }                    }    }        function moveDisk(){        frm = document.hanoi;        disk=disksOnTowers[arrFr[pos]][0];        pushDisk(disk,arrTo[pos]+1);        getNewTop(arrFr[pos]+1,null);        getNewTop(arrTo[pos]+1,disk);        movectr++;        frm.yourmove.value=movectr;        pos++;        if (movectr<parseInt(frm.minmove.value)) t=window.setTimeout("moveDisk()",delay);        else {            alert("Can you do that in "+movectr+" moves?");            gameOver=true;            stop=false;            frm.btnSolve.value="Solve";            frm.btnIns.disabled=false;            frm.btnRes.disabled=false;        }    }    function getMoves(from,to,empty,numDisk){        if (numDisk > 1) {            getMoves(from, empty, to, numDisk - 1);            arrFr[idx] = from;            arrTo[idx++] = to;            getMoves(empty, to, from, numDisk - 1);        }        else {            arrFr[idx] = from;            arrTo[idx++] = to;        }    }        function unDo(btn){        disk=disksOnTowers[currTower-1][0];        pushDisk(disk,prevTower);        getNewTop(currTower,null);        getNewTop(prevTower,disk);        movectr--;        document.hanoi.yourmove.value=movectr;        btn.disabled=true;    }        function displayIns(){        var msg="Try to move all the disks from TOWER 1 to TOWER 3.\n";        msg+="You may only move one disk at a time.\n";        msg+="You must never allow a bigger disk to go on top of a smaller disk.";        alert(msg);    } //--></script><noscript>You cannot play this game with JavaScript disabled or non-JavaScript aware browsers.</noscript><!--    This script downloaded from www.JavaScriptBank.com    Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->


HTML
<body onload="init();" onselectstart="return false" oncontextmenu="return false"><form name="hanoi"><div id="title" style="width:160px;height:20px;display: none;"></div><div id="tower1" style="position:absolute;visibility:visible;left:-250;top:-250;width:200px;height:200px" onmousemove="indexTo=1"><div id="verttower1"style="position:absolute;visibility:visible;left:99;top:10;width:3px;height:170px;border:1px solid black;background:black"></div><div id="horiztower1" style="position:absolute;visibility:visible;left:0;top:180;width:200px;height:2px;border:1px solid black;font-size:1px;background:black"></div><div style="position:absolute;visibility:visible;left:77;top:184;font:bold 10px Tahoma;">TOWER 1</div></div><div id="tower2" style="position:absolute;visibility:visible;left:-250;top:-250;width:200px;height:200px;" onmousemove="indexTo=2"><div id="verttower2" style="position:absolute;visibility:visible;left:99;top:10;width:3px;height:170px;border:1px solid black;background:black"></div><div id="horiztower2" style="position:absolute;visibility:visible;left:0;top:180;width:200px;height:2px;border:1px solid black;font-size:1px;background:black"></div><div style="position:absolute;visibility:visible;left:77;top:184;font:bold 10px Tahoma;">TOWER 2</div></div><div id="tower3" style="position:absolute;visibility:visible;left:-250;top:-250;width:200px;height:200px;" onmousemove="indexTo=3"><div id="verttower3" style="position:absolute;visibility:visible;left:99;top:10;width:3px;height:170px;border:1px solid black;background:black;"></div><div id="horiztower3" style="position:absolute;visibility:visible;left:0;top:180;width:200px;height:2px;border:1px solid black;font-size:1px;background:black"></div><div style="position:absolute;visibility:visible;left:77;top:184;font:bold 10px Tahoma;">TOWER 3</div></div><div id="disk1" style="position:absolute;visibility:visible;left:-250;top:-250;width:50px;height:8px;border:1px solid black;background:pink" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 1"></div><div id="disk2" style="position:absolute;visibility:visible;left:-250;top:-250;width:70px;height:8px;border:1px solid black;background:violet" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 2"></div><div id="disk3" style="position:absolute;visibility:visible;left:-250;top:-250;width:90px;height:8px;border:1px solid black;background:indigo" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 3"></div><div id="disk4" style="position:absolute;visibility:visible;left:-250;top:-250;width:110px;height:8px;border:1px solid black;background:blue" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 4"></div><div id="disk5" style="position:absolute;visibility:visible;left:-250;top:-250;width:130px;height:8px;border:1px solid black;background:green" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 5"></div><div id="disk6" style="position:absolute;visibility:visible;left:-250;top:-250;width:150px;height:8px;border:1px solid black;background:yellow" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 6"></div><div id="disk7" style="position:absolute;visibility:visible;left:-250;top:-250;width:170px;height:8px;border:1px solid black;background:orange" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 7"></div><div id="disk8" style="position:absolute;visibility:visible;left:-250;top:-250;width:190px;height:8px;border:1px solid black;background:red" onmousedown="initializeDrag(this)" onmouseup="dropDisk(this)" title="Disk 8"></div><div id="settings" style="position:absolute;visibility:visible;left:-250;top:-250;width:260px;"><table><tr><td><font face="Verdana" size="2"><b>No. of disks</b></font></td><td><select name="diskno" style="width:40px" onchange="newGame(this)" onclick="prevIndex=this.options.selectedIndex"><option value="7" selected>3</option><option value="15">4</option><option value="31">5</option><option value="63">6</option><option value="127">7</option><option value="255">8</option></select></td></tr><tr><td><font face="Verdana" size="2"><b>Minimum no. of moves&nbsp;&nbsp;</b></font></td><td><input name="minmove" style="border:none" size="3" value="255" readonly></td></tr><tr><td><font face="Verdana" size="2"><b>Your no. of moves</b></font></td><td><input name="yourmove" style="border:none" size="3" value="0" readonly></td></tr><tr><td colspan="2" align="center"><input type="button" name="btnIns" value="Instructions" onclick="displayIns()" style="font:normal 12px Tahoma,Verdana"><input type="button" name="btnRes" value="Restart" onclick="newGame(document.hanoi.diskno)" style="font:normal 12px Tahoma,Verdana"><input type="button" name="btnUndo" value="Undo" onclick="unDo(this)" style="font:normal 12px Tahoma,Verdana" disabled><input type="button" name="btnSolve" value="Solve" onclick="solve(this)" style="font:normal 12px Tahoma,Verdana"></td></tr></table></div></form><div id="footnote" style="position:absolute;left:228;top:445;font:bold 12px Verdana; display: none;">~ Script featured on <a href="http://www.michieru.cjb.net">Michieru!</a> ~</div></body><!--    This script downloaded from www.JavaScriptBank.com    Come to view and download over 2000+ free javascript at www.JavaScriptBank.com-->