ruby-go 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 99c7a4ed50ed990d7029979e84ff6c18338577f2
4
- data.tar.gz: 12c6da43266d2267faae29bfe7b121589e5c85d7
3
+ metadata.gz: bf963b32b745df2c152b2c7b3f29e71292087deb
4
+ data.tar.gz: 071b6bb76e230e17b17d5e3dfd7e21f19b78adae
5
5
  SHA512:
6
- metadata.gz: 7453628a08d3b1f1cf25e39fa2494eaeb085af2e1f986974467f2e51040c58ddd5a351e93fc363a4011cb0e3c9001aa0c48d918afc3a70ae52f299bcfb02dc0b
7
- data.tar.gz: 79eaf22114887997f545b5877ab3dcd19bc801b9fc8dd4b9e96d039d83e81400959a86b10ba1fec87b259f4a1b48d02d71f2bd21a4713114520addf51223993f
6
+ metadata.gz: a16e13bc9751e9542bb4fb619a41a7ca6b45a0265148f627d20902e58a4a43fae580ed35ba674a94b43e082414f6f75f2a2227fcff2a438d7bdf8bbc12a5922e
7
+ data.tar.gz: d99a7e2ad8758315f11b49351820e91a5cffdcc138de51e858e51d142a5c3c66babe417f84549802002c88a6ec3cdfba6572f48eda30f35fabe03882e0ff02b3
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '../lib/ruby-go'
4
4
 
5
- game = Game.new
5
+ game = RubyGo::Game.new
6
6
 
7
7
  def game.prompt_for_turn
8
8
  print "Pass or enter coordinates x, y for move (e.g. 4, 4): "
@@ -37,7 +37,7 @@ until game.passes >= 2
37
37
  game.view
38
38
 
39
39
  turn += 1
40
- rescue Game::IllegalMove
40
+ rescue RubyGo::Game::IllegalMove
41
41
  next
42
42
  end
43
43
  end
@@ -1,8 +1,10 @@
1
1
  require 'sgf'
2
2
 
3
+ require_relative 'ruby-go/liberty'
4
+ require_relative 'ruby-go/stone'
3
5
  require_relative 'ruby-go/board'
6
+ require_relative 'ruby-go/moves'
4
7
  require_relative 'ruby-go/game'
5
- require_relative 'ruby-go/stone'
6
8
 
7
9
  module RubyGo
8
10
  end
@@ -1,83 +1,89 @@
1
1
  module RubyGo
2
2
  class Board
3
- Colors = {black: 'x', white: 'o', empty: '_'}
3
+ COLORS = { black: 'x', white: 'o', empty: '_' }.freeze
4
+
5
+ attr_accessor :internal_board, :size
4
6
 
5
- attr_accessor :board
6
7
  def initialize(size)
7
- @board = []
8
- size -= 1
9
-
10
- 0.upto(size) do |y|
11
- row = []
12
- 0.upto(size) do |x|
13
- row << Liberty.new(x, y)
14
- end
15
- @board << row
16
- end
8
+ @internal_board = Array.new(size) { Array.new(size) { Liberty.new } }
9
+ @size = size
17
10
  end
18
11
 
19
- def size
20
- @board.length
21
- end
12
+ private :internal_board
22
13
 
23
14
  def empty?
24
- !@board.flatten.any? do |s|
25
- !s.empty?
26
- end
15
+ internal_board.flatten.all?(&:empty?)
27
16
  end
28
17
 
29
18
  def at(x, y)
30
- @board[y][x]
19
+ internal_board[y][x]
31
20
  end
32
21
 
33
- def around(x, y = :y_not_given)
34
- x, y = x.to_coord if x.kind_of?(Stone)
35
- stones = []
36
- stones << at(x-1, y) unless x == 0
37
- stones << at(x+1, y) unless x == (@board.length - 1)
38
- stones << at(x, y-1) unless y == 0
39
- stones << at(x, y+1) unless y == (@board.length - 1)
40
- stones
22
+ def around(x, y)
23
+ intersections = []
24
+
25
+ intersections << at(x-1, y) unless x == 0
26
+ intersections << at(x+1, y) unless x == (internal_board.length - 1)
27
+ intersections << at(x, y-1) unless y == 0
28
+ intersections << at(x, y+1) unless y == (internal_board.length - 1)
29
+ intersections
41
30
  end
