Hanoi Towers Animator..

by refhat

HTML

<div class="container">
    <div class="peg left"></div>
    <div class="peg middle"></div>
    <div class="peg right"></div>
    
    <div data-size="5" class="disc black"></div>
    <div data-size="4" class="disc yellow"></div>
    <div data-size="3" class="disc blue"></div>
    <div data-size="2" class="disc green"></div>
    <div data-size="1" class="disc red"></div>
</div>

CSS

.disc{
    position:absolute;
    height:10px;
    border:1px solid #ccc;
    z-index:10;
}
.container{position:relative;margin:20px;height:120px;}
.peg{z-index:5;background-color:brown;width:10px;height:100px;position:absolute;bottom:0;}
.left{left:50px;}
.middle{left:180px;}
.right{left:310px;}

.red{background-color:red;width:30px;bottom:48px;left:40px;}
.green{background-color:green;width:50px;bottom:36px;left:30px;}
.blue{background-color:blue;width:70px;bottom:24px;left:20px;}
.yellow{background-color:yellow;width:90px;bottom:12px;left:10px;}
.black{background-color:black;width:110px;bottom:0;left:0px;}

JavaScript

var q = $({});
var pegs = {};
var discHeight = 12;
var pegHeight = 100;
// initialize start
$('.peg').each(function(idx){
    var peg = $(this);
    var pegid = 'peg' + (idx+1);
    pegs[pegid] = {};
    pegs[pegid].discs = [];
    pegs[pegid].center = peg.position().left + (peg.width()/2);
});
$('.disc').each(function(){
    pegs.peg1.discs.push( $(this) );
});
// initialize end


function moveToQueue(peg_from, peg_to, undefined) {
    q.queue(function(next) {
        //check if the move is valid
        var frompeg = pegs['peg'+peg_from],
            topeg = pegs['peg'+peg_to],
            topFrom = frompeg.discs.pop(),
            topTo = topeg.discs.pop();
        if (!topFrom) {
             var err = 'failed at move(' + peg_from + ', ' + peg_to + ')\nFROM is empty.';
             alert(err);
            
            if (topTo) topeg.discs.push( topTo );
            return false;
        }
        if (!(topTo === undefined || topTo.data('size') > topFrom.data('size'))){
            if (topTo) topeg.discs.push( topTo );
            if (topFrom) frompeg.discs.push( topFrom );
            var err = 'failed at move(' + peg_from + ', ' +peg_to + ')\nFROM is bigger than TO';
            alert(err);
            return false; 
        }
        
        if (topTo) topeg.discs.push( topTo );
        topeg.discs.push( topFrom );
        
        var new_left = topeg.center - (topFrom.width()/2);
        
        topFrom
            .animate({bottom: pegHeight},200) /*out of peg*/
            .animate({left: new_left, bottom: (topeg.discs.length-1)*discHeight}, 500, next);/* to new position*/
    });
}





// usage with wrong move
/*
moveToQueue(1, 3);
moveToQueue(1, 2);
moveToQueue(3, 2);
moveToQueue(3, 2);
*/


// usage with solution
moveToQueue(1, 3);
moveToQueue(1, 2);
moveToQueue(3, 2);
 moveToQueue(1, 3);
 moveToQueue(2, 1);
 moveToQueue(2, 3);
 moveToQueue(1, 3);
 moveToQueue(1, 2);
  moveToQueue(3, 2);
  moveToQueue(3, 1);
  moveToQueue(2, 1);
  moveToQueue(3,...