Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Friday, 19 April 2013

More cellular automata (spore2 from vanilla processing)


#
# Spore 2 
# by Mike Davis. 
# 
# A short program for alife experiments. Click in the window to restart. 
# Each cell is represented by a pixel on the display as well as an entry in
# the array 'cells'. Each cell has a run method, which performs actions
# based on the cell's surroundings.  Cells run one at a time (to avoid conflicts
# like wanting to move to the same space) and in random order. 
#
load_library :cell

attr_reader  :cells, :black, :colours, :spore1, :spore2, :spore3, :spore4

MAX_CELLS = 8000

# set lower for smoother animation, higher for faster simulation
RUNS_PER_LOOP = 10000

def setup
  size(640, 360)
  frame_rate(24)
  @black = color(0, 0, 0)
  @spore1 = color(128, 172, 255)
  @spore2 = color(64, 128, 255)
  @spore3 = color(255, 128, 172)
  @spore4 = color(255, 64, 128)
  @colours =[spore1, spore2, spore3, spore4]
  reset!
end

def reset!
  clear_screen
  seed
end

def seed
  @cells = []
  # Add cells at random places
  MAX_CELLS.times do
    cx = rand(0 ... width)
    cy = rand(0 ... height)
    if (getpix(cx, cy) == black)
      setpix(cx, cy, colours.sample)
      cells << Cell.new(self, cx, cy)
    end
  end
end

def draw
  # Run cells in random order
  RUNS_PER_LOOP.times do
    cells.sample.run
  end
end

def clear_screen
  background(0)
end

def setpix(x, y, c)
  while (x < 0)
    x += width
  end
  while (x > (width - 1))
    x -= width
  end
  while (y < 0)
    y += height
  end
  while (y > (height - 1))
    y -= height
  end
  set(x, y, c)
end

def getpix(x, y)
  while (x < 0)
    x += width
  end
  while (x > (width - 1))
    x -= width
  end
  while (y < 0)
    y += height
  end
  while (y > (height - 1))
    y -= height
  end
  get(x, y)
end

def mouse_pressed
  reset!
end

class Cell

  attr_reader :outer, :x, :y, :width, :height, :black
  attr_reader :spore1, :spore2, :spore3, :spore4

  def initialize(outer, xin = 0, yin = 0)
    @outer, @x, @y = outer, xin, yin
    @width, @height, @black = outer.width, outer.height, outer.black
    @spore1, @spore2, @spore3, @spore4 = *outer.colours
  end

  # Perform action based on surroundings
  def run
    # Fix cell coordinates
    while (x < 0)
      @x += width
    end
    while (x > (width - 1))
      @x -= width
    end
    while (y < 0)
      @y += height
    end
    while (y > (height - 1))
      @y -= height
    end
    # Cell instructions
    my_color = outer.getpix(x, y)
    if (my_color == spore1)
      if (outer.getpix(x - 1, y + 1) == black && outer.getpix(x + 1, y + 1) == black && outer.getpix(x, y + 1) == black)
        move(0, 1)
      elsif (outer.getpix(x - 1, y) == spore2 && outer.getpix(x - 1, y - 1) != black)
        move(0, -1)
      elsif (outer.getpix(x - 1, y) == spore2 && outer.getpix(x - 1, y - 1) == black)
        move(-1, -1)
      elsif (outer.getpix(x + 1, y) == spore1 && outer.getpix(x + 1, y - 1) != black)
        move(0, -1)
      elsif (outer.getpix(x + 1, y) == spore1 && outer.getpix(x + 1, y - 1) == black)
        move(1, -1)
      else
        move(rand(1 .. 2), 0)
      end
    elsif (my_color == spore2)
      if (outer.getpix(x - 1, y + 1) == black && outer.getpix(x + 1, y + 1) == black && outer.getpix(x, y + 1) == black)
        move(0, 1)
      elsif (outer.getpix(x + 1, y) == spore1 && outer.getpix(x + 1, y - 1) != black)
        move(0, -1)
      elsif (outer.getpix(x + 1, y) == spore1 && outer.getpix(x + 1, y - 1) == black)
        move(1, -1)
      elsif (outer.getpix(x - 1, y) == spore2 && outer.getpix(x - 1, y - 1) != black)
        move(0, -1)
      elsif (outer.getpix(x - 1, y) == spore2 && outer.getpix(x - 1, y - 1) == black)
        move(-1, -1)
      else
        move(rand(1 .. 2), 0)
      end
    elsif (my_color == spore3)
      if (outer.getpix(x - 1, y - 1) == black && outer.getpix(x + 1, y - 1) == black && outer.getpix(x, y - 1) == black)
        move(0, -1)
      elsif (outer.getpix(x - 1, y) == spore4 && outer.getpix(x - 1, y + 1) != black)
        move(0, 1)
      elsif (outer.getpix(x - 1, y) == spore4 && outer.getpix(x - 1, y + 1) == black)
        move(-1, 1)
      elsif (outer.getpix(x + 1, y) == spore3 && outer.getpix(x + 1, y + 1) != black)
        move(0, 1)
      elsif (outer.getpix(x + 1, y) == spore3 && outer.getpix(x + 1, y + 1) == black)
        move(1, 1)
      else
        move(rand(1 .. 2), 0)
      end
    elsif (my_color == spore4)
      if (outer.getpix(x - 1, y - 1) == black && outer.getpix(x + 1, y - 1) == black && outer.getpix(x, y - 1) == black)
        move(0, -1)
      elsif (outer.getpix(x + 1, y) == spore3 && outer.getpix(x + 1, y + 1) != black)
        move(0, 1)
      elsif (outer.getpix(x + 1, y) == spore3 && outer.getpix(x + 1, y + 1) == black)
        move(1, 1)
      elsif (outer.getpix(x - 1, y) == spore4 && outer.getpix(x - 1, y + 1) != black)
        move(0, 1)
      elsif (outer.getpix(x - 1, y) == spore4 && outer.getpix(x - 1, y + 1) == black)
        move(-1, 1)
      else
        move(rand(1 .. 2), 0)
      end
    end
  end

  # Will move the cell (dx, dy) units if that space is empty
  def move(dx, dy)
    if (outer.getpix(x + dx, y + dy) == black)
      outer.setpix(x + dx, y + dy, outer.getpix(x, y))
      outer.setpix(x, y, black)
      @x += dx
      @y += dy
    end
  end
end

No comments:

Post a Comment

Followers

Blog Archive

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2