On Tue, Nov 25, 2008 at 11:07 AM, <brabuhr / gmail.com> wrote: > My first thought was a big case statement like that, but wanted > something a bit more "fun". My next thoughts were to try something > with lambda or define_method. Here's a really rough, partial (and > almost entirely untested) implementation built around define_method: Still not-tested :(, but less-incomplete: class Befunge93 instance_methods.each { |m| undef_method m unless (m =~ /^__|send/) } attr_accessor :stack, :memory, :position, :direction def initialize @stack, @memory, @position, @direction = [], {}, [0,0], [1,0] end def move @position[0] = (@position[0] + @direction[0]) % 80 @position[1] = (@position[1] + @direction[1]) % 25 end def run loop do send @memory[@position] move end end (0..9).each do |d| define_method :"#{d}" do @stack.push d end end %w{ + - * / % }.each do |o| define_method :"#{o}" do a, b = @stack.pop, @stack.pop @stack.push b.send(:"#{o}", a) end end define_method :"!" do @stack.pop.zero? ? 1 : 0 end define_method :"`" do a, b = @stack.pop, @stack.pop @stack.push (b > a ? 1 : 0) end define_method :":" do @stack.push @stack.last end define_method :"\\" do a, b = @stack.pop, @stack.pop @stack.push a; @stack.push b end define_method :"$" do @stack.pop end [ [ '^', [ 0,-1] ], [ 'v', [ 0, 1] ], [ '<', [-1, 0] ], [ '>', [ 1, 0] ] ].each do |d| define_method :"#{d[0]}" do @direction = d[1] end end define_method :"?" do [[0,-1],[0,1],[-1,0],[1,0]][rand(4)] end [ [ '_', [ 0, 1], [ 0,-1] ], [ '|', [ 1, 0], [-1, 0] ] ].each do |d| define_method :"#{d[0]}" do @direction = (@stack.pop.zero? ? d[1] : d[2]) end end define_method :"#" do move end define_method :"." do print @stack.pop end define_method :"," do print @stack.pop.chr end define_method :"&" do push gets.to_i end define_method :"~" do push getc end define_method :g do a, b = @stack.pop, @stack.pop @stack.push @memory[[b,a]] end define_method :p do a, b, c = @stack.pop, @stack.pop, @stack.pop @memory[[b,a]] = c end define_method :"@" do puts exit end define_method :"\"" do move until (a = @memory[@position]) == "\"" a[0,1].each_byte{|b| @stack.push b} move end end define_method :" " do end end bf = Befunge93.new #bf.memory = { # [0,0] => "v", [1,0] => " ", [2,0] => " ", [3,0] => " ", [4,0] => " ", # [0,1] => "1", [1,1] => "v", [2,1] => "<", [3,1] => " ", [4,1] => " ", # [0,2] => "1", [1,2] => "3", [2,2] => "2", [3,2] => " ", [4,2] => " ", # [0,3] => ">", [1,3] => "+", [2,3] => "^", [3,3] => " ", [4,3] => " ", # [0,4] => " ", [1,4] => "-", [2,4] => " ", [3,4] => " ", [4,4] => " ", # [0,5] => " ", [1,5] => ".", [2,5] => " ", [3,5] => " ", [4,5] => " ", # [0,6] => " ", [1,6] => "@", [2,6] => " ", [3,6] => " ", [4,6] => " ", # [0,7] => " ", [1,7] => " ", [2,7] => " ", [3,7] => " ", [4,7] => " ", # [0,8] => " ", [1,8] => " ", [2,8] => " ", [3,8] => " ", [4,8] => " ", #} #bf.run #=> -3 s = "> vv ,,,,,\"Hello\"<>48*, vv,,,,,,\"World!\"<>25*,@" 16.times{|a| 5.times{|b| bf.memory[[a,b]] = s[a + (b * 16), 1] } } bf.run #=> "Hello World!\n"