42
31
 
43
32
  def remove(stone)
44
- stone.remove_from_board(self)
33
+ return if stone.empty?
34
+
35
+ x, y = stone.to_coord
36
+
37
+ internal_board[y][x] = Liberty.new
45
38
  end
46
39
 
40
+ # Board shouldn't care about game rules
47
41
  def place(stone)
48
- stone.place_on_board(self)
42
+ x, y = stone.to_coord
43
+
44
+ internal_board[y][x] = stone
49
45
  end
50
46
 
51
47
  def liberties(stone)
52
- group_of(stone).inject(0) do |libs, stn|
53
- libs + stn.liberties(self).count
48
+ libs = []
49
+
50
+ group_of(stone).each do |stn|
51
+ libs += around(*stn.to_coord).select(&:empty?)
54
52
  end
53
+
54
+ libs.uniq.length
55
55
  end
56
56
 
57
- def group_of(stone)
58
- stone.group(self)
57
+ def group_of(stone, stones = [])
58
+ return stones if stones.include?(stone)
59
+
60
+ stones << stone
61
+
62
+ around(*stone.to_coord).each do |intersection|
63
+ next if intersection.empty?
64
+
65
+ group_of(intersection, stones) if intersection.color == stone.color
66
+ end
67
+
68
+ stones
59
69
  end
60
70
 
61
- def to_str
71
+ def to_s
62
72
  out = ""
63
- if @board.length < 11
64
- out << "\s\s\s#{(0..@board.length - 1).to_a.join(' ')}\n"
73
+
74
+ if size < 11
75
+ out << "\s\s\s#{(0..size - 1).to_a.join(' ')}\n"
65
76
  else
66
- out <<
67
- "\s\s\s#{(0..10).to_a.join(' ')}" <<
68
- "#{(11..@board.length - 1).to_a.join('')}\n"
77
+ out << "\s\s\s#{(0..10).to_a.join(' ')}"
78
+ out << "#{(11..size - 1).to_a.join('')}\n"
69
79
  end
70
80
 
71
- @board.each_with_index do |row, i|
81
+ internal_board.each_with_index do |row, i|
72
82
  i = "\s#{i}" if i < 10
73
83
  out << "#{i}\s#{(row.collect {|stn| stn.to_s}).join(' ')}\n"
74
84
  end
75
85
 
76
86
  out
77
87
  end
78
-
79
- def to_s
80
- to_str
81
- end
82
88
  end
83
89
  end
@@ -1,14 +1,14 @@
1
1
  module RubyGo
2
- class Game
2
+ class Game
3
+ attr_reader :board, :moves
3
4
 
4
- LETTERS = ('a'..'z').to_a
5
-
6
- attr_reader :board
7
5
  def initialize(board: 19)
8
6
  @board = Board.new(board)
9
- @moves = []
7
+ @moves = Moves.new
10
8
  end
11
9
 
10
+ private :moves
11
+
12
12
  def save(name="my_go_game")
13
13
  tree = SGF::Parser.new.parse(to_sgf)
14
14
  tree.save(name + '.sgf')
@@ -17,27 +17,27 @@ module RubyGo
17
17
  def to_sgf
18
18
  sgf = "(;GM[1]FF[4]CA[UTF-8]AP[jphager2]SZ[#{board.size}]PW[White]PB[Black]"
19
19
 
20
- @moves.each do |move|
21
- sgf << move[:stone].to_sgf
20
+ moves.each do |move|
21
+ sgf << move.played.to_sgf
22
22
  end
23
23
 
24
24
  sgf << ')'
25
25
  end
26
26
 
27
27
  def view
28
- puts @board.to_s
29
- puts " " + "_"*(@board.size * 2)
28
+ puts board
29
+ puts " " + "_"*(board.size * 2)
30
30
  print " Prisoners || White: #{captures[:black]} |"
31
31
  puts " Black: #{captures[:white]}"
32
- puts " " + "-"*(@board.size * 2)
32
+ puts " " + "-"*(board.size * 2)
33
33
  end
34
34
 
35
35
  def black(x, y)
36
- play(BlackStone.new(x,y))
36
+ play(Stone.new(x, y, :black))
37
37
  end
38
38
 
39
39
  def white(x, y)
40
- play(WhiteStone.new(x,y))
40
+ play(Stone.new(x, y, :white))
41
41
  end
42
42
 
43
43
  def black_pass
@@ -48,79 +48,85 @@ module RubyGo
48
48
  pass(:white)
49
49
  end
50
50
 
51
- def pass(color)
52
- @moves << {stone: NullStone.new(color), captures: [], pass: true}
53
- end
51
+ def undo
52
+ move = moves.pop
54
53
 
55
- def undo
56
- move = @moves.pop
57
- @board.remove(move[:stone])
58
- move[:captures].each {|stone| @board.place(stone)}
54
+ board.remove(move.played)
55
+ move.captures.each do |stone|
56
+ board.place(stone)
57
+ end
59
58
  end
60
59
 
61
60
  def passes
62
- @moves.inject(0) {|total, move| move[:pass] ? total + 1 : 0}
63
- end
61
+ moves.pass_count
62
+ end
64
63
 
65
64
  def captures
66
- @moves.each_with_object({black: 0, white: 0}) do |move, total|
67
- move[:captures].each do |capture|
68
- total[capture.color] += 1
69
- end
70
- end
71
- end
65
+ moves.capture_count
66
+ end
72
67
 
73
68
  private
74
69
 
70
+ def pass(color)
71
+ moves.pass(NullStone.new(color))
72
+ end
73
+
75
74
  def play(stone)
76
- @board.place(stone)
77
- @moves << {stone: stone, captures: [], pass: false}
75
+ check_illegal_placement!(stone)
76
+
77
+ board.place(stone)
78
+ moves.play(stone)
79
+ record_captures!(stone)
78
80
 
79
- capture; suicide; ko
81
+ check_illegal_suicide!(stone)
82
+ check_illegal_ko!(stone)
80
83
  end
81
84
 
82
- def ko
83
- return if @moves.length < 2 or !@moves[-2][:captures]
85
+ def check_illegal_placement!(stone)
86
+ unless board.at(*stone.to_coord).empty?
87
+ raise(
88
+ Game::IllegalMove,
89
+ "You cannot place a stone on top of another stone."
90
+ )
91
+ end
92
+ end
84
93
 
85
- captures = @moves[-2][:captures]
86
- stone = @moves.last[:stone]
94
+ def check_illegal_ko!(stone)
95
+ last_move = moves.prev
87
96
 
88
- if captures == [stone]
97
+ return unless last_move
98
+
99
+ if last_move.captures == [stone] && moves.current.captures.one?
89
100
  undo
90
- raise IllegalMove,
101
+ raise IllegalMove,
91
102
  "You cannot capture the ko, play a ko threat first"
92
103
  end
93
104
  end
94
105
 
95
- def suicide
96
- stone = @moves.last[:stone]
97
- unless @board.liberties(stone) > 0
106
+ def check_illegal_suicide!(stone)
107
+ if board.liberties(stone).zero?
98
108
  undo
99
109
  raise IllegalMove, "You cannot play a suicide."
100
110
  end
101
111
  end
102
112
 
103
- def capture
104
- stone = @moves.last[:stone]
105
- stones_around = @board.around(stone)
106
-
107
- captures = stones_around.select {|stn| @board.liberties(stn) == 0}
113
+ def record_captures!(stone)
114
+ stones_around = board.around(*stone.to_coord).reject(&:empty?)
108
115
 
109
- captures.each {|stone| capture_group(stone)}
110
- end
116
+ captures = stones_around
117
+ .reject {| stn| stn.color == stone.color }
118
+ .select { |stn| @board.liberties(stn).zero? }
111
119
 
112
- def capture_group(stone)
113
- @board.group_of(stone).each {|stone| capture_stone(stone)}
120
+ captures.map {|stone| @board.group_of(stone)}
121
+ .flatten.uniq.each {|stone| capture_stone(stone)}
114
122
  end
115
123
 
116
124
  def capture_stone(stone)
117
- @moves.last[:captures] << stone
118
- @board.remove(stone)
125
+ moves.capture(stone)
126
+ board.remove(stone)
119
127
  end
120
128
 
121
- public
122
-
123
- class IllegalMove < Exception
129
+ class IllegalMove < StandardError
124
130
  end
125
131
  end
126
132
  end
@@ -0,0 +1,11 @@
1
+ module RubyGo
2
+ class Liberty
3
+ def empty?
4
+ true
5
+ end
6
+
7
+ def to_s
8
+ Board::COLORS[:empty]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,63 @@
1
+ module RubyGo
2
+ class Moves
3
+ attr_reader :internal_moves, :capture_count, :pass_count
4
+
5
+ def initialize
6
+ @internal_moves = []
7
+ @pass_count = 0
8
+ @capture_count = { black: 0, white: 0 }
9
+ end
10
+
11
+ def play(played)
12
+ @pass_count += 0
13
+ internal_moves << Move.new(played)
14
+ end
15
+
16
+ def pass(pass)
17
+ @pass_count += 1
18
+ internal_moves << Move.new(pass)
19
+ end
20
+
21
+ def each(&block)
22
+ internal_moves.each(&block)
23
+ end
24
+
25
+ def prev
26
+ internal_moves[-2]
27
+ end
28
+
29
+ def current
30
+ internal_moves[-1]
31
+ end
32
+
33
+ def pop
34
+ move = internal_moves.pop
35
+
36
+ move.captures.each do |stone|
37
+ capture_count[stone.color] -= 1
38
+ end
39
+
40
+ @pass_count -= 1 if move.empty?
41
+
42
+ move
43
+ end
44
+
45
+ def capture(stone)
46
+ current.captures << stone
47
+ capture_count[stone.color] += 1
48
+ end
49
+ end
50
+
51
+ class Move
52
+ attr_reader :played, :captures
53
+
54
+ def initialize(played)
55
+ @played = played
56
+ @captures = []
57
+ end
58
+
59
+ def empty?
60
+ played.empty?
61
+ end
62
+ end
63
+ end
@@ -1,104 +1,54 @@
1
1
  module RubyGo
2
2
  class Stone
3
+ LETTERS = ('a'..'z').to_a
3
4
 
4
- attr_reader :color
5
- def initialize(x, y)
6
- @x, @y = x, y
7
- @color = :none
5
+ attr_reader :color, :x_coord, :y_coord
6
+
7
+ def initialize(x_coord, y_coord, color)
8
+ @x_coord = x_coord
9
+ @y_coord = y_coord
10
+ @color = color
8
11
  end
9
12
 
10
13
  def to_sgf
11
- x = Game::LETTERS[@x]
12
- y = Game::LETTERS[@y]
13
- ";#{color.to_s[0].upcase}[#{x+y}]"
14
+ x = LETTERS[x_coord]
15
+ y = LETTERS[y_coord]
16
+ ";#{color.to_s[0].upcase}[#{x}#{y}]"
14
17
  end
15
18
 
16
19
  def empty?
17
- @color == :empty
18
- end
19
-
20
- def place_on_board(board)
21
- unless board.at(@x, @y).empty?
22
- raise Game::IllegalMove,
23
- "You cannot place a stone on top of another stone."
24
- end
25
- board.board[@y][@x] = self
26
- end
27
-
28
- def remove_from_board(board)
29
- board.board[@y][@x] = Liberty.new(*self.to_coord)
30
- end
31
-
32
- def liberties(board)
33
- board.around(self).select {|stone| stone.empty?}
34
- end
35
-
36
- def group(board, stones = [])
37
- return stones if stones.any? {|stone| stone.eql?(self)}
38
- stones << self
39
-
40
- board.around(self).each do |stone|
41
- if stone.color == @color
42
- stone.group(board, stones)
43
- end
44
- end
45
-
46
- stones
20
+ false
47
21
  end
48
22
 
49
23
  def to_coord
50
- [@x, @y]
51
- end
52
-
53
- def to_str
54
- Board::Colors[@color]
24
+ [x_coord, y_coord]
55
25
  end
56
26
 
57
27
  def to_s
58
- to_str
28
+ Board::COLORS[color]
59
29
  end
60
30
 
61
31
  def ==(other)
62
- (self.color == other.color) and (self.to_coord == other.to_coord)
63
- end
64
- end
65
-
66
- class Liberty < Stone
67
- def initialize(x, y)
68
- super
69
- @color = :empty
70
- end
71
-
72
- def liberties(board)
73
- [self]
74
- end
75
- end
76
-
77
- class BlackStone < Stone
78
- def initialize(x, y)
79
- super
80
- @color = :black
81
- end
82
- end
83
-
84
- class WhiteStone < Stone
85
- def initialize(x, y)
86
- super
87
- @color = :white
32
+ other.is_a?(Stone) &&
33
+ (color == other.color) &&
34
+ (to_coord == other.to_coord)
88
35
  end
89
36
  end
90
37
 
38
+ # This can be changed to a Pass object
91
39
  class NullStone < Stone
92
40
  def initialize(color = :empty)
93
- @x, @y = nil, nil
41
+ @x_coord = nil
42
+ @y_coord = nil
94
43
  @color = color
95
44
  end
96
-
97
- def remove_from_board(board)
98
- end
99
45
 
100
46
  def to_sgf
101
47
  ";#{color.to_s[0].upcase}[]"
102
48
  end
49
+
50
+ def empty?
51
+ true
52
+ end
103
53
  end
104
54
  end
@@ -1,3 +1,3 @@
1
1
  module RubyGo
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -2,12 +2,12 @@ require_relative 'test_helper'
2
2
  require 'stringio'
3
3
 
4
4
  module RubyGo
5
- class GoTest < Minitest::Test
5
+ class GoTest < Minitest::Test
6
6
  def setup
7
- b,w = Board::Colors[:black], Board::Colors[:white]
8
- e = Board::Colors[:empty]
7
+ b,w = Board::COLORS[:black], Board::COLORS[:white]
8
+ e = Board::COLORS[:empty]
9
9
 
10
- @row_9_str = "_ _ _ _ _ _ _ _ _\n"
10
+ @row_9_str = "_ _ _ _ _ _ _ _ _\n"
11
11
 
12
12
  @game = Game.new(board: 9)
13
13
  end
@@ -17,7 +17,7 @@ module RubyGo
17
17
  end
18
18
 
19
19
  def test_empty_board_looks_like_empty_board
20
- assert_includes @game.board.to_s, @row_9_str
20
+ assert_includes @game.board.to_s, @row_9_str
21
21
  end
22
22
 
23
23
  def test_game_can_print_the_board
@@ -33,7 +33,7 @@ module RubyGo
33
33
  def test_game_can_place_a_stone
34
34
  game = Game.new(board: 9)
35
35
  game.black(2,2)
36
- assert_equal BlackStone.new(2,2), game.board.at(2,2)
36
+ assert_equal :black, game.board.at(2,2).color
37
37
  end
38
38
 
39
39
  def test_cannot_place_a_stone_on_top_of_another_stone
@@ -61,7 +61,7 @@ module RubyGo
61
61
  game.white(2,3)
62
62
  game.white(1,2)
63
63
  game.white(3,2)
64
- assert_equal Liberty.new(2,2), game.board.at(2,2)
64
+ assert game.board.at(2,2).empty?
65
65
  end
66
66
 
67
67
  def test_capture_three_stones
@@ -80,12 +80,41 @@ module RubyGo
80
80
  assert_equal 3, game.captures[:black]
81
81
  end
82
82
 
83
+ def test_snap_back
84
+ game = Game.new(board: 9)
85
+ game.black(3,2)
86
+ game.black(2,3)
87
+ game.black(4,3)
88
+ game.black(2,4)
89
+ game.black(5,4)
90
+ game.black(3,5)
91
+ game.black(4,5)
92
+ game.white(4,2)
93
+ game.white(5,3)
94
+ game.white(3,4)
95
+ game.white(4,4)
96
+ game.white(3,3)
97
+ assert_equal 1, game.captures[:black]
98
+ assert_equal 0, game.captures[:white]
99
+ game.black(4,3)
100
+ assert_equal 1, game.captures[:black]
101
+ assert_equal 3, game.captures[:white]
102
+ end
103
+
83
104
  def test_can_undo
