Class: Tetris::Model::Game

Inherits:
Object
  • Object
show all
Defined in:
lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb

Constant Summary collapse

PLAYFIELD_WIDTH =
10
PLAYFIELD_HEIGHT =
20
PREVIEW_PLAYFIELD_WIDTH =
4
PREVIEW_PLAYFIELD_HEIGHT =
2
SCORE_MULTIPLIER =
{1 => 40, 2 => 100, 3 => 300, 4 => 1200}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(playfield_width = PLAYFIELD_WIDTH, playfield_height = PLAYFIELD_HEIGHT) ⇒ Game

Returns a new instance of Game.



46
47
48
49
50
51
52
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 46

def initialize(playfield_width = PLAYFIELD_WIDTH, playfield_height = PLAYFIELD_HEIGHT)
  @playfield_width = playfield_width
  @playfield_height = playfield_height
  @high_scores = []
  @show_high_scores = false
  @up_arrow_action = :rotate_left
end

Instance Attribute Details

#added_high_scoreObject Also known as: added_high_score?

Returns the value of attribute added_high_score.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def added_high_score
  @added_high_score
end

#game_overObject Also known as: game_over?

Returns the value of attribute game_over.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def game_over
  @game_over
end

#high_scoresObject

Returns the value of attribute high_scores.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def high_scores
  @high_scores
end

#levelObject

Returns the value of attribute level.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def level
  @level
end

#linesObject

Returns the value of attribute lines.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def lines
  @lines
end

#pausedObject Also known as: paused?

Returns the value of attribute paused.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def paused
  @paused
end

#playfield_heightObject (readonly)

Returns the value of attribute playfield_height.



40
41
42
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 40

def playfield_height
  @playfield_height
end

#playfield_widthObject (readonly)

Returns the value of attribute playfield_width.



40
41
42
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 40

def playfield_width
  @playfield_width
end

#preview_tetrominoObject

Returns the value of attribute preview_tetromino.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def preview_tetromino
  @preview_tetromino
end

#scoreObject

Returns the value of attribute score.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def score
  @score
end

#show_high_scoresObject

Returns the value of attribute show_high_scores.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def show_high_scores
  @show_high_scores
end

#up_arrow_actionObject

Returns the value of attribute up_arrow_action.



41
42
43
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 41

def up_arrow_action
  @up_arrow_action
end

Instance Method Details

#add_high_score!Object



82
83
84
85
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 82

def add_high_score!
  self.added_high_score = true
  high_scores.prepend(PastGame.new("Player #{high_scores.count + 1}", score, lines, level))
end

#calculate_score!(eliminated_lines) ⇒ Object



165
166
167
168
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 165

def calculate_score!(eliminated_lines)
  new_score = SCORE_MULTIPLIER[eliminated_lines] * (level + 1)
  self.score += new_score
end

#clear_high_scores!Object



78
79
80
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 78

def clear_high_scores!
  high_scores.clear
end

#consider_adding_tetrominoObject



222
223
224
225
226
227
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 222

def consider_adding_tetromino
  if tetrominoes.empty? || current_tetromino.stopped?
    preview_tetromino.launch!
    preview_next_tetromino!
  end
end

#consider_eliminating_linesObject



229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 229

def consider_eliminating_lines
  eliminated_lines = 0
  playfield.each_with_index do |row, playfield_row|
    if row.all? {|block| !block.clear?}
      eliminated_lines += 1
      shift_blocks_down_above_row(playfield_row)
    end
  end
  if eliminated_lines > 0
    self.lines += eliminated_lines
    level_up!
    calculate_score!(eliminated_lines)
  end
end

#current_tetrominoObject



116
117
118
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 116

def current_tetromino
  tetrominoes.last
end

#delayObject



174
175
176
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 174

def delay
  [1.1 - (level.to_i * 0.1), 0.001].max
end

#down!(instant: false) ⇒ Object



95
96
97
98
99
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 95

def down!(instant: false)
  return unless game_in_progress?
  current_tetromino.down!(instant: instant)
  game_over! if current_tetromino.row <= 0 && current_tetromino.stopped?
end

#game_in_progress?Boolean

Returns:

  • (Boolean)


54
55
56
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 54

def game_in_progress?
  !game_over? && !paused?
end

#game_over!Object



73
74
75
76
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 73

def game_over!
  add_high_score!
  self.game_over = true
end

#hypothetical(&block) ⇒ Object

Executes a hypothetical scenario without truly changing playfield permanently



134
135
136
137
138
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 134

