chess_openings 0.0.3 → 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 +4 -4
- data/.gitignore +3 -1
- data/.yardoc/checksums +4 -0
- data/.yardoc/complete +0 -0
- data/.yardoc/object_types +0 -0
- data/.yardoc/objects/root.dat +0 -0
- data/.yardoc/proxy_types +0 -0
- data/Gemfile +3 -2
- data/Gemfile.lock +13 -2
- data/README.md +124 -10
- data/{openings_parser.rb → bin/openings_parser} +24 -23
- data/chess_openings.gemspec +16 -14
- data/doc/ChessOpenings.html +1163 -0
- data/doc/ChessOpeningsHelper.html +355 -0
- data/doc/InvalidPGNError.html +135 -0
- data/doc/Opening.html +909 -0
- data/doc/SearchTree/Node.html +770 -0
- data/doc/SearchTree.html +1081 -0
- data/doc/_index.html +166 -0
- data/doc/class_list.html +51 -0
- data/doc/css/common.css +1 -0
- data/doc/css/full_list.css +58 -0
- data/doc/css/style.css +492 -0
- data/doc/file.README.html +241 -0
- data/doc/file_list.html +56 -0
- data/doc/frames.html +17 -0
- data/doc/index.html +241 -0
- data/doc/js/app.js +243 -0
- data/doc/js/full_list.js +216 -0
- data/doc/js/jquery.js +4 -0
- data/doc/method_list.html +371 -0
- data/doc/top-level-namespace.html +110 -0
- data/lib/chess_openings/chess_openings_helper.rb +18 -0
- data/lib/chess_openings/json_openings/openings.json +3 -3
- data/lib/chess_openings/opening.rb +31 -15
- data/lib/chess_openings/search_tree.rb +97 -81
- data/lib/chess_openings.rb +51 -20
- metadata +61 -7
- data/chess_openings-0.0.1.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 78417b3eddb5c39e879ca39404958b23aa2284ed
|
4
|
+
data.tar.gz: 3e83d4e26d315c9aaca05f1f67c86f01f6ff7d3e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5472f322d4504f665088cf703aa66b22af932049130c605de3a42308f1e34f64d08cd3187c8e32e4768dbc889a21d2786d07c82169a25ef873cbf92604d9f4d8
|
7
|
+
data.tar.gz: b5b1f0e194ce3f92d04122b69e99afa204939c044aa3f58dea73fac198eb13787640b3719922a18244fea2260a1310b5dc4fa92f1a342cb3f4c23fe521593d16
|
data/.gitignore
CHANGED
data/.yardoc/checksums
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
lib/chess_openings.rb 46752f37f62d27c9adc0c321f48ffc4f89cda525
|
2
|
+
lib/chess_openings/opening.rb 47b8824624e83318b4855a0ebf10b44cd3208813
|
3
|
+
lib/chess_openings/search_tree.rb f98ffb2f3089682a85ba6b4a129512d0d30c5b36
|
4
|
+
lib/chess_openings/chess_openings_helper.rb 0f39c3cb6fbd142bb50a222a52ebfa90ef0b74a4
|
data/.yardoc/complete
ADDED
File without changes
|
Binary file
|
Binary file
|
data/.yardoc/proxy_types
ADDED
Binary file
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
GEM
|
2
2
|
remote: https://rubygems.org/
|
3
3
|
specs:
|
4
|
+
coderay (1.1.0)
|
4
5
|
diff-lcs (1.2.5)
|
6
|
+
method_source (0.8.2)
|
5
7
|
mini_portile (0.6.2)
|
6
8
|
nokogiri (1.6.6.2)
|
7
9
|
mini_portile (~> 0.6.0)
|
8
|
-
pgn (0.
|
10
|
+
pgn (0.1.1)
|
9
11
|
whittle
|
12
|
+
pry (0.10.3)
|
13
|
+
coderay (~> 1.1.0)
|
14
|
+
method_source (~> 0.8.1)
|
15
|
+
slop (~> 3.4)
|
10
16
|
rspec (3.3.0)
|
11
17
|
rspec-core (~> 3.3.0)
|
12
18
|
rspec-expectations (~> 3.3.0)
|
@@ -20,6 +26,7 @@ GEM
|
|
20
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
21
27
|
rspec-support (~> 3.3.0)
|
22
28
|
rspec-support (3.3.0)
|
29
|
+
slop (3.6.0)
|
23
30
|
whittle (0.0.8)
|
24
31
|
|
25
32
|
PLATFORMS
|
@@ -27,5 +34,9 @@ PLATFORMS
|
|
27
34
|
|
28
35
|
DEPENDENCIES
|
29
36
|
nokogiri (= 1.6.6.2)
|
30
|
-
pgn (= 0.
|
37
|
+
pgn (= 0.1.1)
|
38
|
+
pry
|
31
39
|
rspec (~> 3.3.0)
|
40
|
+
|
41
|
+
BUNDLED WITH
|
42
|
+
1.10.6
|
data/README.md
CHANGED
@@ -1,23 +1,17 @@
|
|
1
1
|
Chess Openings
|
2
2
|
==========================
|
3
|
-
|
4
|
-
|
5
|
-
## TODOS:
|
6
|
-
- Write documentation
|
7
|
-
- Wrap everything up in a Ruby gem
|
8
|
-
- Get opening from FEN
|
9
|
-
- Make CLI to parse openings from website
|
3
|
+
Ruby gem that where you can manipulate, search for and get information from chess openings.
|
10
4
|
|
11
5
|
## Features:
|
12
6
|
- Get opening from PGN file
|
13
7
|
- Get opening from PGN string
|
14
8
|
- Get opening from array with moves
|
15
|
-
- Get opening from FEN
|
9
|
+
- Get opening from FEN
|
16
10
|
- Search opening by name
|
17
11
|
- Get all openings
|
18
12
|
- Get all openings that start with some determined moves
|
19
13
|
- Get PGN string from an opening
|
20
|
-
- Get
|
14
|
+
- Get FEN from an opening
|
21
15
|
|
22
16
|
## Installation
|
23
17
|
|
@@ -37,7 +31,127 @@ Or install it yourself as:
|
|
37
31
|
|
38
32
|
## Usage
|
39
33
|
|
40
|
-
|
34
|
+
First things first, you need to create a new ChessOpenings object:
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
chess_openings = ChessOpenings.new
|
38
|
+
```
|
39
|
+
|
40
|
+
From here you can use several functions:
|
41
|
+
|
42
|
+
####.from_pgn
|
43
|
+
Get opening from PGN file
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
chess_openings = ChessOpenings.new
|
47
|
+
opening = chess_openings.from_pgn('path_to/pgn_game.pgn')
|
48
|
+
#=> #<Opening:0x007fda6237b510 @name="English, Sicilian reversed", @eco_code="A25", @moves=[:c4, :e5, :Nc3, :Nc6]>
|
49
|
+
```
|
50
|
+
|
51
|
+
|
52
|
+
####.from_string
|
53
|
+
Get opening from a string, formated like a PGN file
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
chess_openings = ChessOpenings.new
|
57
|
+
opening = chess_openings.from_string("1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Bxc6")
|
58
|
+
#=> #<Opening:0x007f820961bf60 @name="Ruy Lopez, exchange variation", @eco_code="C68", @moves=[:e4, :e5, :Nf3, :Nc6, :Bb5, :a6, :Bxc6]>
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
####.from_moves
|
63
|
+
Get opening from an array with moves (as symbols or strings)
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
chess_openings = ChessOpenings.new
|
67
|
+
opening = chess_openings.from_moves [:e4, :c6, :d4, :d5]
|
68
|
+
#=> #<Opening:0x007f8209d9c910 @name="Caro-Kann defence", @eco_code="B12", @moves=[:e4, :c6, :d4, :d5]>
|
69
|
+
```
|
70
|
+
|
71
|
+
####.with_name
|
72
|
+
Search openings by name
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
chess_openings = ChessOpenings.new
|
76
|
+
openings = chess_openings.with_name "alekhine defence"
|
77
|
+
=begin
|
78
|
+
[
|
79
|
+
[ 0] #<Opening:0x007f8209de8a18 @name="Alekhine's defence", @eco_code="B02", @moves=[:e4, :Nf6]>,
|
80
|
+
[ 1] #<Opening:0x007f8209de8950 @name="Alekhine's defence, Scandinavian variation", @eco_code="B02", @moves=[:e4, :Nf6, :Nc3, :d5]>,
|
81
|
+
[ 2] #<Opening:0x007f8209de87e8 @name="Alekhine's defence, Spielmann variation", @eco_code="B02", @moves=[:e4, :Nf6, :Nc3, :d5, :e5, :Nfd7, :e6]>,
|
82
|
+
...
|
83
|
+
]
|
84
|
+
=end
|
85
|
+
```
|
86
|
+
|
87
|
+
####.get_all
|
88
|
+
Get all existing openings as an array
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
chess_openings = ChessOpenings.new
|
92
|
+
all_openings = chess_openings.get_all
|
93
|
+
=begin
|
94
|
+
[
|
95
|
+
[0] #<Opening:0x007f8209dd4b30 @name="Polish (Sokolsky) opening", @eco_code="A00", @moves=[:b4]>,
|
96
|
+
[1] #<Opening:0x007f8209dd4a90 @name="Polish, Tuebingen variation", @eco_code="A00", @moves=[:b4, :Nh6]>,
|
97
|
+
[2] #<Opening:0x007f8209dd49c8 @name="Polish, Outflank variation", @eco_code="A00", @moves=[:b4, :c6]>,
|
98
|
+
...
|
99
|
+
]
|
100
|
+
=end
|
101
|
+
```
|
102
|
+
|
103
|
+
####.that_start_with
|
104
|
+
Get all possible openings that start with determined moves
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
chess_openings = ChessOpenings.new
|
108
|
+
e4_e5_openings = chess_openings.that_start_with [:e4, :e5]
|
109
|
+
|
110
|
+
=begin
|
111
|
+
[
|
112
|
+
[0] #<Opening:0x007ff69c858258 @name="King's pawn game", @eco_code="C20", @moves=[:e4, :e5]>,
|
113
|
+
[1] #<Opening:0x007ff69c858190 @name="KP, Indian opening", @eco_code="C20", @moves=[:e4, :e5, :d3]>,
|
114
|
+
[2] #<Opening:0x007ff69c8580a0 @name="KP, Mengarini's opening", @eco_code="C20", @moves=[:e4, :e5, :a3]>,
|
115
|
+
[3] #<Opening:0x007ff69a1a3dd8 @name="KP, King's head opening", @eco_code="C20", @moves=[:e4, :e5, :f3]>,
|
116
|
+
[4] #<Opening:0x007ff69a1a3248 @name="KP, Patzer opening", @eco_code="C20", @moves=[:e4, :e5, :Qh5]>
|
117
|
+
...
|
118
|
+
]
|
119
|
+
=end
|
120
|
+
```
|
121
|
+
|
122
|
+
####.from_fen
|
123
|
+
Get opening from FEN string
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
opening_from_fen = chess_openings.from_fen 'rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq e6 0 2'
|
127
|
+
#=> #<Opening:0x007ff69c858258 @name="King's pawn game", @eco_code="C20", @moves=[:e4, :e5]>
|
128
|
+
```
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
When you have a opening you can invoke these methods on it:
|
135
|
+
|
136
|
+
####.to_pgn
|
137
|
+
Get PGN string from an opening
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
opening = chess_openings.from_moves [:e4, :e5, :Nf3, :Nc6, :Bb5, :a6, :Bxc6]
|
141
|
+
#=> #<Opening:0x007f820961bf60 @name="Ruy Lopez, exchange variation", @eco_code="C68", @moves=[:e4, :e5, :Nf3, :Nc6, :Bb5, :a6, :Bxc6]>
|
142
|
+
opening.to_pgn
|
143
|
+
#=> "1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Bxc6"
|
144
|
+
```
|
145
|
+
|
146
|
+
####.to_fen
|
147
|
+
Get FEN string of the opening
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
opening = chess_openings.from_moves [:e4, :e5]
|
151
|
+
#=> #<Opening:0x007ff69c858258 @name="King's pawn game", @eco_code="C20", @moves=[:e4, :e5]>
|
152
|
+
opening.to_fen
|
153
|
+
#=> 'rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq e6 0 2'
|
154
|
+
```
|
41
155
|
|
42
156
|
## Development
|
43
157
|
|
@@ -1,7 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
require 'nokogiri'
|
2
4
|
require 'open-uri'
|
3
5
|
require 'json'
|
4
|
-
|
6
|
+
require_relative '../lib/chess_openings/opening'
|
7
|
+
|
8
|
+
puts 'working'
|
5
9
|
|
6
10
|
def get_eco_code(name)
|
7
11
|
name.split(' ').first
|
@@ -11,33 +15,30 @@ def remove_eco_code(name)
|
|
11
15
|
name.split(' ').drop(1).join(' ')
|
12
16
|
end
|
13
17
|
|
14
|
-
def
|
18
|
+
def more_than_1_code?(name)
|
15
19
|
get_eco_code(name).size > 3
|
16
20
|
end
|
17
21
|
|
18
22
|
def convert_line_to_array(moves)
|
19
|
-
moves.split(' ').select{ |move| !move.include?('.') }
|
23
|
+
moves.split(' ').select { |move| !move.include?('.') }
|
20
24
|
end
|
21
25
|
|
22
|
-
initial_page =
|
26
|
+
initial_page = 'http://www.365chess.com/eco.php'
|
23
27
|
|
24
28
|
openings = []
|
25
29
|
pages_to_scrap = [initial_page]
|
26
30
|
|
27
31
|
# Scrap pages in pages_to_scrap array and dump Opening objects to openings array
|
28
32
|
pages_to_scrap.each do |link|
|
29
|
-
|
30
|
-
page = Nokogiri::HTML(open(link))
|
33
|
+
page = Nokogiri::HTML(open(link))
|
31
34
|
page.css('ul#tree li.closed div.line').each do |line|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
pages_to_scrap << line.css('div.opname a').first["href"]
|
35
|
+
if more_than_1_code?(line.css('div.opname a').text)
|
36
|
+
pages_to_scrap << line.css('div.opname a').first['href']
|
36
37
|
else
|
37
38
|
name = remove_eco_code(line.css('div.opname a').text)
|
38
39
|
eco = get_eco_code(line.css('div.opname a').text)
|
39
|
-
|
40
|
-
|
40
|
+
class_name = line.css('div.fright').text.empty? ? 'opmoves' : 'fright'
|
41
|
+
moves = convert_line_to_array(line.css("div.#{class_name}").text)
|
41
42
|
openings << Opening.new(name, eco, moves)
|
42
43
|
end
|
43
44
|
end
|
@@ -59,27 +60,27 @@ end
|
|
59
60
|
if invalid_openings.empty?
|
60
61
|
|
61
62
|
# Convert array elements to hashes
|
62
|
-
openings.map!
|
63
|
+
openings.map!(&:to_h)
|
63
64
|
|
64
65
|
# Write to JSON
|
65
|
-
|
66
|
-
File.
|
66
|
+
json_file = 'openings.json'
|
67
|
+
File.delete(json_file) if File.exist?(json_file)
|
68
|
+
File.open(json_file, 'a+') do |file|
|
67
69
|
file.write("{\n")
|
68
70
|
file.write("\"openings\": [\n")
|
69
|
-
|
71
|
+
|
70
72
|
openings.each_with_index do |op, index|
|
71
|
-
result = openings.size == index + 1 ?
|
73
|
+
result = openings.size == index + 1 ? '' : ', '
|
72
74
|
file.write("#{JSON.generate(op)}#{result}\n")
|
73
75
|
end
|
74
|
-
|
75
|
-
file.write("]")
|
76
|
-
file.write("}")
|
77
76
|
|
78
|
-
|
77
|
+
file.write(']')
|
78
|
+
file.write('}')
|
79
|
+
|
80
|
+
puts 'openings.json was successfully created!'
|
79
81
|
end
|
80
82
|
|
81
83
|
else
|
82
|
-
puts
|
84
|
+
puts 'There were some invalid openings detected:'
|
83
85
|
puts invalid_openings
|
84
86
|
end
|
85
|
-
|
data/chess_openings.gemspec
CHANGED
@@ -3,26 +3,28 @@ lib = File.expand_path('../lib', __FILE__)
|
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
7
|
-
spec.version =
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
6
|
+
spec.name = 'chess_openings'
|
7
|
+
spec.version = '1.0.0'
|
8
|
+
spec.authors = ['Simão Neves']
|
9
|
+
spec.email = ['simaocostaneves@gmail.com']
|
10
10
|
|
11
11
|
if spec.respond_to?(:metadata)
|
12
12
|
end
|
13
13
|
|
14
|
-
spec.summary =
|
15
|
-
spec.description =
|
16
|
-
spec.homepage =
|
17
|
-
spec.license =
|
14
|
+
spec.summary = 'Gem that allows you to calculate which opening was used in a chess game'
|
15
|
+
spec.description = 'Gem that allows you to know what chess opening was used in a chess game, find chess openings by name or get all openings that start with certain moves'
|
16
|
+
spec.homepage = 'http://www.github.com/simaoneves/chess_openings'
|
17
|
+
spec.license = 'MIT'
|
18
18
|
|
19
19
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
|
-
spec.executables
|
21
|
-
spec.require_paths = [
|
20
|
+
spec.executables << 'openings_parser'
|
21
|
+
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency 'pgn', '0.1.1'
|
24
24
|
spec.add_dependency 'nokogiri', '1.6.6.2'
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.8'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.3.0'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
spec.add_development_dependency 'yard'
|
29
|
+
spec.add_development_dependency 'pry'
|
28
30
|
end
|