Comment detail

ライフゲーム (Nested Flatten)

ライフゲームとは関係ないところで妙な小細工

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
require 'curses'
require 'enumerator'

class Object
  def make_instance_variables (_binding)
    eval(<<'EOC', _binding)
      local_variables.each do
        |lv_name|
        instance_variable_set("@#{lv_name}", eval(lv_name))
      end
EOC
  end
end

class World
    attr_reader :height, :width, :rate

    def initialize (height, width, rate)
        make_instance_variables(binding)
        @cells = Array.new(height * width) { rand < rate }
    end

    def [] (x, y)
        @cells[fix_position(x, y)]
    end

    def []= (x, y, v)
        @cells[fix_position(x, y)] = v
    end

    def livings (x, y)
        result = 0
        (-1..1).each {|dy| (-1..1).each {|dx| result += 1 if self[x + dx, y + dy] unless dx == 0 and dy == 0 }}
        result
    end

    def update
        @cells = @cells.dup.enum_for(:each_with_index).map do
            |l, idx|
            x, y = idx % width, idx / width
            ls = livings(x, y)
            if l  
                (2..3) === ls
            else
                ls == 3
            end
        end
    end

    def inspect
        @cells.map {|it| "[#{it ? '*' : ' '}]" }.join.gsub(/.{#{3*width}}/){|it| "#{it}\n" }
    end

    private

    def fix_position (x, y)
        y % width * width + x % height
    end
end

class OptionParser
    def self.parse (args)
        require 'ostruct'
        require 'optparse'

        options = OpenStruct.new
        options.population = 0.3
        options.interval = 0.5
        options.height = options.width = 10

        parser = OptionParser.new do
            |parser|
            parser.banner = "Usage: #{File.basename($0)} [options] "
            parser.on('-p', '--population-rate [RATE]') { |it| options.population = it.to_f }
            parser.on('-i', '--interval [SEC]') { |it| options.interval = it.to_f }
            parser.on('-w', '--width [WIDTH]') { |it| options.interval = it.to_f }
            parser.on('-h', '--height [HEIGHT]') { |it| options.interval = it.to_f }
        end

        parser.parse!(args)
        options
    rescue
        puts parser.help
        exit
    end
end

options = OptionParser.parse(ARGV)

w = World.new(options.width, options.height, options.population) 

Curses.init_screen
loop do
    Curses.clear
    Curses.addstr(w.inspect)
    Curses.refresh
    sleep(options.interval)
    w.update
end
Curses.close_screen

Index

Feed

Other

Link

Pathtraq

loading...