84
105
  game = Game.new()
85
106
  game.black(2,2)
86
107
  game.white(2,3)
87
108
  game.undo
88
- assert_equal Liberty.new(2,3), game.board.at(2,3)
109
+ assert game.board.at(2,3).empty?
110
+ end
111
+
112
+ def test_can_undo_pass
113
+ game = Game.new
114
+ game.black(2,2)
115
+ game.white_pass
116
+ game.undo
117
+ assert_equal 0, game.passes
89
118
  end
90
119
 
91
120
  def test_can_undo_until_beginning
@@ -94,16 +123,14 @@ module RubyGo
94
123
  game.white(3,2)
95
124
  game.black(3,3)
96
125
  3.times {game.undo}
97
- assert_equal Liberty.new(2,2), game.board.at(2,2)
126
+ assert game.board.at(2,2).empty?
98
127
  end
99
128
 
100
129
  def test_can_pass
101
130
  game = Game.new
102
- game.pass(:black)
103
- game.pass(:white)
104
131
  game.black_pass
105
132
  game.white_pass
106
- assert_equal 4, game.passes
133
+ assert_equal 2, game.passes
107
134
  end
108
135
 
109
136
  def test_cannot_play_a_suicide
@@ -147,19 +174,19 @@ module RubyGo
147
174
 
148
175
  def test_can_play_in_previous_capture_area_that_is_not_a_ko
149
176
  game = big_capture_area_game
150
- assert_equal Liberty.new(0,0), game.board.at(0,0)
177
+ assert game.board.at(0,0).empty?
151
178
  game.black(0,0)
152
- assert_equal BlackStone.new(0,0), game.board.at(0,0)
179
+ assert_equal :black, game.board.at(0,0).color
153
180
 
154
181
  game = big_capture_area_game
155
- assert_equal Liberty.new(0,1), game.board.at(0,1)
182
+ assert game.board.at(0,1).empty?
156
183
  game.black(0,1)
157
- assert_equal BlackStone.new(0,1), game.board.at(0,1)
184
+ assert_equal :black, game.board.at(0,1).color
158
185
 
159
186
  game = big_capture_area_game
160
- assert_equal Liberty.new(1,0), game.board.at(1,0)
187
+ assert game.board.at(1,0).empty?
161
188
  game.black(1,0)
162
- assert_equal BlackStone.new(1,0), game.board.at(1,0)
189
+ assert_equal :black, game.board.at(1,0).color
163
190
  end
164
191
  end
165
192
  end
@@ -46,7 +46,7 @@ module RubyGo
46
46
  game.black(16,2)
47
47
  game.white(15,2)
48
48
  game.save
49
- assert_includes Dir.glob(path), file
49
+ assert_includes Dir.glob(path), file
50
50
  end
51
51
  end
52
52
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-go
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - jphager2
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-11 00:00:00.000000000 Z
11
+ date: 2017-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: SgfParser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0
19
+ version: 3.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.0
26
+ version: 3.0.0
27
27
  description: A gem to play go and save games as sgf
28
28
  email: jphager2@gmail.com
29
29
  executables:
@@ -38,6 +38,8 @@ files:
38
38
  - lib/ruby-go.rb
39
39
  - lib/ruby-go/board.rb
40
40
  - lib/ruby-go/game.rb
41
+ - lib/ruby-go/liberty.rb
42
+ - lib/ruby-go/moves.rb
41
43
  - lib/ruby-go/stone.rb
42
44
  - lib/ruby-go/version.rb
43
45
  - test/go_test.rb
@@ -63,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
65
  version: '0'
64
66
  requirements: []
65
67
  rubyforge_project:
66
- rubygems_version: 2.4.6
68
+ rubygems_version: 2.6.12
67
69
  signing_key:
68
70
  specification_version: 4
69
71
  summary: The game of Go, writen in Ruby