汉诺塔游戏

近期一直在玩的游戏是汉诺塔,我倒是觉得这个游戏挺解乏的,但是我女票子却不喜欢,我让她玩 5 层,她讨价还价成 4 层,我再坚持一次,她就说不玩了不玩了,那就陪她玩 4 层咯。下面,我们来看看 js 制作的简单动画展示,这个游戏应该怎么玩。

汉诺塔的思路是递归,用来学习编程思想非常有帮助。我们说一般递归可以解决的问题,也可以用动态规划的思路去做,这个我还没有实现。

相传如果能完成 64 个叠加的圆盘,宇宙将会毁灭。我尝试玩了 10 个,用人脑去递归,贼痛苦呀。

代码在下面写得简陋勿喷。

<script src="http://snapsvg.io/assets/js/snap.svg-min.js"></script>
<svg id="svg" style="width: 100%; height: 100%;"></svg><script> let step = 0; function hanoi(n, a, b, c) { if (n === 1) { step++; console.log(step + ": ", a, "--->", c); let rect; if (a === "A") { rect = dataA.pop(); } else if (a === "B") { rect = dataB.pop(); } else if (a === "C") { rect = dataC.pop(); } if (c === "A") { dataA.push(rect); } else if (c === "B") { dataB.push(rect); } else if (c === "C") { dataC.push(rect); } draw(deepClone(dataA), deepClone(dataB), deepClone(dataC), step); } else { hanoi(n - 1, a, c, b); hanoi(1, a, b, c); hanoi(n - 1, b, a, c); } } function isObject(v) { return Object.prototype.toString.call(v) === "[object Object]"; } function deepClone(data) { if (Array.isArray(data)) { let arr = []; for (const d of data) { arr.push(deepClone(d)); } return arr; } else if (isObject(data)) { let obj = {}; for (let k in data) { if (isObject(data[k])) { obj[k] = deepClone(data[k]); } else { obj[k] = data[k]; } } return obj; } else { return data; } } let svg = Snap("#svg"); let count = 5; let maxWidth = 100; let stepWidth = 10; let maxHeight = 100; let height = 20; let maxY = 100; let dataA = []; let dataB = []; let dataC = []; for (let i = 0; i < count; i++) { let width = maxWidth - stepWidth * i; dataA.push({ width, fill: "#" + ("000000" + String(Math.random() * 0xffffff).toString(16)).slice(-6), }); } for (let i = 0; i < dataA.length; i++) { let { width, fill } = dataA[i]; svg .rect( (maxWidth - width) / 2, maxHeight - height * i, width, height, 10, 10 ) .attr({ fill, }); } hanoi(count, "A", "B", "C"); function draw(dataA, dataB, dataC, step) { setTimeout( (dataA, dataB, dataC) => { console.log(dataA, dataB, dataC); svg.clear(); let datas = [dataA, dataB, dataC]; for (let j = 0; j < datas.length; j++) { let data = datas[j]; for (let i = 0; i < data.length; i++) { let { width, fill } = data[i]; let gapWidth = 120; svg .rect( gapWidth * j + (maxWidth - width) / 2, maxHeight - height * i, width, height, 10, 10 ) .attr({ fill, }); } } }, 1000 * step, dataA, dataB, dataC ); }
</script>

我要分享

曾小乱

作者: 曾小乱

喜欢写点有意思的东西

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据