#!/usr/bin/env ruby

begin
  require 'colorize'
rescue LoadError
  puts "Gem 'colorize' not found. Install with: gem install --user-install colorize"
  exit
end

class GravityLife
  attr_accessor :rows, :cols, :grid, :velocities

  def initialize(rows = 80, cols = 60)
    @rows = rows
    @cols = cols
    @grid = Array.new(rows) { Array.new(cols) { [true, false].sample } }
    @velocities = Array.new(rows) { Array.new(cols, 0) }
  end

  def neighbors(r, c)
    count = 0
    (-1..1).each do |dr|
      (-1..1).each do |dc|
        next if dr == 0 && dc == 0
        rr = (r + dr) % rows
        cc = (c + dc) % cols
        count += 1 if grid[rr][cc]
      end
    end
    count
  end

  def step
    new_grid = Array.new(rows) { Array.new(cols, false) }
    new_vel = Array.new(rows) { Array.new(cols, 0) }

    (0...rows).each do |r|
      (0...cols).each do |c|
        alive = grid[r][c]
        n = neighbors(r, c)

        if alive
          new_grid[r][c] = true if n == 2 || n == 3
        else
          new_grid[r][c] = true if n == 3
        end

        if new_grid[r][c]
          vel = velocities[r][c] + 1
          target_r = [r + vel, rows - 1].min
          new_grid[target_r][c] = true
          new_vel[target_r][c] = vel
        end
      end
    end

    @grid = new_grid
    @velocities = new_vel
  end

  def display
    system("clear") || system("cls")
    grid.each do |row|
      puts row.map { |cell| cell ? "⬛".colorize(:cyan) : "⬜".colorize(:light_black) }.join
    end
  end

  def run(steps = 200, delay = 0.1)
    steps.times do
      display
      step
      sleep(delay)
    end
  end
end

game = GravityLife.new(80, 60)
game.run
