Skip to content

Instantly share code, notes, and snippets.

@nerboda
Last active September 27, 2016 20:21
Show Gist options
  • Save nerboda/2332a227aa1a84dc3a044a54837b3e77 to your computer and use it in GitHub Desktop.
Save nerboda/2332a227aa1a84dc3a044a54837b3e77 to your computer and use it in GitHub Desktop.
Weekly Challenges - Minesweeper
# A custom error class for handling invalid minesweeper boards
class ValueError < StandardError; end
# Minesweeper Board
class Board
class << self
def transform(board)
raise ValueError, 'Invalid character' if invalid_char?(board)
raise ValueError, 'Unequal row lengths' if uneven_lengths?(board)
raise ValueError, 'Invalid border' if invalid_border?(board)
board.map.with_index do |row, row_index|
row[0] == '+' ? row : process_row(row, row_index, board)
end
end
private
def process_row(row, row_index, board)
output = row.chars.map.with_index do |char, char_index|
char == '|' ? char : process_char(row_index, char, char_index, board)
end
output.compact.join
end
def process_char(row_index, char, char_index, board)
adjacent_spaces = adjacent(row_index, char_index)
number_of_mines = mines(adjacent_spaces, board)
char == '*' || number_of_mines.zero? ? char : number_of_mines
end
def adjacent(row_index, char_index)
rows = row_index.zero? ? [0, 1] : (row_index - 1..row_index + 1).to_a
chars = char_index.zero? ? [0, 1] : (char_index - 1..char_index + 1).to_a
rows.product(chars).map do |combined|
{ row: combined[0], char: combined[1] }
end
end
def mines(spaces, board)
spaces.count { |space| board[space[:row]][space[:char]] == '*' }
end
def uneven_lengths?(board)
board.any? { |row| row.size != board.first.size }
end
def invalid_border?(board)
[board.first, board.last].any? { |border| border =~ /[^\+\-]/ }
end
def invalid_char?(board)
board[1..-2].any? { |row| row =~ /[^\|\s\*]/ }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment