stockfish 0.3.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 +7 -0
- data/.gitignore +3 -0
- data/Gemfile +3 -0
- data/README.md +51 -0
- data/Rakefile +10 -0
- data/bin/console +18 -0
- data/lib/stockfish.rb +14 -0
- data/lib/stockfish/analysis_parser.rb +108 -0
- data/lib/stockfish/engine.rb +70 -0
- data/lib/stockfish/version.rb +3 -0
- data/ruby-stockfish.gemspec +24 -0
- data/test/analysis_parser_test.rb +63 -0
- data/test/engine_test.rb +38 -0
- data/test/fixtures/analysis_outputs/black_loses_in_3.txt +13 -0
- data/test/fixtures/analysis_outputs/checkmate.txt +2 -0
- data/test/fixtures/analysis_outputs/kvk_endgame.txt +11 -0
- data/test/fixtures/analysis_outputs/mate_in_1.txt +11 -0
- data/test/fixtures/analysis_outputs/multipv_3.txt +31 -0
- data/test/fixtures/analysis_outputs/stalemate.txt +2 -0
- data/test/fixtures/analysis_outputs/tough_midgame.txt +26 -0
- data/test/fixtures/analysis_outputs/white_wins_in_4.txt +13 -0
- data/test/fixtures/positions/stalemate.txt +1 -0
- data/test/fixtures/positions/start.txt +1 -0
- data/test/fixtures/positions/white_wins_in_4.txt +1 -0
- data/test/test_helper.rb +10 -0
- metadata +110 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: e5fbcce6e53ddc0054fa5a20f9957ef7e188c16a
|
|
4
|
+
data.tar.gz: 32299448619d85bfe4da70f202a67d146a815d4f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 298dd6eb8771f2dc7dfd776389369e83ee14f724f826423dd77061ebfb9b9ac0daf49803189a1b0e16c766a068aa3591754b499a054dae108fe9290b7f458463
|
|
7
|
+
data.tar.gz: 8de4387d5b82eb9f7a7d75eae6f1dc57585f8a2437482e55139238bc46ab129545f933a772aea9a9c043de4281d7c58027f4addc6686eb7a6d1a20b60dde8b1b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Ruby Stockfish
|
|
2
|
+
|
|
3
|
+
A ruby client for the [Stockfish](https://stockfishchess.org/) chess engine
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
$ gem install stockfish
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or add it to your application's Gemfile and install via bundler
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
gem 'stockfish'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Analyzing positions
|
|
18
|
+
|
|
19
|
+
Load a position in [FEN](https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation) notation that you want to analyze
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
fen = "3qr3/1b1rb2Q/p2pk1p1/1p1np3/4P3/P2BB3/1PP3PP/4R2K w - - 2 24"
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Set the search depth (in number of half-moves) you want to use
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
Stockfish.analyze fen, { :depth => 12 }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
And request multiple variations if you'd like
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
Stockfish.analyze fen, { :depth => 6, :multipv => 3 }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Requirements
|
|
38
|
+
|
|
39
|
+
Stockfish 6+ must be installed and available in your $PATH
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
$ which stockfish
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
If Stockfish is not in your $PATH, you can pass the path to the Stockfish binary directly
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
engine = Stockfish::Engine.new("/usr/local/bin/stockfish")
|
|
49
|
+
engine.multipv(3)
|
|
50
|
+
engine.analyze fen, { :depth => 6 }
|
|
51
|
+
```
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
$:.unshift "./lib"
|
|
4
|
+
|
|
5
|
+
require 'pry'
|
|
6
|
+
require 'stockfish'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
engine = Stockfish::Engine.new
|
|
10
|
+
|
|
11
|
+
# puts engine.analyze "rqb2rk1/1p3p2/p1nb1n1p/2pp4/2P4Q/N2P1N2/PP2BPPP/R4RK1 w - - 1 15", { :nodes => 100000 }
|
|
12
|
+
# puts engine.analyze "2r2rk1/p2q1pbp/4b1p1/1p1p4/3P4/1Q2B1P1/PP3PBP/2RR2K1 w - b6 1 17", { :movetime => 2000 }
|
|
13
|
+
# puts engine.analyze "r3k2r/1bqp1pp1/pp1bp3/8/1PP1PP2/3QB1P1/P2N4/1R3RK1 b kq b3 1 18", { :depth => 10 }
|
|
14
|
+
|
|
15
|
+
# analysis_output = open("test/fixtures/analysis_outputs/multipv_3.txt").read
|
|
16
|
+
# parser = Stockfish::AnalysisParser.new(analysis_output)
|
|
17
|
+
|
|
18
|
+
binding.pry
|
data/lib/stockfish.rb
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require "stockfish/engine"
|
|
2
|
+
require "stockfish/analysis_parser"
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module Stockfish
|
|
6
|
+
|
|
7
|
+
def self.analyze(fen, options = {})
|
|
8
|
+
multipv = options.delete(:multipv)
|
|
9
|
+
engine = Engine.new
|
|
10
|
+
engine.multipv(multipv) if multipv
|
|
11
|
+
AnalysisParser.new(engine.analyze(fen, options)).parse
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
module Stockfish
|
|
2
|
+
|
|
3
|
+
# Converts raw analysis output into a hash
|
|
4
|
+
#
|
|
5
|
+
class AnalysisParser
|
|
6
|
+
|
|
7
|
+
ROW_SCANNER = %r{
|
|
8
|
+
\Ainfo\s
|
|
9
|
+
depth\s
|
|
10
|
+
(?<depth>\d+)\s
|
|
11
|
+
seldepth\s
|
|
12
|
+
(?<seldepth>\d+)\s
|
|
13
|
+
(multipv\s(?<multipv>\d+)\s)?
|
|
14
|
+
score\s
|
|
15
|
+
(?<score_type>\w+)?\s
|
|
16
|
+
(?<score>[-\d]+)\s
|
|
17
|
+
(lowerbound\s|upperbound\s)?
|
|
18
|
+
nodes
|
|
19
|
+
}x
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
attr_accessor :raw_analysis, :analysis
|
|
23
|
+
|
|
24
|
+
def initialize(raw_analysis = nil)
|
|
25
|
+
@raw_analysis = raw_analysis
|
|
26
|
+
@analysis = {}
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def parse
|
|
30
|
+
return handle_game_over if game_over?
|
|
31
|
+
if @raw_analysis.include?("multipv")
|
|
32
|
+
handle_multipv
|
|
33
|
+
else
|
|
34
|
+
handle_singlepv
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def game_over?
|
|
39
|
+
!!@raw_analysis[/^bestmove \(none\)$/]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def handle_game_over
|
|
43
|
+
game_over = @raw_analysis.match(/^info depth 0 score (?<outcome>[a-z]+) 0$/)
|
|
44
|
+
score = case game_over[:outcome]
|
|
45
|
+
when "mate" then "mate 0"
|
|
46
|
+
when "cp" then 0
|
|
47
|
+
end
|
|
48
|
+
@analysis = {
|
|
49
|
+
:bestmove => nil,
|
|
50
|
+
:variations => [{ :score => score, :sequence => [], :depth => 0 }]
|
|
51
|
+
}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def best_move_uci
|
|
55
|
+
@raw_analysis[/^bestmove (\w+)/, 1]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def parse_variation_row(row)
|
|
59
|
+
sequence = row.match(/ pv (?<moves>.*)/)
|
|
60
|
+
return if sequence.nil?
|
|
61
|
+
analysis = row.match(ROW_SCANNER)
|
|
62
|
+
score = case analysis[:score_type]
|
|
63
|
+
when "cp" then analysis[:score].to_f/100
|
|
64
|
+
when "mate" then "mate #{analysis[:score]}"
|
|
65
|
+
end
|
|
66
|
+
variation = {
|
|
67
|
+
:score => score,
|
|
68
|
+
:sequence => sequence[:moves].split(/\s+/),
|
|
69
|
+
:depth => analysis[:depth].to_i,
|
|
70
|
+
}
|
|
71
|
+
variation[:multipv] = analysis[:multipv].to_i if analysis[:multipv]
|
|
72
|
+
variation
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def handle_singlepv
|
|
76
|
+
@raw_analysis.strip.split("\n").reverse.each do |row|
|
|
77
|
+
variation = parse_variation_row(row)
|
|
78
|
+
next if variation.nil? || variation[:sequence].split(" ")[0] != best_move_uci
|
|
79
|
+
@analysis = {
|
|
80
|
+
:bestmove => best_move_uci,
|
|
81
|
+
:variations => [variation]
|
|
82
|
+
}
|
|
83
|
+
return @analysis
|
|
84
|
+
end
|
|
85
|
+
@analysis || {}
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def handle_multipv
|
|
89
|
+
multipv = nil
|
|
90
|
+
count = 0
|
|
91
|
+
@analysis = {
|
|
92
|
+
:bestmove => best_move_uci,
|
|
93
|
+
:variations => []
|
|
94
|
+
}
|
|
95
|
+
@raw_analysis.strip.split("\n").reverse.each do |row|
|
|
96
|
+
variation = parse_variation_row(row)
|
|
97
|
+
next if variation.nil?
|
|
98
|
+
multipv = variation[:multipv] if multipv.nil?
|
|
99
|
+
@analysis[:variations].push variation
|
|
100
|
+
count += 1
|
|
101
|
+
break if count >= multipv
|
|
102
|
+
end
|
|
103
|
+
@analysis || {}
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'open3'
|
|
2
|
+
require 'io/wait'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module Stockfish
|
|
6
|
+
|
|
7
|
+
class InvalidBinary < StandardError; end
|
|
8
|
+
class InvalidCommand < StandardError; end
|
|
9
|
+
class InvalidOption < StandardError; end
|
|
10
|
+
|
|
11
|
+
class Engine
|
|
12
|
+
attr_reader :stdin, :stdout, :stderr, :wait_threads, :version, :pid
|
|
13
|
+
|
|
14
|
+
COMMANDS = %w( uci isready setoption ucinewgame position go stop ponderhit quit )
|
|
15
|
+
|
|
16
|
+
def initialize(bin_path = `which stockfish`)
|
|
17
|
+
@stdin, @stdout, @stderr, @wait_threads = Open3.popen3(bin_path)
|
|
18
|
+
@pid = @wait_threads[:pid]
|
|
19
|
+
@version = @stdout.readline.strip
|
|
20
|
+
raise InvalidBinary.new("Not a valid Stockfish binary!") unless @version =~ /^Stockfish/
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def execute(str)
|
|
24
|
+
command = str.split(" ")[0]
|
|
25
|
+
@stdin.puts str
|
|
26
|
+
raise InvalidCommand.new(@stdout.readline.strip) unless COMMANDS.include?(command)
|
|
27
|
+
output = ""
|
|
28
|
+
case command
|
|
29
|
+
when "uci"
|
|
30
|
+
loop do
|
|
31
|
+
output << (line = @stdout.readline)
|
|
32
|
+
break if line =~ /^uciok/
|
|
33
|
+
end
|
|
34
|
+
when "go"
|
|
35
|
+
loop do
|
|
36
|
+
output << (line = @stdout.readline)
|
|
37
|
+
break if line =~ /^bestmove/
|
|
38
|
+
end
|
|
39
|
+
when "setoption"
|
|
40
|
+
sleep 0.1
|
|
41
|
+
raise InvalidOption.new(@stdout.readline.strip) if @stdout.ready?
|
|
42
|
+
when "isready"
|
|
43
|
+
output << @stdout.readline
|
|
44
|
+
end
|
|
45
|
+
output
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def multipv(n)
|
|
49
|
+
execute "setoption name MultiPV value #{n}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def ready?
|
|
53
|
+
execute("isready").strip == "readyok"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def running?
|
|
57
|
+
@wait_threads.alive?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def analyze(fen, options)
|
|
61
|
+
execute "position fen #{fen}"
|
|
62
|
+
%w( depth movetime nodes ).each do |command|
|
|
63
|
+
if (x = options[command.to_sym])
|
|
64
|
+
return execute "go #{command} #{x}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
4
|
+
$:.unshift(lib) unless $:.include?(lib)
|
|
5
|
+
|
|
6
|
+
require 'stockfish/version'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Gem::Specification.new do |s|
|
|
10
|
+
s.name = "stockfish"
|
|
11
|
+
s.version = Stockfish::VERSION
|
|
12
|
+
s.authors = ["Linmiao Xu"]
|
|
13
|
+
s.email = ["linmiao.xu@gmail.com"]
|
|
14
|
+
|
|
15
|
+
s.summary = "Ruby client for the Stockfish chess engine"
|
|
16
|
+
s.description = "Ruby client for the Stockfish chess engine"
|
|
17
|
+
s.license = "MIT"
|
|
18
|
+
|
|
19
|
+
s.files = `git ls-files -z`.split("\0")
|
|
20
|
+
|
|
21
|
+
s.add_development_dependency "rake", "~> 10.0"
|
|
22
|
+
s.add_development_dependency "minitest", "~> 5.0"
|
|
23
|
+
s.add_development_dependency "pry", "~> 0.10"
|
|
24
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AnalysisParserTest < Minitest::Test
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@klass = Stockfish::AnalysisParser
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def parsed_fixture(fixture_path)
|
|
11
|
+
analysis_output = read_fixture(fixture_path)
|
|
12
|
+
@klass.new(analysis_output).parse
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_parser_suggests_a_move_for_a_normal_position
|
|
16
|
+
output = parsed_fixture("analysis_outputs/tough_midgame.txt")
|
|
17
|
+
assert output[:variations].length == 1
|
|
18
|
+
assert output[:variations][0][:score] == -12.51
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_parser_suggests_three_variations_for_multipv_3
|
|
22
|
+
output = parsed_fixture("analysis_outputs/multipv_3.txt")
|
|
23
|
+
assert output[:variations].length == 3
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_parser_detects_stalemate
|
|
27
|
+
output = parsed_fixture("analysis_outputs/stalemate.txt")
|
|
28
|
+
assert output[:bestmove] == nil
|
|
29
|
+
assert output[:variations].length == 1
|
|
30
|
+
move = output[:variations][0]
|
|
31
|
+
assert move[:score] == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_parser_detects_checkmate
|
|
35
|
+
output = parsed_fixture("analysis_outputs/checkmate.txt")
|
|
36
|
+
assert output[:bestmove] == nil
|
|
37
|
+
assert output[:variations].length == 1
|
|
38
|
+
move = output[:variations][0]
|
|
39
|
+
assert move[:score] == "mate 0"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_parser_detects_imminent_win_by_checkmate
|
|
43
|
+
output = parsed_fixture("analysis_outputs/mate_in_1.txt")
|
|
44
|
+
assert output[:variations].length == 1
|
|
45
|
+
move = output[:variations][0]
|
|
46
|
+
assert move[:score] == "mate 1"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_parser_detects_win_by_checkmate
|
|
50
|
+
output = parsed_fixture("analysis_outputs/white_wins_in_4.txt")
|
|
51
|
+
assert output[:variations].length == 1
|
|
52
|
+
move = output[:variations][0]
|
|
53
|
+
assert move[:score] == "mate 4"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_parser_detects_loss_by_checkmate
|
|
57
|
+
output = parsed_fixture("analysis_outputs/black_loses_in_3.txt")
|
|
58
|
+
assert output[:variations].length == 1
|
|
59
|
+
move = output[:variations][0]
|
|
60
|
+
assert move[:score] == "mate -3"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
data/test/engine_test.rb
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class EngineTest < Minitest::Test
|
|
5
|
+
|
|
6
|
+
def setup
|
|
7
|
+
@klass = Stockfish::Engine
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_engine_version_is_valid
|
|
11
|
+
assert @klass.new.version[/^Stockfish \d+/]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def test_engine_is_ready?
|
|
15
|
+
assert @klass.new.ready?
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_engine_returns_position_analysis
|
|
19
|
+
fen = read_fixture("positions/stalemate.txt")
|
|
20
|
+
analysis_output = @klass.new.analyze(fen, { :depth => 6 })
|
|
21
|
+
assert analysis_output[/^info/]
|
|
22
|
+
assert analysis_output[/^bestmove/]
|
|
23
|
+
fen = read_fixture("positions/start.txt")
|
|
24
|
+
analysis_output = @klass.new.analyze(fen, { :depth => 6 })
|
|
25
|
+
assert analysis_output[/^info/]
|
|
26
|
+
assert analysis_output[/^bestmove/]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_multipv_mode_returns_multipv_output
|
|
30
|
+
engine = @klass.new
|
|
31
|
+
engine.multipv(3)
|
|
32
|
+
fen = read_fixture("positions/white_wins_in_4.txt")
|
|
33
|
+
analysis_output = engine.analyze(fen, { :depth => 6 })
|
|
34
|
+
assert analysis_output[/multipv 3/]
|
|
35
|
+
assert analysis_output[/^bestmove/]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
info depth 1 seldepth 1 multipv 1 score mate -3 nodes 10 nps 5000 tbhits 0 time 2 pv g7f6
|
|
2
|
+
info depth 2 seldepth 3 multipv 1 score mate -3 nodes 35 nps 17500 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
3
|
+
info depth 3 seldepth 5 multipv 1 score mate -3 nodes 76 nps 38000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4
|
|
4
|
+
info depth 4 seldepth 7 multipv 1 score mate -3 nodes 112 nps 56000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
5
|
+
info depth 5 seldepth 7 multipv 1 score mate -3 nodes 144 nps 72000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
6
|
+
info depth 6 seldepth 7 multipv 1 score mate -3 nodes 174 nps 87000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
7
|
+
info depth 7 seldepth 7 multipv 1 score mate -3 nodes 219 nps 109500 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
8
|
+
info depth 8 seldepth 7 multipv 1 score mate -3 nodes 263 nps 131500 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
9
|
+
info depth 9 seldepth 7 multipv 1 score mate -3 nodes 309 nps 154500 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
10
|
+
info depth 10 seldepth 7 multipv 1 score mate -3 nodes 352 nps 176000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
11
|
+
info depth 11 seldepth 7 multipv 1 score mate -3 nodes 430 nps 215000 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
12
|
+
info depth 12 seldepth 7 multipv 1 score mate -3 nodes 575 nps 287500 tbhits 0 time 2 pv g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
13
|
+
bestmove g7f6 ponder c3d5
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
info depth 1 seldepth 1 multipv 1 score cp -6 nodes 9 nps 9000 tbhits 0 time 1 pv d3c2
|
|
2
|
+
info depth 2 seldepth 2 multipv 1 score cp 6 nodes 30 nps 30000 tbhits 0 time 1 pv d3c2 e6d5
|
|
3
|
+
info depth 3 seldepth 3 multipv 1 score cp -6 nodes 93 nps 93000 tbhits 0 time 1 pv d3c2 e6d5 c2b1
|
|
4
|
+
info depth 4 seldepth 4 multipv 1 score cp 6 nodes 245 nps 245000 tbhits 0 time 1 pv d3c2 e6d5 c2b1 d5d6
|
|
5
|
+
info depth 5 seldepth 5 multipv 1 score cp -6 nodes 764 nps 382000 tbhits 0 time 2 pv d3c2 e6d5 c2b1 d5d6 b1a1
|
|
6
|
+
info depth 6 seldepth 6 multipv 1 score cp 6 nodes 1316 nps 658000 tbhits 0 time 2 pv d3c2 e6d5 c2b1 d5d6 b1a1 d6d5
|
|
7
|
+
info depth 7 seldepth 7 multipv 1 score cp -6 nodes 2876 nps 719000 tbhits 0 time 4 pv d3c2 e6d5 c2b1 d5d6 b1a1 d6c6 a1b1
|
|
8
|
+
info depth 8 seldepth 8 multipv 1 score cp 6 nodes 5134 nps 855666 tbhits 0 time 6 pv d3e4 e6d6 e4f3 d6d5 f3g2 d5c6 g2g1 c6d5
|
|
9
|
+
info depth 9 seldepth 10 multipv 1 score cp 0 nodes 8781 nps 1097625 tbhits 0 time 8 pv d3e4 e6d6 e4f3 d6d5 f3g2 d5c6 g2g1 c6c7 g1g2
|
|
10
|
+
info depth 10 seldepth 10 multipv 1 score cp 0 nodes 10472 nps 1163555 tbhits 0 time 9 pv d3e4 e6d6 e4f3 d6d5 f3g2 d5e5 g2g1 e5d5 g1g2
|
|
11
|
+
bestmove d3e4 ponder e6d6
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
info depth 1 seldepth 2 multipv 1 score mate 1 nodes 47 nps 23500 tbhits 0 time 2 pv f3f7
|
|
2
|
+
info depth 2 seldepth 2 multipv 1 score mate 1 nodes 90 nps 45000 tbhits 0 time 2 pv f3f7
|
|
3
|
+
info depth 3 seldepth 2 multipv 1 score mate 1 nodes 133 nps 66500 tbhits 0 time 2 pv f3f7
|
|
4
|
+
info depth 4 seldepth 2 multipv 1 score mate 1 nodes 176 nps 88000 tbhits 0 time 2 pv f3f7
|
|
5
|
+
info depth 5 seldepth 2 multipv 1 score mate 1 nodes 219 nps 109500 tbhits 0 time 2 pv f3f7
|
|
6
|
+
info depth 6 seldepth 2 multipv 1 score mate 1 nodes 262 nps 131000 tbhits 0 time 2 pv f3f7
|
|
7
|
+
info depth 7 seldepth 2 multipv 1 score mate 1 nodes 305 nps 152500 tbhits 0 time 2 pv f3f7
|
|
8
|
+
info depth 8 seldepth 2 multipv 1 score mate 1 nodes 348 nps 174000 tbhits 0 time 2 pv f3f7
|
|
9
|
+
info depth 9 seldepth 2 multipv 1 score mate 1 nodes 391 nps 195500 tbhits 0 time 2 pv f3f7
|
|
10
|
+
info depth 10 seldepth 2 multipv 1 score mate 1 nodes 434 nps 217000 tbhits 0 time 2 pv f3f7
|
|
11
|
+
bestmove f3f7
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
info depth 1 seldepth 1 multipv 1 score cp -72 nodes 102 nps 51000 tbhits 0 time 2 pv c8f5
|
|
2
|
+
info depth 1 seldepth 1 multipv 2 score cp -114 nodes 102 nps 51000 tbhits 0 time 2 pv c8d7
|
|
3
|
+
info depth 1 seldepth 1 multipv 3 score cp -118 nodes 102 nps 51000 tbhits 0 time 2 pv f7f5
|
|
4
|
+
info depth 2 seldepth 2 multipv 1 score cp 374 nodes 303 nps 101000 tbhits 0 time 3 pv f7f5 e4e8 d8e8
|
|
5
|
+
info depth 2 seldepth 2 multipv 2 score cp 307 nodes 303 nps 101000 tbhits 0 time 3 pv c8f5 c4a6 f5e4 a6b7
|
|
6
|
+
info depth 2 seldepth 2 multipv 3 score cp 86 nodes 303 nps 101000 tbhits 0 time 3 pv b7b5 b2b3 b5c4
|
|
7
|
+
info depth 3 seldepth 3 multipv 1 score cp 374 nodes 477 nps 159000 tbhits 0 time 3 pv f7f5 e4e8 d8e8
|
|
8
|
+
info depth 3 seldepth 3 multipv 2 score cp 307 nodes 477 nps 159000 tbhits 0 time 3 pv c8f5 c4a6 f5e4
|
|
9
|
+
info depth 3 seldepth 3 multipv 3 score cp 86 nodes 477 nps 159000 tbhits 0 time 3 pv b7b5 b2b3 b5c4
|
|
10
|
+
info depth 4 seldepth 4 multipv 1 score cp 358 nodes 757 nps 252333 tbhits 0 time 3 pv f7f5 e4e8 d8e8 a2a3
|
|
11
|
+
info depth 4 seldepth 4 multipv 2 score cp 307 nodes 757 nps 252333 tbhits 0 time 3 pv c8f5 c4a6 f5e4 a6b7
|
|
12
|
+
info depth 4 seldepth 4 multipv 3 score cp 72 nodes 757 nps 252333 tbhits 0 time 3 pv b7b5 f3d2 b5c4 d2c4
|
|
13
|
+
info depth 5 seldepth 7 multipv 1 score cp 239 nodes 2060 nps 343333 tbhits 0 time 6 pv f7f5 f3d2 f5e4 d2e4 a6a5
|
|
14
|
+
info depth 5 seldepth 7 multipv 2 score cp 237 nodes 2060 nps 343333 tbhits 0 time 6 pv c8f5 f3d2 b7b5 f2f3 f5e4
|
|
15
|
+
info depth 5 seldepth 7 multipv 3 score cp 16 nodes 2060 nps 343333 tbhits 0 time 6 pv b7b5 a1e1 b5c4 e4e8 d8e8 e1e8 d6f8
|
|
16
|
+
info depth 6 seldepth 7 multipv 1 score cp -97 nodes 6166 nps 474307 tbhits 0 time 13 pv c8f5 e4e2 d6f4 a1e1 b7b5 g2g3 b5c4
|
|
17
|
+
info depth 6 seldepth 7 multipv 2 score cp -124 nodes 6166 nps 474307 tbhits 0 time 13 pv c8d7 c4d3 d7f5 e4e3 f5d3 e3d3
|
|
18
|
+
info depth 6 seldepth 7 multipv 3 score cp -131 nodes 6166 nps 474307 tbhits 0 time 13 pv h7h5 e4e2 c8f5 a1e1 f7f6 c4d3 f5d3
|
|
19
|
+
info depth 7 seldepth 7 multipv 1 score cp -63 nodes 9227 nps 542764 tbhits 0 time 17 pv b7b5 c4d3 c8b7 e4e1 b7d5 c2c3 f7f6
|
|
20
|
+
info depth 7 seldepth 7 multipv 2 score cp -97 nodes 9227 nps 542764 tbhits 0 time 17 pv c8f5 e4e2 d6f4 a1e1 b7b5 g2g3 b5c4
|
|
21
|
+
info depth 7 seldepth 7 multipv 3 score cp -128 nodes 9227 nps 542764 tbhits 0 time 17 pv g7g5 c4d3 g5g4 f3d2 c8f5 e4e3 f5d3
|
|
22
|
+
info depth 8 seldepth 10 multipv 1 score cp -97 nodes 15550 nps 706818 tbhits 0 time 22 pv c8f5 e4e2 d6f4 a1e1 b7b5 g2g3 b5c4 g3f4
|
|
23
|
+
info depth 8 seldepth 10 multipv 2 score cp -124 nodes 15550 nps 706818 tbhits 0 time 22 pv c8d7 c4d3 c7c6 d5c6 d7c6 e4e1 b7b5 c2c4
|
|
24
|
+
info depth 8 seldepth 10 multipv 3 score cp -130 nodes 15550 nps 706818 tbhits 0 time 22 pv b7b5 c4d3 c8b7 c2c4 b5c4 d3c4 f7f5 e4e3
|
|
25
|
+
info depth 9 seldepth 13 multipv 1 score cp -109 nodes 33905 nps 997205 tbhits 0 time 34 pv c8f5 e4e2 f5g4 a1e1 g4f3 g2f3 d6f4 e2e7 b7b5 c4d3
|
|
26
|
+
info depth 9 seldepth 13 multipv 2 score cp -124 nodes 33905 nps 997205 tbhits 0 time 34 pv f7f6 c4d3 c8f5 e4e3 f5d3 e3d3 g8f7 c2c4 c7c6 d5c6
|
|
27
|
+
info depth 9 seldepth 13 multipv 3 score cp -132 nodes 33905 nps 997205 tbhits 0 time 34 pv b7b5 c4d3 c8b7 c2c4 f7f5 e4e1 b5c4 d3c4 d6f4
|
|
28
|
+
info depth 10 seldepth 15 multipv 1 score cp -108 nodes 79802 nps 1308229 tbhits 0 time 61 pv c8f5 e4e2 f5g4 a1e1 g4f3 g2f3 b7b5 c4d3 g7g6 c2c3 g8g7 g1g2 f7f5 e2e3
|
|
29
|
+
info depth 10 seldepth 15 multipv 2 score cp -108 nodes 79802 nps 1308229 tbhits 0 time 61 pv g7g6 a1e1 c8f5 e4e2 f5g4 c4d3 g4f3 g2f3 b7b5 c2c3
|
|
30
|
+
info depth 10 seldepth 15 multipv 3 score cp -114 nodes 79802 nps 1308229 tbhits 0 time 61 pv b7b5 c4b3 c8f5 e4e1 f7f6 c2c3 f5g4 a2a3 g4f3 g2f3
|
|
31
|
+
bestmove c8f5 ponder e4e2
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
info depth 1 seldepth 1 multipv 1 score cp 0 nodes 31 nps 31000 tbhits 0 time 1 pv d5e4
|
|
2
|
+
info depth 2 seldepth 2 multipv 1 score cp 0 nodes 75 nps 75000 tbhits 0 time 1 pv d5e4 h7f7
|
|
3
|
+
info depth 3 seldepth 3 multipv 1 score cp 0 nodes 131 nps 131000 tbhits 0 time 1 pv d5e4 h7f7 e7f6
|
|
4
|
+
info depth 4 seldepth 5 multipv 1 score cp 0 nodes 232 nps 116000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
5
|
+
info depth 5 seldepth 7 multipv 1 score cp 0 nodes 346 nps 173000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
6
|
+
info depth 6 seldepth 8 multipv 1 score cp 0 nodes 478 nps 239000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
7
|
+
info depth 7 seldepth 8 multipv 1 score cp 0 nodes 636 nps 318000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
8
|
+
info depth 8 seldepth 8 multipv 1 score cp 0 nodes 836 nps 418000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
9
|
+
info depth 9 seldepth 8 multipv 1 score cp 0 nodes 1186 nps 593000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
10
|
+
info depth 10 seldepth 8 multipv 1 score cp 0 nodes 1584 nps 792000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
11
|
+
info depth 11 seldepth 8 multipv 1 score cp 0 nodes 2168 nps 1084000 tbhits 0 time 2 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
12
|
+
info depth 12 seldepth 8 multipv 1 score cp 0 nodes 2744 nps 914666 tbhits 0 time 3 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
13
|
+
info depth 13 seldepth 8 multipv 1 score cp 0 nodes 3486 nps 1162000 tbhits 0 time 3 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
14
|
+
info depth 14 seldepth 8 multipv 1 score cp 0 nodes 4444 nps 1481333 tbhits 0 time 3 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
15
|
+
info depth 15 seldepth 8 multipv 1 score cp 0 nodes 5649 nps 1412250 tbhits 0 time 4 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
16
|
+
info depth 16 seldepth 8 multipv 1 score cp 0 nodes 6979 nps 1744750 tbhits 0 time 4 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
17
|
+
info depth 17 seldepth 8 multipv 1 score cp 0 nodes 8532 nps 1706400 tbhits 0 time 5 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
18
|
+
info depth 18 seldepth 8 multipv 1 score cp 0 nodes 10474 nps 1745666 tbhits 0 time 6 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
19
|
+
info depth 19 seldepth 8 multipv 1 score cp 0 nodes 12770 nps 2128333 tbhits 0 time 6 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
20
|
+
info depth 20 seldepth 8 multipv 1 score cp 0 nodes 15352 nps 2193142 tbhits 0 time 7 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
21
|
+
info depth 21 seldepth 8 multipv 1 score cp 0 nodes 18208 nps 2276000 tbhits 0 time 8 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
22
|
+
info depth 22 seldepth 8 multipv 1 score cp 0 nodes 21852 nps 2185200 tbhits 0 time 10 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
23
|
+
info depth 23 seldepth 8 multipv 1 score cp 0 nodes 60706 nps 1839575 tbhits 0 time 33 pv d5e4 h7f7 e7f6 e3d2 e4d4 d2e3 d4e4
|
|
24
|
+
info depth 24 currmove d5c4 currmovenumber 3
|
|
25
|
+
info depth 24 seldepth 57 multipv 1 score cp -1251 nodes 7541511 nps 2078123 tbhits 0 time 3629 pv d5e6 h7g6 e7f6 g6f5 e6f7 f5h7 f7f8 e3h6 d7g7 e1f1 f8e7 h6g7 b7e4 g7f6 e7e6 h7h3 e6d5 f6d8 e8d8 h3e3 e4g6 e3f3 g6e4 f1d1 d5c6 f3e4 c6c7 d1f1 d8d7 f1f6 d7d8 f6f7 d8d7 f7d7 c7d7 e4b7 d7e6 b2b4 e6f6 b7a6 f6e6
|
|
26
|
+
bestmove d5e6 ponder h7g6
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
info depth 1 seldepth 1 multipv 1 score cp 846 nodes 79 nps 39500 tbhits 0 time 2 pv c3d5 c6d4
|
|
2
|
+
info depth 2 seldepth 3 multipv 1 score cp 878 nodes 244 nps 122000 tbhits 0 time 2 pv h3h7 g7f6 g5f7
|
|
3
|
+
info depth 3 seldepth 4 multipv 1 score cp 887 nodes 434 nps 144666 tbhits 0 time 3 pv h3h7 g7f6 g5f7 f8f7 c3d5 f6e6 h7g6 f7f6
|
|
4
|
+
info depth 4 seldepth 8 multipv 1 score mate 4 nodes 616 nps 205333 tbhits 0 time 3 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
5
|
+
info depth 5 seldepth 8 multipv 1 score mate 4 nodes 700 nps 233333 tbhits 0 time 3 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
6
|
+
info depth 6 seldepth 8 multipv 1 score mate 4 nodes 786 nps 262000 tbhits 0 time 3 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
7
|
+
info depth 7 seldepth 8 multipv 1 score mate 4 nodes 942 nps 314000 tbhits 0 time 3 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
8
|
+
info depth 8 seldepth 8 multipv 1 score mate 4 nodes 1104 nps 276000 tbhits 0 time 4 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
9
|
+
info depth 9 seldepth 8 multipv 1 score mate 4 nodes 1445 nps 361250 tbhits 0 time 4 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
10
|
+
info depth 10 seldepth 8 multipv 1 score mate 4 nodes 1862 nps 372400 tbhits 0 time 5 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
11
|
+
info depth 11 seldepth 8 multipv 1 score mate 4 nodes 2430 nps 405000 tbhits 0 time 6 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
12
|
+
info depth 12 seldepth 8 multipv 1 score mate 4 nodes 3489 nps 436125 tbhits 0 time 8 pv h3h7 g7f6 c3d5 f6g5 f2f4 g5g4 f1e2
|
|
13
|
+
bestmove h3h7 ponder g7f6
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
8/8/8/8/8/1k6/p7/K7 w - - 0 1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
r1bq1r2/p1ppppk1/1pn3p1/3n2N1/3PP3/2N4Q/PPP2PPP/R3KB1R w KQ - 2 10
|
data/test/test_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: stockfish
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.3.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Linmiao Xu
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-12-09 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: rake
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ~>
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '10.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '10.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: minitest
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ~>
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '5.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - ~>
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '5.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: pry
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ~>
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.10'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - ~>
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.10'
|
|
55
|
+
description: Ruby client for the Stockfish chess engine
|
|
56
|
+
email:
|
|
57
|
+
- linmiao.xu@gmail.com
|
|
58
|
+
executables: []
|
|
59
|
+
extensions: []
|
|
60
|
+
extra_rdoc_files: []
|
|
61
|
+
files:
|
|
62
|
+
- .gitignore
|
|
63
|
+
- Gemfile
|
|
64
|
+
- README.md
|
|
65
|
+
- Rakefile
|
|
66
|
+
- bin/console
|
|
67
|
+
- lib/stockfish.rb
|
|
68
|
+
- lib/stockfish/analysis_parser.rb
|
|
69
|
+
- lib/stockfish/engine.rb
|
|
70
|
+
- lib/stockfish/version.rb
|
|
71
|
+
- ruby-stockfish.gemspec
|
|
72
|
+
- test/analysis_parser_test.rb
|
|
73
|
+
- test/engine_test.rb
|
|
74
|
+
- test/fixtures/analysis_outputs/black_loses_in_3.txt
|
|
75
|
+
- test/fixtures/analysis_outputs/checkmate.txt
|
|
76
|
+
- test/fixtures/analysis_outputs/kvk_endgame.txt
|
|
77
|
+
- test/fixtures/analysis_outputs/mate_in_1.txt
|
|
78
|
+
- test/fixtures/analysis_outputs/multipv_3.txt
|
|
79
|
+
- test/fixtures/analysis_outputs/stalemate.txt
|
|
80
|
+
- test/fixtures/analysis_outputs/tough_midgame.txt
|
|
81
|
+
- test/fixtures/analysis_outputs/white_wins_in_4.txt
|
|
82
|
+
- test/fixtures/positions/stalemate.txt
|
|
83
|
+
- test/fixtures/positions/start.txt
|
|
84
|
+
- test/fixtures/positions/white_wins_in_4.txt
|
|
85
|
+
- test/test_helper.rb
|
|
86
|
+
homepage:
|
|
87
|
+
licenses:
|
|
88
|
+
- MIT
|
|
89
|
+
metadata: {}
|
|
90
|
+
post_install_message:
|
|
91
|
+
rdoc_options: []
|
|
92
|
+
require_paths:
|
|
93
|
+
- lib
|
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
|
+
requirements:
|
|
96
|
+
- - '>='
|
|
97
|
+
- !ruby/object:Gem::Version
|
|
98
|
+
version: '0'
|
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - '>='
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
requirements: []
|
|
105
|
+
rubyforge_project:
|
|
106
|
+
rubygems_version: 2.1.11
|
|
107
|
+
signing_key:
|
|
108
|
+
specification_version: 4
|
|
109
|
+
summary: Ruby client for the Stockfish chess engine
|
|
110
|
+
test_files: []
|