6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

二次元セルオートマトン(ライフゲーム)

Last updated at Posted at 2017-01-07

一次元セルオートマトンの続き。
詳細はwikiへ。
二次元セルオートマトンの中でもこのルールのことをライフゲームと呼ぶようです。

Ruby

init

Array.newにブロックを渡すと良しなに初期化してくれます。

class Lifegame
  attr_accessor :cells

  def initialize(y = 0,x = 0)
    @cells = Array.new(y) { Array.new(x,0) }
  end

rule

前回と違いパターンないしルールは固定。
自分の生死と周囲の生きている数を元に明日の生死が決まります。
孤独だと死。騒がしくても死。丁度良いと生き返ったりします。

  def rule(*cs)
    case cs
    when [1, 2] then 1
    when [1, 3] then 1
    when [0, 3] then 1
    else 0
    end
  end

apply

配列の外を参照しない様に確認しながら、
周囲の生きている数を数え上げ、ルールに適応します。
前回教えていただいたproductが使えスッキリしてます。

  def apply
    sy = @cells.size
    sx = @cells[0].size
    as = [-1,0,1]

    @cells = @cells.map.with_index { |cy,iy|
      cy.map.with_index { |c,ix|
        rule(c,
          as.product(as).map { |ay,ax| 
            if ay == 0 && ax == 0
              0
            else
              y = iy + ay
              x = ix + ax
              if y >= 0 && y < sy && x >= 0 && x < sx
                @cells[y][x]
              else
                0
              end
            end
          }.reduce(:+)
        )
      }
    }
  end

random

セルを手で打つのはだるいのでランダムに任せます。
一応ブロックで調整できます。
コクのある乱数など試して見ましょう。

  def random
    @cells = @cells.map { |y|
      y.map { |x| 
        if block_given?
          yield x
        else
          rand(2) 
        end
      }
    }
  end

show, run

clearコマンドでターミナルの画面でアニメーション(遅い)
その場合はsleepで調整。

  def show
    @cells.map { |y| y.map { |x| x == 0 ? " " : "O" }.join + "\n" }.join + "\n"
  end

  def run n = 200,m = 0.1
    g = 0
    for nn in 1 .. n
      system "clear"
      puts "Gen: #{g}\n#{show}"
      g += 1
      apply
      sleep m
    end
  end
end

main

サイズが大きすぎると遅いので調整しましょう。
私のターミナルは縦25*横100しかないのでこれくらいで十分です。
めっちゃフォントを大きくしてます。

require "io/console"
y,x = IO.console.winsize
cs = Lifegame.new(y-3,x)
cs.random { (rand(2) + rand(2) + rand(2)) / 3 }
cs.run(50)

lifegame_terminal.gif

end

ttygif使って見たけどいまいちカクカク。
実際はもう少しなめらかです。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?