Class: Minesweeprb::Game

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

Constant Summary collapse

SPRITES =
{
  clock: '',
  clues: '◻➊➋➌➍➎➏➐➑'.chars.freeze,
  flag: '', # ⚑ Flag does not work in curses?
  lose_face: '',
  mark: '',
  mine: '',
  play_face: '',
  square: '',
  win_face: '',
}.freeze
WIN =
"#{SPRITES[:win_face]} YOU WON #{SPRITES[:win_face]}"
LOSE =
"#{SPRITES[:lose_face]} GAME OVER #{SPRITES[:lose_face]}"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

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

Returns a new instance of Game.



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

def initialize(label:, width:, height:, mines:)
  @width = width
  @height = height
  @mines = mines
  restart
end

Instance Attribute Details

#active_squareObject

Returns the value of attribute active_square.



19
20
21
# File 'lib/minesweeprb/game.rb', line 19

def active_square
  @active_square
end

#flagged_squaresObject (readonly)

Returns the value of attribute flagged_squares.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def flagged_squares
  @flagged_squares
end

#heightObject (readonly)

Returns the value of attribute height.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def height
  @height
end

#marked_squaresObject (readonly)

Returns the value of attribute marked_squares.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def marked_squares
  @marked_squares
end

#minesObject (readonly)

Returns the value of attribute mines.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def mines
  @mines
end

#revealed_squaresObject (readonly)

Returns the value of attribute revealed_squares.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def revealed_squares
  @revealed_squares
end

#start_timeObject (readonly)

Returns the value of attribute start_time.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

def start_time
  @start_time
end

#widthObject (readonly)

Returns the value of attribute width.



20
21
22
# File 'lib/minesweeprb/game.rb', line 20

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



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

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



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

def game_over_message
  won? ? WIN : LOSE
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

#lost?Boolean

Returns:

  • (Boolean)


154
155
156
# File 'lib/minesweeprb/game.rb', line 154

def lost?
  (revealed_squares & @mined_squares).any?
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)


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

def over?
  won? || lost?
end

#play_gridObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/minesweeprb/game.rb', line 126

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



118
119
120
121
122
123
124
# File 'lib/minesweeprb/game.rb', line 118

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)


146
147
148
# File 'lib/minesweeprb/game.rb', line 146

def started?
  !over? && revealed_squares.count > 0
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)


150
151
152
# File 'lib/minesweeprb/game.rb', line 150

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