Skip to content

Instantly share code, notes, and snippets.

@ngw
Last active July 7, 2019 17:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ngw/9814e04ac4cc1de08b0b10bf2742eca9 to your computer and use it in GitHub Desktop.
Save ngw/9814e04ac4cc1de08b0b10bf2742eca9 to your computer and use it in GitHub Desktop.
module Minesweeper
class Board
DIFFICULTIES = {easy: 25, medium: 50, hard: 75}
attr_reader :panel
def initialize(width:, height:, difficulty:)
@width = width
@height = height
@difficulty = DIFFICULTIES[difficulty]
populate
end
def to_s
output = ""
@panel.each do |row|
row.each do |tile|
output << tile.to_s
end
output << "\n"
end
output
end
private
def populate
@panel = Array.new(@height) do |y|
Array.new(@width) do |x|
Tile.new(x: x, y: y)
end
end
mine_panel!
calculate_neighbours!
end
def area
@width * @height
end
def number_of_mines
((area.to_f / 100.0) * @difficulty).to_i
end
def mine_panel!
count = number_of_mines
while count != 0
x, y = rand(@width), rand(@height)
tile = @panel[y][x]
unless tile.mine
tile.mine = true
count -= 1
end
end
end
def calculate_neighbours!
@panel.map.with_index do |row, i|
row.map.with_index do |tile, z|
next if tile.mine
tile.neighbours = calculate_neighbours(y: i, x: z)
end
end
end
def calculate_neighbours(y:, x:)
count = 0
[-1, 0, 1].product([-1, 0, 1]).each do |k, j|
if @panel[y + k] && @panel[y + k][x + j]
tile = @panel[y + k][x + j]
count += 1 if tile.mine == true
end
end
count
end
end
end
module Minesweeper
class Tile
attr_reader :x, :y
attr_accessor :mine, :neighbours
def initialize(x:, y:)
@x = x
@y = y
@mine = false
@neighbours = 0
end
def to_s
if @mine
"*"
else
@neighbours.to_s
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment