简介
最早接触兰顿蚂蚁是在做参数化的时候, 那时候只感觉好奇, 以为是很复杂的东西. 因无意中看到生命游戏 https://github.com/thepeted/game-of-life-redux 的 React 实现, 所以希望通过兰顿蚂蚁的例子再学习一下 React.
兰顿蚂蚁的规则非常简单:
如果蚂蚁位于白色方块, 则向右旋转 90°, 反转方块的颜色, 然后向前移动一步.
如果蚂蚁位于黑色方块, 则向左旋转 90°, 反转方块的颜色, 然后向前移动一步.
如下图所示:
蚂蚁在前一百步有一定规律, 之后陷入混沌, 直到一万步之后将走出混沌形成一条高速公路.
兰顿蚂蚁和生命游戏都是元胞自动机的一种, 关于兰顿蚂蚁的更多介绍可以看维基百科 https://en.wikipedia.org/wiki/Langton's_ant
开始编写程序
在本教程中, 我主要还是说一下项目中的问题及难点, 不会对整个项目做太详细的介绍, 把代码粘贴一遍也没什么意义, 大家可以自己摸索一遍, 其中 webpack 用了 4.0, 顺便说一句, Webpack4.0 还是有不少坑的, 项目在 GitHub 中有, 遇到问题可以翻阅一下源代码
源码: https://github.com/nzbin/langton-ant-redux
先看一下最终效果的动图演示:
这个项目可以说是 React + Redux 非常基础的练习. 主要就是绘制网格, 根据蚂蚁规则重绘网格. 以下是项目目录:
src
├── actions
│ └── index.JS
├── components
│ ├── App.JS
│ ├── button.JS
│ └── cell.JS
├── containers
│ ├── board.JS
│ ├── control.JS
│ └── counter.JS
├── reducers
│ ├── index.JS
│ ├── reducer_board.JS
│ ├── reducer_generations.JS
│ └── reducer_play_status.JS
└── index.JS
蚂蚁法则的算法
兰顿蚂蚁演示程序的关键就是蚂蚁规则的算法, 其实算法也很简单, 设置方向变量, 模拟蚂蚁的前进线路即可. 以下是逻辑代码:
- // status: true -> black square
- if (gameState[row][col].status) {
- gameState[row][col].status = false;
- // ant: turnLeft90 -> move forward 1 step
- switch (dir) {
- case 'T':
- ant['pos'] = [row, col - 1];
- ant['dir'] = 'L';
- break;
- case 'B':
- ant['pos'] = [row, col + 1];
- ant['dir'] = 'R';
- break;
- case 'L':
- ant['pos'] = [row + 1, col];
- ant['dir'] = 'B';
- break;
- case 'R':
- ant['pos'] = [row - 1, col];
- ant['dir'] = 'T';
- break;
- default:
- }
- }
- // status: false -> white square
- else if (!gameState[row][col].status) {
- gameState[row][col].status = true;
- // ant: turnRight90 -> move forward 1 step
- switch (dir) {
- case 'T':
- ant['pos'] = [row, col + 1];
- ant['dir'] = 'R';
- break;
- case 'B':
- ant['pos'] = [row, col - 1];
- ant['dir'] = 'L';
- break;
- case 'L':
- ant['pos'] = [row - 1, col];
- ant['dir'] = 'T';
- break;
- case 'R':
- ant['pos'] = [row + 1, col];
- ant['dir'] = 'B';
- break;
- default:
- }
- }
布局
演示程序的网格如果只是写死的话就非常简单, 但是为了有更好的体验, 我做成了响应式, 无论有多少网格, 总能全部显示在屏幕上. 看似很简单的问题, 其实有很多可以学习的地方.
制作响应式网格的方式有很多, 比如结合媒体查询, 百分比. 为了效果更好一点, 我选择了百分比.
其次正方形网格也有多种方式实现, 比如 vw 单位, 百分比 + padding. 其中使用 vw 单位会有一个问题, 就是它的相对父元素是视窗, 所以网格总是全屏显示, 比较恶心. 最后使用了百分比 + padding 的方式. 细节方面还使用了 calc 运算.
但是百分比计算的网格存在精度问题, 适当放大尺寸可以解决.
查看在线 Demo: https://nzbin.github.io/langton-ant-redux
性能
因为我对 React 的研究不深, 所以在这个项目中遇到了一些性能问题, 绘制一个 100X100 的网格的话, 在 Firefox 中明显感觉到卡顿 (与我的机子也有关系),Chrome 表现还可以.
其实用 canvas 做演示程序可能更好一些, 同时跑多个蚂蚁也没有问题.
总结
因各种各样的原因, 没想到这篇文章又拖了半年多才写完, 与其说是教程, 不如说是对兰顿蚂蚁的介绍, 更惭愧的是文章内容不深, 无法帮助更多的初学者. 我不是 React 的拥泵, 目前专注 Angular, 所以关于 React 的译文以及简易教程就到此为止吧.
来源: https://www.cnblogs.com/nzbin/p/9243294.html