Class: Minesweeprb::Game

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

Constant Summary collapse

SPRITES =
{
  clock: '',
  clues: '◻➊➋➌➍➎➏➐➑'.chars.freeze,
  flag: '',
  lose_face: '',
  mark: '',
  mine: '',
  play_face: '',
  square: '',
  win_face: '',
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(width:, height:, mines:, label: nil, sprites: SPRITES) ⇒ Game

rubocop:disable Lint/UnusedMethodArgument



27
28
29
30
31
32
33
# File 'lib/minesweeprb/game.rb', line 27

def initialize(width:, height:, mines:, label: nil, sprites: SPRITES) # rubocop:disable Lint/UnusedMethodArgument
  @width = width
  @height = height
  @mines = mines
  @sprites = sprites
  restart
end

Instance Attribute Details

#active_squareObject

Returns the value of attribute active_square.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def active_square
  @active_square
end

#flagged_squaresObject (readonly)

Returns the value of attribute flagged_squares.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def flagged_squares
  @flagged_squares
end

#heightObject (readonly)

Returns the value of attribute height.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def height
  @height
end

#marked_squaresObject (readonly)

Returns the value of attribute marked_squares.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def marked_squares
  @marked_squares
end

#minesObject (readonly)

Returns the value of attribute mines.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def mines
  @mines
end

#revealed_squaresObject (readonly)

Returns the value of attribute revealed_squares.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def revealed_squares
  @revealed_squares
end

#spritesObject (readonly)

Returns the value of attribute sprites.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def sprites
  @sprites
end

#start_timeObject (readonly)

Returns the value of attribute start_time.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def start_time
  @start_time
end

#widthObject (readonly)

Returns the value of attribute width.



17
18
19
# File 'lib/minesweeprb/game.rb', line 17

def width
  @width
end

Instance Method Details

#centerObject



50
51
52
# File 'lib/minesweeprb/game.rb', line 50

def center
  [(width / 2).floor, (height / 2).floor]
end

#cycle_flagObject



116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/minesweeprb/game.rb', line 116

def cycle_flag
  return if over? || revealed_squares.empty? || revealed_squares.include?(active_square)

  if flagged_squares.include?(active_square)
    @flagged_squares -= [active_square]
    @marked_squares += [active_square]
  elsif marked_squares.include?(active_square)
    @marked_squares -= [active_square]
  elsif flagged_squares.length < mines
    @flagged_squares += [active_square]
  end
end

#end_timeObject



54
55
56
# File 'lib/minesweeprb/game.rb', line 54

def end_time
  @end_time || now
end

#faceObject



89
90
91
92
93
94
95
96
97
# File 'lib/minesweeprb/game.rb', line 89

def face
  if won?
    sprites[:win_face]
  elsif lost?
    sprites[:lose_face]
  else
    sprites[:play_face]
  end
end

#game_over_messageObject



173
174
175
176
177
178
179
# File 'lib/minesweeprb/game.rb', line 173

def game_over_message
  if won?
    "#{sprites[:win_face]} YOU WON #{sprites[:win_face]}"
  else
    "#{sprites[:lose_face]} GAME OVER #{sprites[:lose_face]}"
  end
end

#headerObject



99
100
101
102
103
# File 'lib/minesweeprb/game.rb', line 99

def header
  "#{sprites[:mine]} #{remaining_mines.to_s.rjust(3, '0')}  " \
    "#{face}  " \
    "#{sprites[:clock]} #{time.round.to_s.rjust(3, '0')}"
end

#header_segmentsObject



105
106
107
108
109
110
111
112
113
114
# File 'lib/minesweeprb/game.rb', line 105

def header_segments
  [
    [:mine, sprites[:mine]],
    [nil, " #{remaining_mines.to_s.rjust(3, '0')}  "],
    [:face, face],
    [nil, '  '],
    [:clock, sprites[:clock]],
    [nil, " #{time.round.to_s.rjust(3, '0')}"],
  ]
end

#lost?Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/minesweeprb/game.rb', line 165

def lost?
  revealed_squares.intersect?(@mined_squares)
end

#move(direction) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/minesweeprb/game.rb', line 64

def move(direction)
  return if over?

  x, y = active_square

  case direction
  when :up then y -= 1
  when :down then y += 1
  when :left then x -= 1
  when :right then x += 1
  end

  self.active_square = [x, y]
end

#over?Boolean

Returns:

  • (Boolean)


169
170
171
# File 'lib/minesweeprb/game.rb', line 169

def over?
  won? || lost?
end

#play_gridObject



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/minesweeprb/game.rb', line 137

def play_grid
  height.times.map do |y|
    width.times.map do |x|
      square = [x, y]

      if @mined_squares.include?(square) && (revealed_squares.include?(square) || over?)
        sprites[:mine]
      elsif revealed_squares.include?(square) || over?
        sprites[:clues][@grid[y][x]]
      elsif flagged_squares.include?(square)
        sprites[:flag]
      elsif marked_squares.include?(square)
        sprites[:mark]
      else
        sprites[:square]
      end
    end
  end
end

#remaining_minesObject



46
47
48
# File 'lib/minesweeprb/game.rb', line 46

def remaining_mines
  mines - flagged_squares.length
end

#restartObject



35
36
37
38
39
40
41
42
43
44
# File 'lib/minesweeprb/game.rb', line 35

def restart
  @active_square = center
  @flagged_squares = []
  @marked_squares = []
  @mined_squares = []
  @revealed_squares = []
  @grid = Array.new(height) { Array.new(width) }
  @start_time = nil
  @end_time = nil
end

#reveal_active_squareObject



129
130
131
132
133
134
135
# File 'lib/minesweeprb/game.rb', line 129

def reveal_active_square
  return if over? || flagged_squares.include?(active_square)

  x, y = active_square
  reveal_square(x, y)
  @end_time = now if over?
end

#started?Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/minesweeprb/game.rb', line 157

def started?
  !over? && revealed_squares.any?
end

#timeObject



58
59
60
61
62
# File 'lib/minesweeprb/game.rb', line 58

def time
  return 0 unless start_time

  end_time - start_time
end

#won?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/minesweeprb/game.rb', line 161

def won?
  !lost? && revealed_squares.count == (width * height) - mines
end