Class: Glass

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

Overview

The glass thing. It handles the figure position calculcations watches the available space, removes full lines, etc, etc.

Copyright © 2011 Nikolay Nemshilov

Constant Summary collapse

WIDTH =
12
HEIGHT =
24
COLOR =
Color::GRAY

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(window, x, y) ⇒ Glass

Basic constructor



17
18
19
20
21
22
23
24
25
# File 'lib/glass.rb', line 17

def initialize(window, x, y)
  @window = window
  @block  = Block.new(window, COLOR)

  @pos_x  = x
  @pos_y  = y

  reset!
end

Instance Attribute Details

#matrixObject

Returns the value of attribute matrix.



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

def matrix
  @matrix
end

#pos_xObject

Returns the value of attribute pos_x.



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

def pos_x
  @pos_x
end

#pos_yObject

Returns the value of attribute pos_y.



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

def pos_y
  @pos_y
end

Instance Method Details

#drawObject

Draws the class walls and content



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/glass.rb', line 39

def draw
  @block.color = COLOR

  # drawing the walls
  (0..HEIGHT).each do |i|
    @block.draw(@pos_x,  @pos_y + i)
    @block.draw(@pos_x + WIDTH + 1, @pos_y + i)
  end

  # drawing the bottom
  (1..WIDTH).each do |i|
    @block.draw(@pos_x + i, @pos_y + HEIGHT)
  end

  # drawing the blocks inside
  @matrix.each_with_index do |row, y|
    row.each_with_index do |color, x|
      unless color == nil
        @block.color = color
        @block.draw(@pos_x + x + 1, @pos_y + y)
      end
    end
  end
end

#glue_in(figure) ⇒ Object

Glues the figure into the glass. The figure might hang above or virtually get through the stack, it doesn’t matter. This method uses the horizontal position only



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/glass.rb', line 124

def glue_in(figure)
  @window.status.count_drop(figure)

  (0..figure.size_x - 1).each do |x|
    (0..figure.size_y-1).each do |y|
      if figure.matrix[y][x]
        @matrix[
          y + figure.pos_y - @pos_y + figure.distance
        ][
          x + figure.pos_x - @pos_x - 1
        ] = figure.color
      end
    end
  end

  remove_full_lines
end

#has_space_for?(matrix, pos_x, pos_y) ⇒ Boolean

Checks if this figure matrix can fit the glass at the given position. Used for prechecks on figure manipulations to enforce movement constraints

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/glass.rb', line 101

def has_space_for?(matrix, pos_x, pos_y)
  if pos_x > @pos_x && pos_x < (@pos_x + WIDTH + 2 - matrix[0].size)
    if pos_y >= @pos_y && pos_y < (@pos_y + HEIGHT + 1 - matrix.size)
      matrix.each_with_index do |row, y|
        row.each_with_index do |visible, x|
          if visible && nil != @matrix[pos_y - @pos_y + y][pos_x - @pos_x + x - 1]
            return false
          end
        end
      end

      return true
    end
  end

  false
end

#remove_full_linesObject

Checks the glass for full lines, removes them and refills the glass



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/glass.rb', line 146

def remove_full_lines
  lines = @matrix.map do |row|
    row.all? ? row : nil
  end.compact!

  lines.each do |row|
    @matrix.delete(row)
    @matrix.unshift Array.new(WIDTH)
  end

  @window.status.count_kill(lines)
end

#reset!Object

Empties the glass by creating a new blocks matrix



30
31
32
33
34
# File 'lib/glass.rb', line 30

def reset!
  @matrix = (0..HEIGHT-1).map do
    Array.new(WIDTH)
  end
end

#spaces_below(figure) ⇒ Object

Calculates the available space (in blocks) below the figure



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/glass.rb', line 68

def spaces_below(figure)
  fig_x = figure.pos_x - @pos_x - 1
  fig_y = figure.pos_y - @pos_y

  (0..figure.size_x-1).map do |x|
    column_height = 0

    figure.matrix.each_with_index do |row, y|
      column_height = y + 1 if row[x]
    end

    lowest_point = fig_y + column_height

    x += fig_x
    distance = HEIGHT - lowest_point

    # checking if it interescts with any existing blocks
    (lowest_point..HEIGHT-1).each do |y|
      if @matrix[y][x] != nil
        distance = y - lowest_point
        break
      end
    end

    distance
  end.min
end