Skip to content

Commit 25b7fe7

Browse files
committed
Add ruby solution
1 parent 74e89d0 commit 25b7fe7

File tree

7 files changed

+199
-0
lines changed

7 files changed

+199
-0
lines changed

ruby/bin/minesweeper

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env ruby
2+
3+
require_relative '../src/minesweeper.rb'
4+
require_relative '../src/minesweeper_helpers.rb'
5+
6+
lines_to_fields(ARGF).each_with_index do |field, i|
7+
puts "Field #{i+1}:\n"
8+
(0..field.length-1).each do |y|
9+
puts ((0..field.width-1).map do |x|
10+
c = Coord.new(x, y)
11+
if field.boom(c)
12+
'*'
13+
else
14+
field.hint(c)
15+
end
16+
end).join('')
17+
end
18+
end

ruby/bin/minesweeper_done

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env ruby
2+
3+
require_relative '../src/minesweeper.rb'
4+
5+
y = nil
6+
fields = []
7+
field = nil
8+
9+
ARGF.each do |line|
10+
if y.nil? or y == field.length
11+
raise "Invalid input: Expected W L" unless line =~ /^(\d+) (\d+)$/
12+
break if $1.to_i == 0 and $2.to_i == 0
13+
field = MineField.new($2.to_i, $1.to_i)
14+
fields.push(field)
15+
y = 0
16+
else
17+
(0..field.width-1).each do |x|
18+
if line[x] == '*'
19+
field.drop_mine(Coord.new(x, y))
20+
end
21+
end
22+
y += 1
23+
end
24+
end
25+
26+
fields.each_with_index do |field, i|
27+
puts "Field #{i+1}:\n"
28+
(0..field.length-1).each do |y|
29+
puts ((0..field.width-1).map do |x|
30+
c = Coord.new(x, y)
31+
if field.boom(c)
32+
'*'
33+
else
34+
field.hint(c)
35+
end
36+
end).join('')
37+
end
38+
end

ruby/src/minesweeper.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
class MineField
2+
attr_reader :width
3+
attr_reader :length
4+
5+
def initialize(width, length)
6+
@width = width
7+
@length = length
8+
@mines = []
9+
end
10+
11+
def drop_mine(coord)
12+
raise "coord.x must less than #{@width}" unless coord.x < @width
13+
raise "coord.y must less than #{@length}" unless coord.y < @length
14+
15+
@mines.push coord
16+
end
17+
18+
def boom(coord)
19+
@mines.any? do |mine|
20+
mine == coord
21+
end
22+
end
23+
24+
def hint(coord)
25+
h = 0
26+
27+
@mines.each do |mine|
28+
h += 1 if mine.adjacent_to(coord)
29+
end
30+
31+
h
32+
end
33+
end
34+
35+
class Coord
36+
attr_reader :x
37+
attr_reader :y
38+
39+
def initialize(x, y)
40+
raise "x must be greater or equal to 0" unless x >= 0
41+
raise "y must be greater or equal to 0" unless y >= 0
42+
43+
@x = x
44+
@y = y
45+
end
46+
47+
def adjacent_to(coord)
48+
(@x - coord.x).abs <= 1 and
49+
(@y - coord.y).abs <= 1 and
50+
self != coord
51+
end
52+
53+
def ==(coord)
54+
coord.x == @x and coord.y == @y
55+
end
56+
end

ruby/src/minesweeper_helpers.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
def lines_to_fields(lines)
2+
y = nil
3+
fields = []
4+
field = nil
5+
6+
lines.each do |line|
7+
if y.nil? or y == field.length
8+
raise "Invalid input: Expected W L" unless line =~ /^(\d+) (\d+)$/
9+
break if $1.to_i == 0 and $2.to_i == 0
10+
field = MineField.new($2.to_i, $1.to_i)
11+
fields.push(field)
12+
y = 0
13+
else
14+
(0..field.width-1).each do |x|
15+
if line[x] == '*'
16+
field.drop_mine(Coord.new(x, y))
17+
end
18+
end
19+
y += 1
20+
end
21+
end
22+
23+
fields
24+
end

ruby/test.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
4 4
2+
*...
3+
....
4+
.*..
5+
....
6+
3 5
7+
**...
8+
.....
9+
.*...
10+
0 0

ruby/test/test_minesweeper.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
require "minitest/autorun"
2+
require_relative "../src/minesweeper.rb"
3+
4+
class TestMinesweeper < Minitest::Test
5+
def test_coords()
6+
assert(Coord.new(1, 1).adjacent_to(Coord.new(1, 0)))
7+
assert(Coord.new(1, 1).adjacent_to(Coord.new(0, 1)))
8+
assert(Coord.new(1, 1).adjacent_to(Coord.new(2, 2)))
9+
10+
assert(!Coord.new(1, 1).adjacent_to(Coord.new(1, 1)))
11+
assert(!Coord.new(1, 1).adjacent_to(Coord.new(2, 3)))
12+
end
13+
14+
def test_field()
15+
field = MineField.new(4, 4)
16+
field.drop_mine(Coord.new(2, 2))
17+
18+
assert_equal(1, field.hint(Coord.new(1, 2)))
19+
assert_equal(1, field.hint(Coord.new(3, 3)))
20+
assert_equal(0, field.hint(Coord.new(0, 2)))
21+
end
22+
end

ruby/test/test_minesweeper_helpers.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
require "minitest/autorun"
2+
require_relative "../src/minesweeper.rb"
3+
require_relative "../src/minesweeper_helpers.rb"
4+
5+
class TestMinesweeperHelpers < Minitest::Test
6+
def test_lines_to_fields
7+
fields = lines_to_fields([
8+
'4 4',
9+
'*...',
10+
'....',
11+
'.*..',
12+
'....',
13+
'3 5',
14+
'**...',
15+
'.....',
16+
'.*...',
17+
'0 0'
18+
])
19+
20+
assert_equal(2, fields.length)
21+
22+
assert(fields[0].boom(Coord.new(0, 0)))
23+
assert(fields[0].boom(Coord.new(2, 1)))
24+
assert(!fields[0].boom(Coord.new(2, 2)))
25+
26+
assert(fields[1].boom(Coord.new(0, 0)))
27+
assert(fields[1].boom(Coord.new(0, 1)))
28+
assert(fields[1].boom(Coord.new(2, 1)))
29+
assert(!fields[1].boom(Coord.new(2, 2)))
30+
end
31+
end

0 commit comments

Comments
 (0)