AiScriptでライフゲーム！

**これは[Misskey Advent Calendar 2020](https://adventar.org/calendars/5026)の3日目の記事です！！**


# 概要
AiScriptでライフゲームを作ってpagesで走らせたら**めちゃくちゃ重かった！**

[Aiscriptでライフゲーム](https://misskey.io/@kuchibashi/pages/1606828667328)


# はじめに

僕は**ライフゲームが大好き**で、小一時間はずっと眺めることができます。

ライフゲームとは、偉い数学者が考えた遊びで、票の格子を生物に見立てて、**環境によってその格子が死んだり生まれたりするというようなゲームです**


**本物を見たい方は[ここ](https://aadebdeb.github.io/WebGL_LifeGame/)を見てください**
  
kawaii

![open-source-cellauto-js-2.5f6c69fb4cce1f78445204d8bdf13c3c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923242/2cbb3424-a711-53ed-4755-364864c7197a.gif)

それぞれの格子に**隣接する生きている格子の数**によって

- **誕生**
死んでいるセルに隣接する生きたセルがちょうど**3つ**あれば、次の世代が**誕生する**。

- **生存**
生きているセルに隣接する生きたセルが**2つか3つ**ならば、次の世代でも**生存する**。

- **過疎**
生きているセルに隣接する生きたセルが**1つ以下**ならば、過疎により**死滅する**。

- **過密**
生きているセルに隣接する生きたセルが**4つ以上ならば**、過密により**死滅する**。

みたいなルールにのっとて世代が進んでいきます。  


この記事は細かいこと知らなくても**雰囲気で楽しめる記事となっております**が、詳細が気になる人は[wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0)をご覧ください！


そこまで実装がむずかしくないためプログラムの入門なんかにも使われたりすることがあるらしいです。
なので今回は、AiScriptで実装してみることにしました！！

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [ライフゲームについて](#ライフゲームについて)
1. [AiScriptで実装した](#AiScriptで実装した)
1. [参考文献](#reference)

<!-- 各チャプター -->
<a id="ライフゲームについて"></a>
# ライフゲームについて
このライフゲーム、見ていて面白いだけではなく、これで論理上、時間はかかるものの**一般的なプログラミング言語と同等の計算能力**（チューリング完全性）を持っています！！（なので、これで**時計とか電卓とか作ったりできます！**）
さらに、マス目を移動して行ったり、増殖したりと、いろんな面白いパターンが作ることができて、その中でも僕がすきなものをいくつか紹介します！

## パルサー
![パルサー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923242/7f952230-6973-330c-8bb7-979293c3eaa3.gif)

こいつは**振動子**と呼ばれるタイプのパターンで**一定の動きを繰り返します！**振動子の中でもパルサーはx軸,y軸対象のきれいな動きをするのでお気に入りです！

## グライダー
![Animated_glider_emblem.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923242/f8106c23-3f6b-b149-653d-028447ea8dc0.gif)

ライフゲームといえばこいつというぐらい有名な移動物体です！こいつは見てわかる通り**クネクネしながら移動して行きます。**
ごちゃごちゃしたライフゲームの中でも移動していて目立つのですぐに見つけられると思います！ 


<a id="AiScriptで実装した"></a>
# AiScriptで実装した

それでそれをpagesに移植したのがこちらです！

[Aiscriptでライフゲーム](https://misskey.io/@kuchibashi/pages/1606828667328)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/923242/c8884dfc-3123-1d2e-0e81-5f582652ace8.png)

15x15マスの中でランダムに生きた格子が生成され、生き死にを繰り返します。



AiScriptはやっぱり**癖が強くて**、**書くのが大変でした**！スペース一つで構文エラーになるのでもうちょっと柔軟になったら使いやすいと思いました！

それで、**この実装だとむちゃくちゃ重いです！**
やりようによってはもっと軽くできるとは思うのですが、AiScriptに慣れてなかったので、できるだけコーディングで迷わないようにと気を使った結果この重さに！

**こんな書き方もあるよ～**など、知ってる方！ぜひ助言をお願いします！

一応コードも載せておきます！

**ここまで見ていただきありがとうございました～！**

``` ai
#FIELD_WIDTH = 15
#FIELD_HEIGHT = 15

$field <- []

~ #column (FIELD_HEIGHT+2) {
    ~ #row (FIELD_WIDTH+2) {
        ? ((((row=1)|(column=1))|((row=(FIELD_HEIGHT+2))|(column=(FIELD_WIDTH+2))))=no) {
            Arr:push(field Math:rnd(0 1))
        } . {
            Arr:push(field 0)
        }
    }
}


@isAlive(field index){
    #count = (((field[((index-(FIELD_WIDTH+2))-1)]+field[(index-(FIELD_WIDTH+2))])+(field[((index-(FIELD_WIDTH+2))+1)]
            +field[(index-1)]))+((field[(index+1)]
            +field[((index+(FIELD_WIDTH+2))-1)])+(field[(index+(FIELD_WIDTH+2))]+field[((index+(FIELD_WIDTH+2))+1)])))
    
    ? ((field[index]=1)&(count=2)) {
        << 1
    } .? (count=3) {
        << 1
    } . {
        << 0
    }
}

@do(field){
    $_field <- []
    ~ ((FIELD_HEIGHT + 2) * (FIELD_WIDTH + 2)) {
        Arr:push(_field 0)
    }
    
    ~ #column (FIELD_HEIGHT+2) {
        ? (((column=1)|(column=(FIELD_HEIGHT+2)))=no) { 
            ~ #row (FIELD_WIDTH+2) {
                ? (((row=1)|(row=(FIELD_WIDTH+2)))=no) {
                    _field[(((FIELD_WIDTH+2)*(column-1))+row)] <- isAlive(field (((FIELD_WIDTH+2)*(column-1))+row))
                }
            }
        }
    }

    << _field
}

@display(field){
    $row_str <- ""
    ~ #column (FIELD_HEIGHT+2) {
        ~ #row (FIELD_WIDTH+2) {
            ? ((((row=1)|(column=1))|((row=(FIELD_HEIGHT+2))|(column=(FIELD_WIDTH+2))))=no) {
                ? (field[(((column-1)*(FIELD_HEIGHT+2))+row)]=1) {
                    row_str <- `{row_str} 0`
                } . {
                    row_str <- `{row_str} .`
                }
            } . {
                row_str <- `{row_str} *`
            }
        }
        <: row_str
        row_str <- ""
    }
}

@start(){
    Async:interval(50, @(){
        field <- do(field)
        <: ""
        <: ""
        display(field)
    })
}

display(field)
start()

```



<a id="#reference"></a>
# 参考文献
- [AiScriptを使ってみた](https://qiita.com/YuzuRyo61/items/58d8c2f6a2c2bbfb7eda)
- [aiscript-github](https://github.com/syuilo/aiscript)
- [ライフゲームの物体一覧](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B2%E3%83%BC%E3%83%A0%E3%81%AE%E7%89%A9%E4%BD%93%E4%B8%80%E8%A6%A7)