1. 程式人生 > >React 系列教程2:編寫蘭頓螞蟻演示程式

React 系列教程2:編寫蘭頓螞蟻演示程式

簡介

最早接觸蘭頓螞蟻是在做引數化的時候,那時候只感覺好奇,以為是很複雜的東西。因無意中看到生命遊戲的 React 實現,所以希望通過蘭頓螞蟻的例子再學習一下 React。

蘭頓螞蟻的規則非常簡單:

如果螞蟻位於白色方塊,則向右旋轉 90°,反轉方塊的顏色,然後向前移動一步。
如果螞蟻位於黑色方塊,則向左旋轉 90°,反轉方塊的顏色,然後向前移動一步。

如下圖所示:

螞蟻在前一百步有一定規律,之後陷入混沌,直到一萬步之後將走出混沌形成一條高速公路。

蘭頓螞蟻和生命遊戲都是元胞自動機的一種,關於蘭頓螞蟻的更多介紹可以看維基百科

開始編寫程式

在本教程中,我主要還是說一下專案中的問題及難點,不會對整個專案做太詳細的介紹,把程式碼貼上一遍也沒什麼意義,大家可以自己摸索一遍,其中 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 的譯文以及簡易教程就到此為止吧。