C++ でライフゲームを書いてみた

特に意味はないんですが、C++ライフゲームを書いてみました。
C++14 で動作します(Windows での動作は未確認。

[コード]

#include <cstdlib>
#include <thread>
#include <string>
#include <iostream>
#include <vector>


int
main(){
    using table_t = std::vector<std::vector<bool>>;
    table_t table = {
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    };

    auto width = [](auto const& table){
        return table[0].size();
    };

    auto height = [](auto const& table){
        return table.size();
    };

    auto at_cell = [&](auto const& table, auto x, auto y){
        return x < 0 || width(table)  <= x ? false
             : y < 0 || height(table) <= y ? false
             : table[y][x];
    };

    auto dead_or_alive = [&](auto table, auto x, auto y){
        auto cell  = at_cell(table, x, y);
        auto count = at_cell(table, x - 1, y - 1)
                   + at_cell(table, x - 0, y - 1)
                   + at_cell(table, x + 1, y - 1)
                   + at_cell(table, x + 1, y - 0)
                   + at_cell(table, x + 1, y + 1)
                   + at_cell(table, x - 0, y + 1)
                   + at_cell(table, x - 1, y + 1)
                   + at_cell(table, x - 1, y - 0);
        return cell ? count == 3 || count == 2 : count == 3;
    };

    auto update = [&](auto const& table){
        table_t result = table;
        for(int y = 0 ; y < table.size() ; ++y){
            for(int x = 0 ; x < table[y].size() ; ++x){
                result[y][x] = dead_or_alive(table, x, y);
            }
        }
        return result;
    };
    
    auto print = [&](auto const& table){
        std::system("clear");
        // or
//      std::system("cls");
        
        std::cout << std::string(width(table) + 2, '-') << "\n";
        for(auto&& row : table){
            std::cout << "|";
            for(auto&& cell : row){
                std::cout << (cell ? "*" : " ");
            }
            std::cout << "|\n";
        }
        std::cout << std::string(width(table) + 2, '-') << "\n";
        std::cout << std::endl;
    };

    while(1){
        print(table);
        table = update(table);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }

    return 0;
}

[動作]

lifegame

C++ だと実装するのが難しいと思いましたが、実際に書いてみるとそこまで複雑なコードにはならなかった。
上のコードだと100行もありませんし、短くしようと思えばもっと短くできそう。
鬼門なのは『接するセル』をどうやって走査するかですかね。
今回は愚直に実装しましたが、もっとスマートなやり方はありそう。
とりあえず、標準ライブラリに Range がほしい。