class Minesweeprb::Game
Constants
- LOSE
- SPRITES
- WIN
Attributes
active_square[RW]
flagged_squares[R]
height[R]
marked_squares[R]
mines[R]
revealed_squares[R]
start_time[R]
width[R]
Public Class Methods
new(label:, width:, height:, mines:)
click to toggle source
# File lib/minesweeprb/game.rb, line 28 def initialize(label:, width:, height:, mines:) @width = width @height = height @mines = mines restart end
Public Instance Methods
active_square=(pos)
click to toggle source
# File lib/minesweeprb/game.rb, line 79 def active_square=(pos) x, y = pos x = x < 0 ? width - 1 : x x = x > width - 1 ? 0 : x y = y < 0 ? height - 1 : y y = y > height - 1 ? 0 : y @active_square = [x,y] end
center()
click to toggle source
# File lib/minesweeprb/game.rb, line 50 def center [(width / 2).floor, (height / 2).floor] end
cycle_flag()
click to toggle source
# 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_time()
click to toggle source
# File lib/minesweeprb/game.rb, line 54 def end_time @end_time || now end
face()
click to toggle source
# 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_message()
click to toggle source
# File lib/minesweeprb/game.rb, line 162 def game_over_message won? ? WIN : LOSE end
header()
click to toggle source
# 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?()
click to toggle source
# File lib/minesweeprb/game.rb, line 154 def lost? (revealed_squares & @mined_squares).any? end
move(direction)
click to toggle source
# 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?()
click to toggle source
# File lib/minesweeprb/game.rb, line 158 def over? won? || lost? end
play_grid()
click to toggle source
# 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_mines()
click to toggle source
# File lib/minesweeprb/game.rb, line 46 def remaining_mines mines - flagged_squares.length end
restart()
click to toggle source
# 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_square()
click to toggle source
# 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?()
click to toggle source
# File lib/minesweeprb/game.rb, line 146 def started? !over? && revealed_squares.count > 0 end
time()
click to toggle source
# File lib/minesweeprb/game.rb, line 58 def time return 0 unless start_time end_time - start_time end
won?()
click to toggle source
# File lib/minesweeprb/game.rb, line 150 def won? !lost? && revealed_squares.count == width * height - mines end
Private Instance Methods
lose!()
click to toggle source
# File lib/minesweeprb/game.rb, line 218 def lose! @revealed_squares |= @mined_squares end
neighbors(x,y)
click to toggle source
# File lib/minesweeprb/game.rb, line 222 def neighbors(x,y) [ # top [x - 1, y - 1], [x - 0, y - 1], [x + 1, y - 1], # sides [x - 1, y - 0], [x + 1, y - 0], # bottom [x - 1, y + 1], [x - 0, y + 1], [x + 1, y + 1], ].select do |x,y| x.between?(0, width-1) && y.between?(0, height-1) end end
now()
click to toggle source
# File lib/minesweeprb/game.rb, line 168 def now Process.clock_gettime(Process::CLOCK_MONOTONIC) end
place_clues()
click to toggle source
# File lib/minesweeprb/game.rb, line 192 def place_clues width.times do |x| height.times do |y| @grid[y][x] = square_value(x,y) end end end
place_mines()
click to toggle source
# File lib/minesweeprb/game.rb, line 178 def place_mines mines.times do pos = random_square pos = random_square while pos == active_square || @mined_squares.include?(pos) @mined_squares << pos end end
random_square()
click to toggle source
# File lib/minesweeprb/game.rb, line 186 def random_square x = (1..width).to_a.sample - 1 y = (1..height).to_a.sample - 1 [x, y] end
reveal_square(x,y)
click to toggle source
# File lib/minesweeprb/game.rb, line 206 def reveal_square(x,y) square = [x,y] return if over? || flagged_squares.include?(active_square) start_game if revealed_squares.empty? return if revealed_squares.include?(square) return lose! if @mined_squares.include?(square) @revealed_squares << [x,y] value = @grid[y][x] neighbors(x,y).each { |x,y| reveal_square(x,y) } if value == 0 end
square_value(x,y)
click to toggle source
# File lib/minesweeprb/game.rb, line 200 def square_value(x,y) return if @mined_squares.include?([x,y]) (neighbors(x,y) & @mined_squares).length end
start_game()
click to toggle source
# File lib/minesweeprb/game.rb, line 172 def start_game place_mines place_clues @start_time = now end