Created
August 27, 2017 11:03
-
-
Save elmendalerenda/156edc41e2ba42d0c24e540286399e18 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "minitest/autorun" | |
class TestMine < Minitest::Test | |
def test_1 | |
field = '*' | |
expected_result = '*' | |
assert_equal expected_result, minesweeper(1, 1, field) | |
end | |
def test_2 | |
field = '.*.' | |
expected_result = '1*1' | |
assert_equal expected_result, minesweeper(1, 3, field) | |
end | |
def test_3 | |
field = "...\n.*." | |
expected_result = "111\n1*1" | |
assert_equal expected_result, minesweeper(2, 3, field) | |
end | |
def test_4 | |
field = "...\n...\n..*" | |
expected_result = "000\n011\n01*" | |
assert_equal expected_result, minesweeper(3, 3, field) | |
end | |
def test_5 | |
field = "*..\n..*" | |
expected_result = "*21\n12*" | |
assert_equal expected_result, minesweeper(2, 3, field) | |
end | |
def test_6 | |
field = "*..\n..*\n..." | |
expected_result = "*21\n12*\n011" | |
assert_equal expected_result, minesweeper(3, 3, field) | |
end | |
def test_7 | |
field = "*..\n*.." | |
expected_result = "*20\n*20" | |
assert_equal expected_result, minesweeper(2, 3, field) | |
end | |
end | |
MINE = '*' | |
NO_MINE = '.' | |
MINE_HINT = '*' | |
HINT = '1' | |
NO_HINT = '0' | |
ROW_SEPARATOR = "\n" | |
def minesweeper(rows, cols, field) | |
hint_maps = each_mine(field) do |mine_pos| | |
create_hint_map(field, mine_pos, rows, cols) | |
end | |
merge_maps(hint_maps) | |
end | |
def each_mine(field, &block) | |
mine_pos = -1 | |
mines_count = 1..field.count(MINE) | |
mines_count.map do | |
mine_pos = field.index(MINE, mine_pos + 1) | |
yield(mine_pos) | |
end | |
end | |
def create_hint_map(field, mine_pos, rows, cols) | |
hint_map = create_empty_hint_map_with_border(field, cols) | |
mine_pos_with_border = add_border_offset(mine_pos, cols) | |
add_hints(hint_map, mine_pos_with_border, cols) | |
remove_border(hint_map, rows, cols) | |
end | |
def merge_maps(maps) | |
maps.reduce do |merged, map| | |
merge(merged, map) | |
end | |
end | |
def remove_border(hint_map, rows, cols) | |
border_per_row = 2 | |
hint_map_without_upper_border = hint_map[cols+border_per_row .. -1] | |
(0..rows-1).map { |row| | |
start = row * cols + row * border_per_row + 1 | |
hint_map_without_upper_border[start, cols] | |
}.join(ROW_SEPARATOR) | |
end | |
def create_empty_hint_map_with_border(field, cols) | |
empty_row = NO_HINT * (cols + 2) | |
left_right_border = /$|^/ | |
hint_map = field.gsub(left_right_border, NO_HINT) | |
hint_map = hint_map.tr(NO_MINE, NO_HINT) | |
hint_map = hint_map.tr(ROW_SEPARATOR, '') | |
empty_row + hint_map + empty_row | |
end | |
def add_hints(hint_map, pos, cols) | |
add_hint(hint_map, pos - cols - 1) | |
add_hint(hint_map, pos - cols - 2) | |
add_hint(hint_map, pos - cols - 3) | |
add_hint(hint_map, pos + cols + 1) | |
add_hint(hint_map, pos + cols + 2) | |
add_hint(hint_map, pos + cols + 3) | |
add_hint(hint_map, pos - 1) | |
add_hint(hint_map, pos + 1) | |
end | |
def merge(a_field, another_field) | |
[a_field.chars, another_field.chars].transpose.map do |cell| | |
cell.reduce do |sum, value| | |
begin | |
(Integer(value) + Integer(sum)).to_s | |
rescue | |
value | |
end | |
end | |
end.join | |
end | |
def add_border_offset(pos, cols) | |
separator_per_line = ROW_SEPARATOR.length | |
upper_border = cols + 2 | |
cols_with_separator = cols + separator_per_line | |
offset = upper_border + separator_per_line + (pos / cols_with_separator) | |
pos + offset | |
end | |
def add_hint(hint_map, pos) | |
valid_hint_pos = hint_map[pos] == NO_HINT | |
if(valid_hint_pos) | |
hint_map[pos] = HINT | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment