Help us understand the problem. What is going on with this article?

AiScriptでライフゲーム!

これはMisskey Advent Calendar 2020の3日目の記事です!!

概要

AiScriptでライフゲームを作ってpagesで走らせたらめちゃくちゃ重かった!

Aiscriptでライフゲーム

はじめに

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

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

本物を見たい方はここを見てください

kawaii

open-source-cellauto-js-2.5f6c69fb4cce1f78445204d8bdf13c3c.gif

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

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

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

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

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

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

この記事は細かいこと知らなくても雰囲気で楽しめる記事となっておりますが、詳細が気になる人はwikipediaをご覧ください!

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

目次

  1. ライフゲームについて
  2. AiScriptで実装した
  3. 参考文献

ライフゲームについて

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

パルサー

パルサー

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

グライダー

Animated_glider_emblem.gif

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

AiScriptで実装した

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

Aiscriptでライフゲーム
image.png

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

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

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

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

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

ここまで見ていただきありがとうございました~!

#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()

参考文献

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away