def hypothetical(&block)
  @playfield = hypothetical_playfield
  block.call
  @playfield = @original_playfield
end

#hypothetical?Boolean

Returns whether currently executing a hypothetical scenario

Returns:

  • (Boolean)


141
142
143
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 141

def hypothetical?
  @playfield != @original_playfield
end

#hypothetical_playfieldObject



145
146
147
148
149
150
151
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 145

def hypothetical_playfield
  @playfield_height.times.map { |row|
    @playfield_width.times.map { |column|
      playfield[row][column].clone
    }
  }
end

#instant_down_on_upObject



182
183
184
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 182

def instant_down_on_up
  self.up_arrow_action == :instant_down
end

#instant_down_on_up=(value) ⇒ Object



178
179
180
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 178

def instant_down_on_up=(value)
  self.up_arrow_action = :instant_down if value
end

#left!Object



106
107
108
109
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 106

def left!
  return unless game_in_progress?
  current_tetromino.left!
end

#level_up!Object



170
171
172
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 170

def level_up!
  self.level += 1 if lines >= self.level*10
end

#playfieldObject

Returns blocks in the playfield



125
126
127
128
129
130
131
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 125

def playfield
  @playfield ||= @original_playfield = @playfield_height.times.map {
    @playfield_width.times.map {
      Block.new
    }
  }
end

#playfield_remaining_heights(tetromino = nil) ⇒ Object



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 244

def playfield_remaining_heights(tetromino = nil)
  @playfield_width.times.map do |playfield_column|
    bottom_most_block = tetromino.bottom_most_block_for_column(playfield_column)
    (playfield.each_with_index.detect do |row, playfield_row|
      !row[playfield_column].clear? &&
      (
        tetromino.nil? ||
        bottom_most_block.nil? ||
        (playfield_row > tetromino.row + bottom_most_block[:row_index])
      )
    end || [nil, @playfield_height])[1]
  end.to_a
end

#preview_next_tetromino!Object



161
162
163
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 161

def preview_next_tetromino!
  self.preview_tetromino = Tetromino.new(self)
end

#preview_playfieldObject



153
154
155
156
157
158
159
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 153

def preview_playfield
  @preview_playfield ||= PREVIEW_PLAYFIELD_HEIGHT.times.map {|row|
    PREVIEW_PLAYFIELD_WIDTH.times.map {|column|
      Block.new
    }
  }
end

#reset_playfieldObject



206
207
208
209
210
211
212
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 206

def reset_playfield
  playfield.each do |row|
    row.each do |block|
      block.clear
    end
  end
end

#reset_preview_playfieldObject



214
215
216
217
218
219
220
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 214

def reset_preview_playfield
  preview_playfield.each do |row|
    row.each do |block|
      block.clear
    end
  end
end

#reset_tetrominoesObject



202
203
204
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 202

def reset_tetrominoes
  @tetrominoes = []
end

#right!Object



101
102
103
104
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 101

def right!
  return unless game_in_progress?
  current_tetromino.right!
end

#rotate!(direction) ⇒ Object



111
112
113
114
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 111

def rotate!(direction)
  return unless game_in_progress?
  current_tetromino.rotate!(direction)
end

#rotate_left_on_upObject



198
199
200
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 198

def rotate_left_on_up
  self.up_arrow_action == :rotate_left
end

#rotate_left_on_up=(value) ⇒ Object



194
195
196
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 194

def rotate_left_on_up=(value)
  self.up_arrow_action = :rotate_left if value
end

#rotate_right_on_upObject



190
191
192
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 190

def rotate_right_on_up
  self.up_arrow_action == :rotate_right
end

#rotate_right_on_up=(value) ⇒ Object



186
187
188
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 186

def rotate_right_on_up=(value)
  self.up_arrow_action = :rotate_right if value
end

#start!Object Also known as: restart!



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 58

def start!
  self.show_high_scores = false
  self.paused = false
  self.level = 1
  self.score = 0
  self.lines = 0
  reset_playfield
  reset_preview_playfield
  reset_tetrominoes
  preview_next_tetromino!
  consider_adding_tetromino
  self.game_over = false
end

#tetris_dirObject



87
88
89
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 87

def tetris_dir
  @tetris_dir ||= File.join(File.expand_path('~'), '.glimmer-tetris')
end

#tetris_high_score_fileObject



91
92
93
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 91

def tetris_high_score_file
  File.join(tetris_dir, "high_scores.txt")
end

#tetrominoesObject



120
121
122
# File 'lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb', line 120

def tetrominoes
  @tetrominoes ||= reset_tetrominoes
end