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

ImageMagick でライフゲームを動かすシェル芸

ImageMagick でライフゲームを動かすシェル芸ができたので、記録しておきます。

ImageMagick でライフゲームを動かすとは?

ライフゲームを動かすには、
* 初期状態の設定
* ライフゲームのルール記述
* 可視化
などの機能が必要ですが、これらをすべて ImageMagick で行いました。
シェル芸botでの実行例は以下のような感じになります(この実行例では初期状態設定はtextimgを利用)。

動作環境

以下の環境で動作確認しています。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.3 LTS
Release:    18.04
Codename:   bionic
$ $SHELL --version
GNU bash, バージョン 4.4.20(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ convert --version
Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib

コマンド

以下のコマンドを実行することで、ライフゲームが動きます。

$ eval "convert -delay 10 xc:[160x90\!] -gravity center -pointsize 50 -draw 'text 0,0 \"Life\"' -negate -threshold 10% `for i in {1..1399};do echo -n "\( +clone -fx 'aa=p[-1,-1]+p[-1,0]+p[-1,1]+p[0,-1]+p[0,1]+p[1,-1]+p[1,0]+p[1,1];aa==3&1-u?1:aa<2|aa>3&u?0:u' \) ";done`x.gif"

実行結果は、x.gif というファイルに、以下の gif アニメーションが出力されます。
x.gif

コマンド解説

コマンド全体は、bash の for 文で、長大な convert コマンドの 引数を生成して、それを eval しています。
eval される中身は大きく3つの部分に分けられます。

初期状態設定部分

convert -delay 10 xc:[160x90\!] -gravity center -pointsize 50 -draw 'text 0,0 \"Life\"' -negate -threshold 10%

この部分は、160x90のグリッドに黒地に白文字で Life と描いています。

ルール記述部分

`for i in {1..1399};do echo -n "\( +clone -fx 'aa=p[-1,-1]+p[-1,0]+p[-1,1]+p[0,-1]+p[0,1]+p[1,-1]+p[1,0]+p[1,1];aa==3&1-u?1:aa<2|aa>3&u?0:u' \) ";done`

この部分はライフゲームのルールを記述しています。
for 文で繰り返し echo している

\( +clone -fx 'aa=p[-1,-1]+p[-1,0]+p[-1,1]+p[0,-1]+p[0,1]+p[1,-1]+p[1,0]+p[1,1];aa==3&1-u?1:aa<2|aa>3&u?0:u' \)

は、直前(イメージシーケンスの最後)のイメージに対して、各ピクセルの近傍ピクセルの白ピクセルの個数に応じた更新を行います。
これを for 文で繰り返すたびにライフゲームが1tic進んだイメージが生成されます。
このコマンドでは1399回の更新を行っていることになります。
実行に時間がかかるので、試しにちょっと実行してみる場合、
この回数を減らすと短時間で結果が確かめられていいでしょう。

出力表示部分

最後に

x.gif

として、イメージシーケンスのイメージをx.gifというファイルにgifアニメーションとして出力します。

所感

ImageMagick の fx expression が便利。
フラクタル図形なんかも描ける。


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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした