Rubyでライフゲームを作ってみた.
起動後,10×10みたいな感じでフィールドの大きさを入力.
あとはEnterを押すと世代が一つずつ進んでいく.
また,座標の指定をすれば,その座標の生死を切り替えられる.
以下にソースコードを示す.
lifegame.rb
#!/usr/bin/env ruby require "lifegamefield.rb" require "lifegameview.rb" print "[幅x高さ]を入力してください: " widthheight=gets.split(/x/) width=widthheight[0].to_i height=widthheight[1].to_i lgf = LifeGame::Field.new(width,height) view = LifeGame::ConsoleView.new(lgf) g=0 loop do print "=== generation #{g+1} ===\n" view.visualize cmd="" loop do print "状態を変更する場合はその座標をカンマ区切りで入力[x,y]:" break if (cmd=gets) == "\n" # 座標指定があれば if cmd =~ /(\d+),(\d+)/ x=$1.to_i y=$2.to_i if lgf.isalive?(x,y) lgf.kill(x,y) else lgf.create(x,y) end end view.visualize end break if cmd=="exit" lgf.update g+=1 end
lifegamefield.rb
module LifeGame class Field attr_reader :width,:height def initialize(width,height) @width=width @height=height init end def init @field=[] @height.times do |h| line=[] @width.times do |w| line.push(false) end @field.push(line) end end def isalive?(x,y) return false if x >= @width return false if y >= @height return @field[y][x] end def create(x,y) return false if x >= @width return false if y >= @height @field[y][x]=true end def kill(x,y) return false if x >= @width return false if y >= @height @field[y][x]=false end def update # life game のメインルーチン newfield=@field.map{|x| x.clone} @height.times do |h| @width.times do |w| count=getlivecount(h,w) if @field[h][w] # 8近傍のうち生きているのが2つか3つでないなら死ぬ newfield[h][w]=false if count != 2 and count != 3 else # 8近傍のうち生きているのが3つだったら生きる newfield[h][w]=true if count == 3 end end end @field=newfield end def getlivecount(h,w) count=0 (-1..1).each do |dy| (-1..1).each do |dx| next if dy==0 and dx==0 count += 1 if @field[h-dy] != nil and @field[h-dy][w-dx] end end return count end end end
lifegameview.rb
module LifeGame class ConsoleView def initialize(field) @field=field end def visualize @field.height.times do |h| @field.width.times do |w| state=@field.isalive?(w,h) print "□" if state print "■" unless state end print "\n" end end end end
ついでにWebアプリにもしてみたいけど,めんどくさいので今日はここまで.