ruby-go 0.4.0 → 1.0.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 +5 -5
- data/README.md +30 -16
- data/bin/rubygo +56 -0
- data/lib/ruby-go/board.rb +8 -31
- data/lib/ruby-go/game.rb +16 -13
- data/lib/ruby-go/liberty.rb +2 -2
- data/lib/ruby-go/printers/html.rb +76 -0
- data/lib/ruby-go/printers/text.rb +40 -0
- data/lib/ruby-go/stone.rb +3 -7
- data/lib/ruby-go/version.rb +1 -1
- data/test/go_test.rb +72 -81
- data/test/sgf_test.rb +18 -18
- data/test/test_helper.rb +2 -1
- metadata +7 -6
- data/bin/ruby-go.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '024418870e37d715d73c1ce299b3db4c59b231d8fea65b64870e280b9f439387'
|
4
|
+
data.tar.gz: 460d7dbde08c15c6aec3e067dcd50c11d1b2dfac31cd708a97826a3b7b585ad1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2871316ce937e2df59f6ec8b912b51bb20cc1b37c3d257e3ddb6be0067f559d7a18feb6d8e292955257d910cfacb36aab945794912f61438d036c0d561269b3
|
7
|
+
data.tar.gz: bba3a81eac11819591ff71683b413a9679d06e15fc3334b3e874e415ec25886a600272e783f98495a578722ad8fc4c4514089e954cd2bdf73d6046c8e3836555
|
data/README.md
CHANGED
@@ -1,16 +1,30 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
1
|
+
# Ruby Go
|
2
|
+
|
3
|
+
A gem that implements the rules of go (igo, weiqi, baduk).
|
4
|
+
|
5
|
+
## Use
|
6
|
+
|
7
|
+
```
|
8
|
+
game = RubyGo::Game(board: 19)
|
9
|
+
game.place_black(3,3)
|
10
|
+
game.place_white(15,15)
|
11
|
+
|
12
|
+
# ...
|
13
|
+
|
14
|
+
game.pass_black
|
15
|
+
game.pass_white
|
16
|
+
```
|
17
|
+
|
18
|
+
### Printers
|
19
|
+
|
20
|
+
There are a few printers included in the gem, including `TextPrinter` and `HTMLPrinter`.
|
21
|
+
|
22
|
+
The printer takes an `IO` like object, and can print the game.
|
23
|
+
```
|
24
|
+
printer = RubyGo::TextPrinter.new($stdout)
|
25
|
+
printer.print_game(game)
|
26
|
+
```
|
27
|
+
|
28
|
+
### rubygo Command Line Interface
|
29
|
+
|
30
|
+
The rubygo executable included in the gem is CLI that plays the game of go.
|
data/bin/rubygo
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'ruby-go'
|
4
|
+
require 'ruby-go/printers/text'
|
5
|
+
|
6
|
+
game = RubyGo::Game.new
|
7
|
+
printer = RubyGo::TextPrinter.new($stdout)
|
8
|
+
|
9
|
+
Signal.trap("INTERUPT") do
|
10
|
+
puts "\nGoodbye"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def prompt_for_turn(game)
|
15
|
+
loop do
|
16
|
+
print 'Enter "Pass" or enter coordinates x, y for move (e.g. "4, 4"): '
|
17
|
+
ans = gets.chomp.downcase.gsub(/\s/, '')
|
18
|
+
|
19
|
+
return if ans =~ /pass/
|
20
|
+
|
21
|
+
return ans.split(',').collect {|c| Integer(c)} if ans =~/\d+,\d+/
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def update_terminal(printer, game)
|
26
|
+
system "clear"
|
27
|
+
printer.print_game(game)
|
28
|
+
end
|
29
|
+
|
30
|
+
update_terminal(printer, game)
|
31
|
+
|
32
|
+
turn = 0
|
33
|
+
until game.passes >= 2
|
34
|
+
begin
|
35
|
+
if turn % 2 == 0
|
36
|
+
#black's turn
|
37
|
+
puts "Black's turn"
|
38
|
+
move = prompt_for_turn(game)
|
39
|
+
move ? game.place_black(*move) : game.black_pass
|
40
|
+
else
|
41
|
+
#white's turn
|
42
|
+
puts "White's turn"
|
43
|
+
move = prompt_for_turn(game)
|
44
|
+
move ? game.place_white(*move) : game.white_pass
|
45
|
+
end
|
46
|
+
|
47
|
+
update_terminal(printer, game)
|
48
|
+
|
49
|
+
turn += 1
|
50
|
+
rescue RubyGo::Game::IllegalMove => e
|
51
|
+
puts e.message
|
52
|
+
next
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
puts "Game over"
|
data/lib/ruby-go/board.rb
CHANGED
@@ -1,31 +1,27 @@
|
|
1
1
|
module RubyGo
|
2
2
|
class Board
|
3
|
-
|
4
|
-
|
5
|
-
attr_accessor :internal_board, :size
|
3
|
+
attr_reader :rows, :size
|
6
4
|
|
7
5
|
def initialize(size)
|
8
|
-
@
|
6
|
+
@rows = Array.new(size) { Array.new(size) { Liberty.new } }
|
9
7
|
@size = size
|
10
8
|
end
|
11
9
|
|
12
|
-
private :internal_board
|
13
|
-
|
14
10
|
def empty?
|
15
|
-
|
11
|
+
rows.flatten.all?(&:empty?)
|
16
12
|
end
|
17
13
|
|
18
14
|
def at(x, y)
|
19
|
-
|
15
|
+
rows[y][x]
|
20
16
|
end
|
21
17
|
|
22
18
|
def around(x, y)
|
23
19
|
intersections = []
|
24
20
|
|
25
21
|
intersections << at(x-1, y) unless x == 0
|
26
|
-
intersections << at(x+1, y) unless x == (
|
22
|
+
intersections << at(x+1, y) unless x == (size - 1)
|
27
23
|
intersections << at(x, y-1) unless y == 0
|
28
|
-
intersections << at(x, y+1) unless y == (
|
24
|
+
intersections << at(x, y+1) unless y == (size - 1)
|
29
25
|
intersections
|
30
26
|
end
|
31
27
|
|
@@ -34,14 +30,13 @@ module RubyGo
|
|
34
30
|
|
35
31
|
x, y = stone.to_coord
|
36
32
|
|
37
|
-
|
33
|
+
rows[y][x] = Liberty.new
|
38
34
|
end
|
39
35
|
|
40
|
-
# Board shouldn't care about game rules
|
41
36
|
def place(stone)
|
42
37
|
x, y = stone.to_coord
|
43
38
|
|
44
|
-
|
39
|
+
rows[y][x] = stone
|
45
40
|
end
|
46
41
|
|
47
42
|
def liberties(stone)
|
@@ -67,23 +62,5 @@ module RubyGo
|
|
67
62
|
|
68
63
|
stones
|
69
64
|
end
|
70
|
-
|
71
|
-
def to_s
|
72
|
-
out = ""
|
73
|
-
|
74
|
-
if size < 11
|
75
|
-
out << "\s\s\s#{(0..size - 1).to_a.join(' ')}\n"
|
76
|
-
else
|
77
|
-
out << "\s\s\s#{(0..10).to_a.join(' ')}"
|
78
|
-
out << "#{(11..size - 1).to_a.join('')}\n"
|
79
|
-
end
|
80
|
-
|
81
|
-
internal_board.each_with_index do |row, i|
|
82
|
-
i = "\s#{i}" if i < 10
|
83
|
-
out << "#{i}\s#{(row.collect {|stn| stn.to_s}).join(' ')}\n"
|
84
|
-
end
|
85
|
-
|
86
|
-
out
|
87
|
-
end
|
88
65
|
end
|
89
66
|
end
|
data/lib/ruby-go/game.rb
CHANGED
@@ -24,19 +24,11 @@ module RubyGo
|
|
24
24
|
sgf << ')'
|
25
25
|
end
|
26
26
|
|
27
|
-
def
|
28
|
-
puts board
|
29
|
-
puts " " + "_"*(board.size * 2)
|
30
|
-
print " Prisoners || White: #{captures[:black]} |"
|
31
|
-
puts " Black: #{captures[:white]}"
|
32
|
-
puts " " + "-"*(board.size * 2)
|
33
|
-
end
|
34
|
-
|
35
|
-
def black(x, y)
|
27
|
+
def place_black(x, y)
|
36
28
|
play(Stone.new(x, y, :black))
|
37
29
|
end
|
38
30
|
|
39
|
-
def
|
31
|
+
def place_white(x, y)
|
40
32
|
play(Stone.new(x, y, :white))
|
41
33
|
end
|
42
34
|
|
@@ -83,10 +75,21 @@ module RubyGo
|
|
83
75
|
end
|
84
76
|
|
85
77
|
def check_illegal_placement!(stone)
|
86
|
-
|
78
|
+
coord = stone.to_coord
|
79
|
+
|
80
|
+
if coord.any? { |i| i < 0 || i >= board.size }
|
81
|
+
raise(
|
82
|
+
Game::IllegalMove,
|
83
|
+
"You cannot place a stone off the board."
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
intersection = board.at(*coord)
|
88
|
+
|
89
|
+
unless intersection.empty?
|
87
90
|
raise(
|
88
|
-
Game::IllegalMove,
|
89
|
-
"You cannot place a stone on top of another stone."
|
91
|
+
Game::IllegalMove,
|
92
|
+
"You cannot place a stone on top of another stone."
|
90
93
|
)
|
91
94
|
end
|
92
95
|
end
|
data/lib/ruby-go/liberty.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module RubyGo
|
4
|
+
class HTMLPrinter
|
5
|
+
LETTERS = ('A'..'Z').to_a.freeze
|
6
|
+
COLORS = { black: 'black stone', white: 'white stone', empty: 'liberty' }.freeze
|
7
|
+
TEMPLATE = ERB.new(<<~ERB).freeze
|
8
|
+
<style>
|
9
|
+
.board { max-width: 100%; padding: 16px; }
|
10
|
+
.row { display: flex; margin: 0; }
|
11
|
+
.intersection { display: inline-block; height: 32px; width: 32px; border-top: 2px solid black; border-left: 2px solid black; }
|
12
|
+
.intersection:last-child { border-top-width: 0px; height: 34px; }
|
13
|
+
.row:last-child .intersection { border-left-width: 0px; width: 34px; }
|
14
|
+
.row:last-child .intersection:last-child { width: 2px; height: 2px; background: black; }
|
15
|
+
.stone, .liberty { display: inline-block; width: 30px; height: 30px; border-radius: 100%; margin: 0; position: relative; top: -18px; left: -18px; }
|
16
|
+
.stone { border: 2px solid black; }
|
17
|
+
.black.stone { background: black; }
|
18
|
+
.white.stone { background: white; }
|
19
|
+
.liberty:hover { border: 2px solid red; }
|
20
|
+
.row-num, .column-num { display: inline-block; width: 34px; height: 34px; margin: 0; position: relative; }
|
21
|
+
.row-num { top: -0.5em; }
|
22
|
+
.column-num { left: -0.3em; }
|
23
|
+
</style>
|
24
|
+
<div class="game">
|
25
|
+
<div class="board">
|
26
|
+
<div class="row">
|
27
|
+
<div class="column-num row-num"></div>
|
28
|
+
<% size.times do |i| %>
|
29
|
+
<div class="column-num"><%= letters[i] %></div>
|
30
|
+
<% end %>
|
31
|
+
</div>
|
32
|
+
<% rows.each_with_index do |row, i| %>
|
33
|
+
<div class="row">
|
34
|
+
<div class="row-num"><%= letters[i] %></div>
|
35
|
+
<% row.each do |stn| %>
|
36
|
+
<div class="intersection">
|
37
|
+
<div class="<%= colors[stn.color] %>"></div>
|
38
|
+
</div>
|
39
|
+
<% end %>
|
40
|
+
</div>
|
41
|
+
<% end %>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="info">
|
45
|
+
<table>
|
46
|
+
<tbody>
|
47
|
+
<tr>
|
48
|
+
<th>Prisoners</th>
|
49
|
+
<th>White</th>
|
50
|
+
<td><%= captures[:black] %></td>
|
51
|
+
<th>Black</th>
|
52
|
+
<td><%= captures[:white] %></td>
|
53
|
+
</tr>
|
54
|
+
</tbody>
|
55
|
+
</table>
|
56
|
+
</div>
|
57
|
+
</div>
|
58
|
+
ERB
|
59
|
+
|
60
|
+
attr_reader :io
|
61
|
+
|
62
|
+
def initialize(io)
|
63
|
+
@io = io
|
64
|
+
end
|
65
|
+
|
66
|
+
def print_game(game)
|
67
|
+
html = TEMPLATE.result_with_hash(
|
68
|
+
size: game.board.size,
|
69
|
+
captures: game.captures,
|
70
|
+
rows: game.board.rows,
|
71
|
+
colors: COLORS, letters: LETTERS
|
72
|
+
)
|
73
|
+
io.write(html)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubyGo
|
2
|
+
class TextPrinter
|
3
|
+
COLORS = { black: 'x', white: 'o', empty: '_' }.freeze
|
4
|
+
|
5
|
+
attr_reader :io
|
6
|
+
|
7
|
+
def initialize(io)
|
8
|
+
@io = io
|
9
|
+
end
|
10
|
+
|
11
|
+
def print_game(game)
|
12
|
+
print_board(game.board)
|
13
|
+
io.puts " " + "_"*(game.board.size * 2)
|
14
|
+
io.print " Prisoners || White: #{game.captures[:black]} |"
|
15
|
+
io.puts " Black: #{game.captures[:white]}"
|
16
|
+
io.puts " " + "-"*(game.board.size * 2)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def print_board(board)
|
22
|
+
if board.size < 11
|
23
|
+
io.puts " #{(0..board.size - 1).to_a.join(' ')}"
|
24
|
+
else
|
25
|
+
io.puts " #{(0..10).to_a.join(' ')}#{(11..board.size - 1).to_a.join('')}"
|
26
|
+
end
|
27
|
+
|
28
|
+
board.rows.each_with_index do |row, i|
|
29
|
+
i = " #{i}" if i < 10
|
30
|
+
io.print "#{i} "
|
31
|
+
row.each { |stn| print_stone(stn) }
|
32
|
+
io.puts
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def print_stone(stone)
|
37
|
+
io.print "#{COLORS[stone.color]} "
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/ruby-go/stone.rb
CHANGED
@@ -6,7 +6,7 @@ module RubyGo
|
|
6
6
|
|
7
7
|
def initialize(x_coord, y_coord, color)
|
8
8
|
@x_coord = x_coord
|
9
|
-
@y_coord = y_coord
|
9
|
+
@y_coord = y_coord
|
10
10
|
@color = color
|
11
11
|
end
|
12
12
|
|
@@ -24,10 +24,6 @@ module RubyGo
|
|
24
24
|
[x_coord, y_coord]
|
25
25
|
end
|
26
26
|
|
27
|
-
def to_s
|
28
|
-
Board::COLORS[color]
|
29
|
-
end
|
30
|
-
|
31
27
|
def ==(other)
|
32
28
|
other.is_a?(Stone) &&
|
33
29
|
(color == other.color) &&
|
@@ -36,7 +32,7 @@ module RubyGo
|
|
36
32
|
end
|
37
33
|
|
38
34
|
# This can be changed to a Pass object
|
39
|
-
class NullStone < Stone
|
35
|
+
class NullStone < Stone
|
40
36
|
def initialize(color = :empty)
|
41
37
|
@x_coord = nil
|
42
38
|
@y_coord = nil
|
@@ -46,7 +42,7 @@ module RubyGo
|
|
46
42
|
def to_sgf
|
47
43
|
";#{color.to_s[0].upcase}[]"
|
48
44
|
end
|
49
|
-
|
45
|
+
|
50
46
|
def empty?
|
51
47
|
true
|
52
48
|
end
|
data/lib/ruby-go/version.rb
CHANGED
data/test/go_test.rb
CHANGED
@@ -4,10 +4,7 @@ require 'stringio'
|
|
4
4
|
module RubyGo
|
5
5
|
class GoTest < Minitest::Test
|
6
6
|
def setup
|
7
|
-
|
8
|
-
e = Board::COLORS[:empty]
|
9
|
-
|
10
|
-
@row_9_str = "_ _ _ _ _ _ _ _ _\n"
|
7
|
+
@row_9_str = " 8 _ _ _ _ _ _ _ _ _ \n"
|
11
8
|
|
12
9
|
@game = Game.new(board: 9)
|
13
10
|
end
|
@@ -16,102 +13,96 @@ module RubyGo
|
|
16
13
|
assert @game.board.empty?
|
17
14
|
end
|
18
15
|
|
19
|
-
def
|
20
|
-
assert_includes @game.board.to_s, @row_9_str
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_game_can_print_the_board
|
16
|
+
def test_printer_can_print_the_game
|
24
17
|
out = StringIO.new
|
25
|
-
|
26
|
-
|
27
|
-
@game.view
|
28
|
-
$stdout = temp
|
18
|
+
printer = RubyGo::TextPrinter.new(out)
|
19
|
+
printer.print_game(@game)
|
29
20
|
out.rewind
|
30
21
|
assert_includes out.read, @row_9_str
|
31
22
|
end
|
32
23
|
|
33
24
|
def test_game_can_place_a_stone
|
34
25
|
game = Game.new(board: 9)
|
35
|
-
game.
|
26
|
+
game.place_black(2,2)
|
36
27
|
assert_equal :black, game.board.at(2,2).color
|
37
28
|
end
|
38
29
|
|
39
30
|
def test_cannot_place_a_stone_on_top_of_another_stone
|
40
31
|
game = Game.new(board: 9)
|
41
|
-
game.
|
32
|
+
game.place_black(2,2)
|
42
33
|
assert_raises(Game::IllegalMove) do
|
43
|
-
game.
|
34
|
+
game.place_white(2,2)
|
44
35
|
end
|
45
36
|
end
|
46
37
|
|
47
38
|
def test_can_capture_one_stone
|
48
39
|
game = Game.new(board: 9)
|
49
|
-
game.
|
50
|
-
game.
|
51
|
-
game.
|
52
|
-
game.
|
53
|
-
game.
|
40
|
+
game.place_black(2,2)
|
41
|
+
game.place_white(2,1)
|
42
|
+
game.place_white(2,3)
|
43
|
+
game.place_white(1,2)
|
44
|
+
game.place_white(3,2)
|
54
45
|
assert_equal 1, game.captures[:black]
|
55
46
|
end
|
56
47
|
|
57
48
|
def test_capture_removes_stone
|
58
49
|
game = Game.new(board: 9)
|
59
|
-
game.
|
60
|
-
game.
|
61
|
-
game.
|
62
|
-
game.
|
63
|
-
game.
|
50
|
+
game.place_black(2,2)
|
51
|
+
game.place_white(2,1)
|
52
|
+
game.place_white(2,3)
|
53
|
+
game.place_white(1,2)
|
54
|
+
game.place_white(3,2)
|
64
55
|
assert game.board.at(2,2).empty?
|
65
56
|
end
|
66
57
|
|
67
58
|
def test_capture_three_stones
|
68
59
|
game = Game.new(board: 9)
|
69
|
-
game.
|
70
|
-
game.
|
71
|
-
game.
|
72
|
-
game.
|
73
|
-
game.
|
74
|
-
game.
|
75
|
-
game.
|
76
|
-
game.
|
77
|
-
game.
|
78
|
-
game.
|
79
|
-
game.
|
60
|
+
game.place_black(2,1)
|
61
|
+
game.place_black(2,2)
|
62
|
+
game.place_black(2,3)
|
63
|
+
game.place_white(2,0)
|
64
|
+
game.place_white(2,4)
|
65
|
+
game.place_white(1,1)
|
66
|
+
game.place_white(1,2)
|
67
|
+
game.place_white(1,3)
|
68
|
+
game.place_white(3,1)
|
69
|
+
game.place_white(3,2)
|
70
|
+
game.place_white(3,3)
|
80
71
|
assert_equal 3, game.captures[:black]
|
81
72
|
end
|
82
73
|
|
83
74
|
def test_snap_back
|
84
75
|
game = Game.new(board: 9)
|
85
|
-
game.
|
86
|
-
game.
|
87
|
-
game.
|
88
|
-
game.
|
89
|
-
game.
|
90
|
-
game.
|
91
|
-
game.
|
92
|
-
game.
|
93
|
-
game.
|
94
|
-
game.
|
95
|
-
game.
|
96
|
-
game.
|
76
|
+
game.place_black(3,2)
|
77
|
+
game.place_black(2,3)
|
78
|
+
game.place_black(4,3)
|
79
|
+
game.place_black(2,4)
|
80
|
+
game.place_black(5,4)
|
81
|
+
game.place_black(3,5)
|
82
|
+
game.place_black(4,5)
|
83
|
+
game.place_white(4,2)
|
84
|
+
game.place_white(5,3)
|
85
|
+
game.place_white(3,4)
|
86
|
+
game.place_white(4,4)
|
87
|
+
game.place_white(3,3)
|
97
88
|
assert_equal 1, game.captures[:black]
|
98
89
|
assert_equal 0, game.captures[:white]
|
99
|
-
game.
|
90
|
+
game.place_black(4,3)
|
100
91
|
assert_equal 1, game.captures[:black]
|
101
92
|
assert_equal 3, game.captures[:white]
|
102
93
|
end
|
103
94
|
|
104
95
|
def test_can_undo
|
105
96
|
game = Game.new()
|
106
|
-
game.
|
107
|
-
game.
|
97
|
+
game.place_black(2,2)
|
98
|
+
game.place_white(2,3)
|
108
99
|
game.undo
|
109
100
|
assert game.board.at(2,3).empty?
|
110
101
|
end
|
111
102
|
|
112
103
|
def test_can_undo_pass
|
113
104
|
game = Game.new
|
114
|
-
game.
|
105
|
+
game.place_black(2,2)
|
115
106
|
game.white_pass
|
116
107
|
game.undo
|
117
108
|
assert_equal 0, game.passes
|
@@ -119,9 +110,9 @@ module RubyGo
|
|
119
110
|
|
120
111
|
def test_can_undo_until_beginning
|
121
112
|
game = Game.new()
|
122
|
-
game.
|
123
|
-
game.
|
124
|
-
game.
|
113
|
+
game.place_black(2,2)
|
114
|
+
game.place_white(3,2)
|
115
|
+
game.place_black(3,3)
|
125
116
|
3.times {game.undo}
|
126
117
|
assert game.board.at(2,2).empty?
|
127
118
|
end
|
@@ -135,57 +126,57 @@ module RubyGo
|
|
135
126
|
|
136
127
|
def test_cannot_play_a_suicide
|
137
128
|
game = Game.new
|
138
|
-
game.
|
139
|
-
game.
|
140
|
-
game.
|
141
|
-
game.
|
142
|
-
game.
|
129
|
+
game.place_black(3,3)
|
130
|
+
game.place_white(2,3)
|
131
|
+
game.place_white(4,3)
|
132
|
+
game.place_white(3,4)
|
133
|
+
game.place_white(3,2)
|
143
134
|
assert_raises(Game::IllegalMove) do
|
144
|
-
game.
|
135
|
+
game.place_black(3,3)
|
145
136
|
end
|
146
137
|
end
|
147
138
|
|
148
139
|
def test_cannot_play_a_ko
|
149
140
|
game = Game.new
|
150
|
-
game.
|
151
|
-
game.
|
152
|
-
game.
|
153
|
-
game.
|
154
|
-
game.
|
155
|
-
game.
|
156
|
-
game.
|
157
|
-
game.
|
158
|
-
game.
|
141
|
+
game.place_black(3,3)
|
142
|
+
game.place_white(2,3)
|
143
|
+
game.place_white(4,3)
|
144
|
+
game.place_white(3,4)
|
145
|
+
game.place_white(3,2)
|
146
|
+
game.place_black(4,2)
|
147
|
+
game.place_black(4,4)
|
148
|
+
game.place_black(5,3)
|
149
|
+
game.place_black(3,3)
|
159
150
|
assert_raises(Game::IllegalMove) do
|
160
|
-
game.
|
151
|
+
game.place_white(4,3)
|
161
152
|
end
|
162
153
|
end
|
163
154
|
|
164
155
|
def big_capture_area_game
|
165
156
|
game = Game.new
|
166
|
-
game.
|
167
|
-
game.
|
168
|
-
game.
|
169
|
-
game.
|
170
|
-
game.
|
171
|
-
game.
|
157
|
+
game.place_black(0,0)
|
158
|
+
game.place_white(1,1)
|
159
|
+
game.place_black(0,1)
|
160
|
+
game.place_white(0,2)
|
161
|
+
game.place_black(1,0)
|
162
|
+
game.place_white(2,0)
|
172
163
|
game
|
173
164
|
end
|
174
165
|
|
175
166
|
def test_can_play_in_previous_capture_area_that_is_not_a_ko
|
176
167
|
game = big_capture_area_game
|
177
168
|
assert game.board.at(0,0).empty?
|
178
|
-
game.
|
169
|
+
game.place_black(0,0)
|
179
170
|
assert_equal :black, game.board.at(0,0).color
|
180
171
|
|
181
172
|
game = big_capture_area_game
|
182
173
|
assert game.board.at(0,1).empty?
|
183
|
-
game.
|
174
|
+
game.place_black(0,1)
|
184
175
|
assert_equal :black, game.board.at(0,1).color
|
185
176
|
|
186
177
|
game = big_capture_area_game
|
187
178
|
assert game.board.at(1,0).empty?
|
188
|
-
game.
|
179
|
+
game.place_black(1,0)
|
189
180
|
assert_equal :black, game.board.at(1,0).color
|
190
181
|
end
|
191
182
|
end
|
data/test/sgf_test.rb
CHANGED
@@ -11,26 +11,26 @@ module RubyGo
|
|
11
11
|
|
12
12
|
def test_game_converts_to_sgf_with_moves
|
13
13
|
game = Game.new
|
14
|
-
game.
|
15
|
-
game.
|
16
|
-
game.
|
17
|
-
game.
|
14
|
+
game.place_black(15,3)
|
15
|
+
game.place_white(3,3)
|
16
|
+
game.place_black(3,15)
|
17
|
+
game.place_white(15,15)
|
18
18
|
assert_equal "(;GM[1]FF[4]CA[UTF-8]AP[jphager2]SZ[19]PW[White]PB[Black];B[pd];W[dd];B[dp];W[pp])",
|
19
19
|
game.to_sgf
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_game_converts_correctly_with_capture
|
23
23
|
game = Game.new
|
24
|
-
game.
|
25
|
-
game.
|
26
|
-
game.
|
27
|
-
game.
|
28
|
-
game.
|
29
|
-
game.
|
30
|
-
game.
|
31
|
-
game.
|
32
|
-
game.
|
33
|
-
game.
|
24
|
+
game.place_black(15,3)
|
25
|
+
game.place_white(16,3)
|
26
|
+
game.place_black(16,2)
|
27
|
+
game.place_white(15,2)
|
28
|
+
game.place_black(14,2)
|
29
|
+
game.place_white(14,3)
|
30
|
+
game.place_black(17,3)
|
31
|
+
game.place_white(15,4)
|
32
|
+
game.place_black(16,4)
|
33
|
+
game.place_white(15,3)
|
34
34
|
|
35
35
|
assert_equal "(;GM[1]FF[4]CA[UTF-8]AP[jphager2]SZ[19]PW[White]PB[Black];B[pd];W[qd];B[qc];W[pc];B[oc];W[od];B[rd];W[pe];B[qe];W[pd])",
|
36
36
|
game.to_sgf
|
@@ -41,10 +41,10 @@ module RubyGo
|
|
41
41
|
path = File.expand_path('../../*.sgf', __FILE__)
|
42
42
|
File.delete(file) if File.exist?(file)
|
43
43
|
game = Game.new
|
44
|
-
game.
|
45
|
-
game.
|
46
|
-
game.
|
47
|
-
game.
|
44
|
+
game.place_black(15,3)
|
45
|
+
game.place_white(16,3)
|
46
|
+
game.place_black(16,2)
|
47
|
+
game.place_white(15,2)
|
48
48
|
game.save
|
49
49
|
assert_includes Dir.glob(path), file
|
50
50
|
end
|
data/test/test_helper.rb
CHANGED
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.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jphager2
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: SgfParser
|
@@ -27,19 +27,21 @@ dependencies:
|
|
27
27
|
description: A gem to play go and save games as sgf
|
28
28
|
email: jphager2@gmail.com
|
29
29
|
executables:
|
30
|
-
-
|
30
|
+
- rubygo
|
31
31
|
extensions: []
|
32
32
|
extra_rdoc_files: []
|
33
33
|
files:
|
34
34
|
- LICENSE
|
35
35
|
- README.md
|
36
36
|
- Rakefile
|
37
|
-
- bin/
|
37
|
+
- bin/rubygo
|
38
38
|
- lib/ruby-go.rb
|
39
39
|
- lib/ruby-go/board.rb
|
40
40
|
- lib/ruby-go/game.rb
|
41
41
|
- lib/ruby-go/liberty.rb
|
42
42
|
- lib/ruby-go/moves.rb
|
43
|
+
- lib/ruby-go/printers/html.rb
|
44
|
+
- lib/ruby-go/printers/text.rb
|
43
45
|
- lib/ruby-go/stone.rb
|
44
46
|
- lib/ruby-go/version.rb
|
45
47
|
- test/go_test.rb
|
@@ -64,8 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
66
|
- !ruby/object:Gem::Version
|
65
67
|
version: '0'
|
66
68
|
requirements: []
|
67
|
-
|
68
|
-
rubygems_version: 2.6.12
|
69
|
+
rubygems_version: 3.1.2
|
69
70
|
signing_key:
|
70
71
|
specification_version: 4
|
71
72
|
summary: The game of Go, writen in Ruby
|
data/bin/ruby-go.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require_relative '../lib/ruby-go'
|
4
|
-
|
5
|
-
game = RubyGo::Game.new
|
6
|
-
|
7
|
-
def game.prompt_for_turn
|
8
|
-
print "Pass or enter coordinates x, y for move (e.g. 4, 4): "
|
9
|
-
ans = gets.chomp.downcase.gsub(/\s/, '')
|
10
|
-
|
11
|
-
if ans =~ /pass/
|
12
|
-
self.pass
|
13
|
-
nil
|
14
|
-
else
|
15
|
-
ans.split(',').collect {|c| Integer(c)}
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
system "clear"
|
20
|
-
game.view
|
21
|
-
turn = 0
|
22
|
-
until game.passes >= 2
|
23
|
-
begin
|
24
|
-
if turn % 2 == 0
|
25
|
-
#black's turn
|
26
|
-
puts "Black's turn"
|
27
|
-
ans = game.prompt_for_turn
|
28
|
-
game.black(*ans) if ans
|
29
|
-
else
|
30
|
-
#white's turn
|
31
|
-
puts "white's turn"
|
32
|
-
ans = game.prompt_for_turn
|
33
|
-
game.white(*ans) if ans
|
34
|
-
end
|
35
|
-
|
36
|
-
system "clear"
|
37
|
-
game.view
|
38
|
-
|
39
|
-
turn += 1
|
40
|
-
rescue RubyGo::Game::IllegalMove
|
41
|
-
next
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
system "clear"
|