class Tetris::Model::Game

Constants

PLAYFIELD_HEIGHT
PLAYFIELD_WIDTH
PREVIEW_PLAYFIELD_HEIGHT
PREVIEW_PLAYFIELD_WIDTH
SCORE_MULTIPLIER

Attributes

added_high_score[RW]
added_high_score?[RW]
game_over[RW]
game_over?[RW]
high_scores[RW]
level[RW]
lines[RW]
paused[RW]
paused?[RW]
playfield_height[R]
playfield_width[R]
preview_tetromino[RW]
score[RW]
show_high_scores[RW]
up_arrow_action[RW]

Public Class Methods

new(playfield_width = PLAYFIELD_WIDTH, playfield_height = PLAYFIELD_HEIGHT) click to toggle source
# 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

Public Instance Methods

add_high_score!() click to toggle source
# 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) click to toggle source
# 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!() click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 78
def clear_high_scores!
  high_scores.clear
end
consider_adding_tetromino() click to toggle source
# 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_lines() click to toggle source
# 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_tetromino() click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 116
def current_tetromino
  tetrominoes.last
end
delay() click to toggle source
# 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) click to toggle source
# 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?() click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 54
def game_in_progress?
  !game_over? && !paused?
end
game_over!() click to toggle source
# 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) click to toggle source

Executes a hypothetical scenario without truly changing playfield permanently

# 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?() click to toggle source

Returns whether currently executing a hypothetical scenario

# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 141
def hypothetical?
  @playfield != @original_playfield
end
hypothetical_playfield() click to toggle source
# 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_up() click to toggle source
# 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) click to toggle source
# 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!() click to toggle source
# 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!() click to toggle source
# 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
playfield() click to toggle source

Returns blocks in the playfield

# 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) click to toggle source
# 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!() click to toggle source
# 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_playfield() click to toggle source
# 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_playfield() click to toggle source
# 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_playfield() click to toggle source
# 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_tetrominoes() click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 202
def reset_tetrominoes
  @tetrominoes = []
end
restart!()
Alias for: start!
right!() click to toggle source
# 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) click to toggle source
# 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_up() click to toggle source
# 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) click to toggle source
# 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_up() click to toggle source
# 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) click to toggle source
# 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!() click to toggle source
# 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
Also aliased as: restart!
tetris_dir() click to toggle source
# 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_file() click to toggle source
# 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
tetrominoes() click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 120
def tetrominoes
  @tetrominoes ||= reset_tetrominoes
end

Private Instance Methods

shift_blocks_down_above_row(row) click to toggle source
# File lib/glimmer-dsl-opal/samples/elaborate/tetris/model/game.rb, line 260
def shift_blocks_down_above_row(row)
  row.downto(0) do |playfield_row|
     playfield[playfield_row].each_with_index do |block, playfield_column|
       previous_row = playfield[playfield_row - 1]
       previous_block = previous_row[playfield_column]
       block.color = previous_block.color unless block.color == previous_block.color
     end
  end
  playfield[0].each(&:clear)
end