Class: RPiet::Interpreter

Inherits:
Object
  • Object
show all
Defined in:
lib/rpiet/interpreter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, event_handler = RPiet::Logger::NoOutput.new) ⇒ Interpreter

Returns a new instance of Interpreter.



10
11
12
13
14
15
16
17
# File 'lib/rpiet/interpreter.rb', line 10

def initialize(source, event_handler=RPiet::Logger::NoOutput.new)
  @x, @y, @pvm, @step = 0, 0, RPiet::Machine.new, 1
  @source, @event_handler = source, event_handler
  @rows, @cols = @source.size
  @pixels = alloc_matrix { |i, j| @source.pixel(i, j)}
  @groups = calculate_groups(alloc_matrix { |i, j| 0 })
  @event_handler.initialized(self)
end

Instance Attribute Details

#groupsObject (readonly)

Returns the value of attribute groups.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def groups
  @groups
end

#pvmObject (readonly)

Returns the value of attribute pvm.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def pvm
  @pvm
end

#sourceObject (readonly)

Returns the value of attribute source.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def source
  @source
end

#stepObject (readonly)

Returns the value of attribute step.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def step
  @step
end

#xObject (readonly)

Returns the value of attribute x.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def x
  @x
end

#yObject (readonly)

Returns the value of attribute y.



8
9
10
# File 'lib/rpiet/interpreter.rb', line 8

def y
  @y
end

Instance Method Details

#alloc_matrixObject



98
99
100
101
102
# File 'lib/rpiet/interpreter.rb', line 98

def alloc_matrix
  Array.new(@rows) { Array.new(@cols) {nil} }.tap do |matrix|
    walk_matrix(matrix) { |i, j| matrix[i][j] = yield i, j }
  end
end

#calculate_groups(groups) ⇒ Object

always look up, left, or make new group



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
# File 'lib/rpiet/interpreter.rb', line 71

def calculate_groups(groups)
  all_groups = []
  walk_matrix(groups) do |i, j|
    rgb = @pixels[i][j]
    up = j-1 >= 0 ? groups[i][j-1] : nil
    left = i-1 >= 0 ? groups[i-1][j] : nil
    if up && up.rgb == rgb
      up << [i, j]
      groups[i][j] = up
      # disjoint groups to merge
      up.merge(groups, left) if left && left != up && left.rgb == rgb
    end

    if groups[i][j] == 0 && left && left.rgb == rgb
      left << [i, j]
      groups[i][j] = left
    end

    if groups[i][j] == 0
      groups[i][j] = RPiet::Group.new(rgb, [i, j])
      all_groups << groups[i][j]
    end
  end
  all_groups.each { |group| group.finish }
  groups
end

#next_stepObject



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
# File 'lib/rpiet/interpreter.rb', line 31

def next_step
  @pvm.block_value = @groups[@x][@y].size
  i = 0
  seen_white = false
  @event_handler.step_begin(self)
  ex, ey = @groups[@x][@y].point_for(@pvm)
  while i < 8 do
    nx, ny = @pvm.next_possible(ex, ey)

    if !valid?(nx, ny)
      i += 1
      @pvm.orient_elsewhere(i)

      ex, ey = @groups[@x][@y].point_for(@pvm) if !seen_white
      @event_handler.trying_again(self, ex, ey)
      next
    elsif @pixels[nx][ny] == RPiet::Color::WHITE
      if !seen_white
        seen_white = true
        i = 0
        @event_handler.seen_white(self)
      end
      ex, ey = nx, ny
    else
      if !seen_white
        operation = @pvm.execute(@pixels[nx][ny], @pixels[@x][@y])
      else
        operation = 'noop'            
      end
      @event_handler.operation(self, operation)
      @x, @y = nx, ny
      @step += 1
      return true
    end
  end
  @event_handler.execution_completed(self)
  false
end

#runObject



19
20
21
22
# File 'lib/rpiet/interpreter.rb', line 19

def run
  while(next_step) do
  end
end

#valid?(x, y) ⇒ Boolean

Is this point on the image and not black?

Returns:

  • (Boolean)


26
27
28
29
# File 'lib/rpiet/interpreter.rb', line 26

def valid?(x, y)
  x >= 0 && x < @rows && y >= 0 && y < @cols && 
    @pixels[x][y] != RPiet::Color::BLACK
end

#walk_matrix(matrix) ⇒ Object



104
105
106
107
108
109
110
# File 'lib/rpiet/interpreter.rb', line 104

def walk_matrix(matrix)
  0.upto(@rows-1) do |i|
    0.upto(@cols-1) do |j|
      yield i, j
    end
  end
end