class Lifegame::Game

Attributes

lifes[R]

Public Class Methods

new(x, y) click to toggle source
# File lib/lifegame/game.rb, line 7
def initialize(x, y)
  @x = x
  @y = y
  @lifes = x.times.map { |x| y.times.map { |y| Life.new } }
  @generation = 0
end

Public Instance Methods

[](x, y) click to toggle source
# File lib/lifegame/game.rb, line 14
def [](x, y)
  return nil if x.negative? || y.negative?
  return nil if x > @x || y > @y

  @lifes.fetch(x, []).fetch(y, nil)
end
each() { |life, x: x, y: y| ... } click to toggle source
# File lib/lifegame/game.rb, line 21
def each
  @lifes.each.with_index { |line, x|
    line.each.with_index { |life, y|
      yield(life, x: x, y: y)
    }
  }
end
next!() click to toggle source
# File lib/lifegame/game.rb, line 29
def next!
  self.
    # 調べて
    map { |_, point| { live: next_alive?(point[:x], point[:y]), x: point[:x], y: point[:y] } }.
    # 実施
    each do |life_point|
    x = life_point[:x]
    y = life_point[:y]

    if life_point[:live]
      self[x, y].be!
    else
      self[x, y].die!
    end
  end
  @generation += 1
end
next_alive?(x, y) click to toggle source

あるセルが次のターンに生きてるか確認する

# File lib/lifegame/game.rb, line 48
def next_alive?(x, y)
  target = self[x, y]

  # 隣接セルの座標
  adjoining = [
    [x - 1, y - 1],
    [x    , y - 1],
    [x + 1, y - 1],
    [x - 1, y],
    # [x    , y],
    [x + 1, y],
    [x - 1, y + 1],
    [x    , y + 1],
    [x + 1, y + 1],
  ]

  dead_or_live = adjoining.map { |point|
    n_x, n_y = point
    self[n_x, n_y]&.alive?
  }.compact

  live_count = dead_or_live.count { |live| live }

  if target.dead?
    # 3の時のみ誕生
    live_count == 3
  else
    # 2,3の時のみ生き残る
    (2..3).include?(live_count)
  end
end
print() click to toggle source
sow!(alive_frequency = 0.2) click to toggle source
# File lib/lifegame/game.rb, line 105
def sow!(alive_frequency = 0.2)
  self.each do |life, _point|
    if alive_frequency > rand
      life.be!
    end
  end
end
start(wait_time = 0.1) click to toggle source
# File lib/lifegame/game.rb, line 95
def start(wait_time = 0.1)
  loop {
    print
    sleep wait_time
    next!
  }
rescue Interrupt
  puts 'good bye world!'
end
to_s() click to toggle source
# File lib/lifegame/game.rb, line 80
def to_s
  lifes = @lifes.map { |line| line.map {|life| "#{life.to_s}"}.join }.join("\n")
  alives = count { |life| life.alive? }
  deads = count { |life| life.dead? }

  "generation: #{@generation}, x: #{@x}, y: #{@y}, all: #{@x * @y}, alive: #{alives}, dead: #{deads}\n#{lifes}"
end