Hanoi Tower
by Alex Ou
HTML
<div id='w'>
<div class='r a'><span>1</span></div>
<div class='r b'><span>2</span></div>
<div class='r c'><span>3</span></div>
</div>
CSS
#w{
position: relative;
height: 300px;
width: 100%;
border-bottom: 10px solid gray;
}
span{
position: absolute;
bottom: -30px;
}
.r {
position: absolute;
bottom: 0;
height:130px;
width: 6px;
background: gray;
}
.a {
transition: 1s;
left: 20%;
}
.b {
transition: 1s;
left: 50%;
}
.c {
transition: 1s;
left: 80%;
}
.disk {
border-radius: 6px;
position: absolute;
bottom: 0;
height: 20px;
transform: translateX(-45%);
}
.disk.size0{
width: 80px;
}
.disk.size1{
width: 70px;
}
.disk.size2{
width: 60px;
}
.disk.size3{
width: 50px;
}
.disk.size4{
width: 40px;
}
.disk.size5{
width: 30px;
}
.disk.l0{
bottom: 0;
}
.disk.l1{
bottom: 20px;
}
.disk.l2{
bottom: 40px;
}
.disk.l3{
bottom: 60px;
}
.disk.l4{
bottom: 80px;
}
.disk.l5{
bottom: 100px;
}
JavaScript
const q = (c) => document.querySelector(c);
const w = q('#w');
function createDisk(color) {
const disk = document.createElement('div');
disk.classList.add('disk');
disk.classList.add(color);
disk.style.background = color;
return disk;
}
const disks = [
'green',
'yellow',
'blue',
'purple',
'red'
];
const rods = [
'a', 'b', 'c'
];
function renderDisks(diskMap) {
Object.keys(diskMap).forEach(r => {
const disks = diskMap[r];
disks.forEach((color, index) => {
const disk = createDisk(color);
disk.classList.add(r);
disk.classList.add('size'+index);
disk.classList.add('l'+index);
w.appendChild(disk);
})
})
}
const diskMap = {
'a': [...disks],
'b': [],
'c': []
};
renderDisks(diskMap);
function moveDisk(color, onRod, toRod) {
var dfd = jQuery.Deferred();
console.log(`${color} disk ${onRod} --> ${toRod}`);
const disk = q('.'+color);
disk.classList.remove(`l${diskMap[onRod].length - 1}`);
diskMap[onRod].splice(diskMap[onRod].length - 1, 1);
diskMap[toRod].push(color);
disk.classList.remove(onRod);
disk.classList.add(toRod);
console.log(`l${diskMap[toRod].length - 1}`);
disk.classList.add(`l${diskMap[toRod].length - 1}`);
setTimeout(() => {
dfd.resolve();
}, 1000)
return dfd.promise();
}
function hanoi(disks, onRod, viaRod, toRod) {
var dfd = jQuery.Deferred();
if (disks.length === 0) {
dfd.resolve();
return dfd.promise();
}
return hanoi(disks.slice(1), onRod, toRod, viaRod).then(() => {
return moveDisk(disks[0], onRod, toRod);
}).then(() => {
return hanoi(disks.slice(1), viaRod, onRod, toRod);
});
}
setTimeout(() => {
hanoi( [...disks], ...rods)
}, 1000);