jkf 0.4.0 → 0.4.1
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/.codeclimate.yml +28 -0
- data/.hound.yml +3 -0
- data/.rubocop.yml +1009 -0
- data/.rubocop_todo.yml +11 -0
- data/.travis.yml +3 -0
- data/Gemfile +17 -2
- data/Guardfile +19 -62
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/jkf.gemspec +13 -18
- data/lib/jkf.rb +3 -3
- data/lib/jkf/converter.rb +6 -4
- data/lib/jkf/converter/base.rb +8 -0
- data/lib/jkf/converter/csa.rb +109 -104
- data/lib/jkf/converter/ki2.rb +63 -223
- data/lib/jkf/converter/kif.rb +62 -239
- data/lib/jkf/converter/kifuable.rb +189 -0
- data/lib/jkf/parser.rb +5 -4
- data/lib/jkf/parser/base.rb +53 -10
- data/lib/jkf/parser/csa.rb +279 -474
- data/lib/jkf/parser/ki2.rb +131 -965
- data/lib/jkf/parser/kif.rb +191 -1142
- data/lib/jkf/parser/kifuable.rb +608 -0
- data/lib/jkf/version.rb +1 -1
- metadata +10 -59
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-02-24 04:22:16 +0900 using RuboCop version 0.37.2.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 30
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 127
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,4 +1,19 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in jkf.gemspec
|
4
3
|
gemspec
|
4
|
+
|
5
|
+
gem "rake", "~> 10.0"
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
gem "yard", require: false
|
9
|
+
gem "redcarpet", require: false
|
10
|
+
|
11
|
+
gem "rubocop", "~> 0.37.2", require: false
|
12
|
+
gem "guard-rubocop", require: false
|
13
|
+
end
|
14
|
+
|
15
|
+
group :test do
|
16
|
+
gem "codeclimate-test-reporter", require: nil
|
17
|
+
gem "rspec", "~> 3.0", require: false
|
18
|
+
gem "guard-rspec", require: false
|
19
|
+
end
|
data/Guardfile
CHANGED
@@ -1,70 +1,27 @@
|
|
1
|
-
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
1
|
+
scope(groups: %w(specs))
|
3
2
|
|
4
|
-
|
5
|
-
# directories %w(app lib config test spec features) \
|
6
|
-
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
|
3
|
+
directories %w(spec lib)
|
7
4
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
# $ mkdir config
|
13
|
-
# $ mv Guardfile config/
|
14
|
-
# $ ln -s config/Guardfile .
|
15
|
-
#
|
16
|
-
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
5
|
+
group :specs, halt_on_fail: true do
|
6
|
+
guard :rspec, cmd: "bundle exec rspec", failed_mode: :keep do
|
7
|
+
require "guard/rspec/dsl"
|
8
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
17
9
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# installed the spring binstubs per the docs)
|
24
|
-
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
25
|
-
# * 'just' rspec: 'rspec'
|
10
|
+
# RSpec files
|
11
|
+
rspec = dsl.rspec
|
12
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
13
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
14
|
+
watch(rspec.spec_files)
|
26
15
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# Feel free to open issues for suggestions and improvements
|
32
|
-
|
33
|
-
# RSpec files
|
34
|
-
rspec = dsl.rspec
|
35
|
-
watch(rspec.spec_helper) { rspec.spec_dir }
|
36
|
-
watch(rspec.spec_support) { rspec.spec_dir }
|
37
|
-
watch(rspec.spec_files)
|
38
|
-
|
39
|
-
# Ruby files
|
40
|
-
ruby = dsl.ruby
|
41
|
-
dsl.watch_spec_files_for(ruby.lib_files)
|
42
|
-
|
43
|
-
# Rails files
|
44
|
-
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
45
|
-
dsl.watch_spec_files_for(rails.app_files)
|
46
|
-
dsl.watch_spec_files_for(rails.views)
|
47
|
-
|
48
|
-
watch(rails.controllers) do |m|
|
49
|
-
[
|
50
|
-
rspec.spec.("routing/#{m[1]}_routing"),
|
51
|
-
rspec.spec.("controllers/#{m[1]}_controller"),
|
52
|
-
rspec.spec.("acceptance/#{m[1]}")
|
53
|
-
]
|
16
|
+
# Ruby files
|
17
|
+
ruby = dsl.ruby
|
18
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
54
19
|
end
|
55
20
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
60
|
-
|
61
|
-
# Capybara features specs
|
62
|
-
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
63
|
-
watch(rails.layouts) { |m| rspec.spec.("features/#{m[1]}") }
|
64
|
-
|
65
|
-
# Turnip features and steps
|
66
|
-
watch(%r{^spec/acceptance/(.+)\.feature$})
|
67
|
-
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
68
|
-
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
21
|
+
guard :rubocop, all_on_start: false, cli: "--rails" do
|
22
|
+
watch(%r{.+\.rb$}) { |m| m[0] }
|
23
|
+
watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
|
69
24
|
end
|
70
25
|
end
|
26
|
+
|
27
|
+
# vim: ft=ruby
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Jkf
|
2
|
-
[](https://travis-ci.org/iyuuya/jkf)
|
2
|
+
[](https://badge.fury.io/rb/jkf) [](https://travis-ci.org/iyuuya/jkf) [](https://codeclimate.com/github/iyuuya/jkf) [](https://codeclimate.com/github/iyuuya/jkf/coverage) [](http://inch-ci.org/github/iyuuya/jkf)
|
3
3
|
|
4
4
|
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/jkf`. To experiment with that code, run `bin/console` for an interactive prompt.
|
5
5
|
|
data/Rakefile
CHANGED
data/jkf.gemspec
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "jkf/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
7
|
+
spec.name = "jkf"
|
8
|
+
spec.version = Jkf::VERSION
|
9
|
+
spec.authors = ["iyuuya"]
|
10
|
+
spec.email = ["i.yuuya@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary
|
13
|
-
spec.description
|
14
|
-
spec.homepage
|
15
|
-
spec.license
|
12
|
+
spec.summary = "jkf/csa/kif/ki2 parser and converter"
|
13
|
+
spec.description = "converter/parser of records of shogi"
|
14
|
+
spec.homepage = "https://github.com/iyuuya/jkf"
|
15
|
+
spec.license = "MIT"
|
16
16
|
|
17
|
-
spec.files
|
18
|
-
spec.bindir
|
19
|
-
spec.executables
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
-
|
22
|
-
spec.add_development_dependency "bundler", "~> 1.11"
|
23
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
25
|
-
spec.add_development_dependency "guard-rspec"
|
26
21
|
end
|
data/lib/jkf.rb
CHANGED
@@ -7,7 +7,7 @@ module Jkf
|
|
7
7
|
class FileTypeError < StandardError; end
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def parse_file(filename, encoding:
|
10
|
+
def parse_file(filename, encoding: "Shift_JIS")
|
11
11
|
parser = case ::File.extname(filename)
|
12
12
|
when /kif/
|
13
13
|
::Jkf::Parser::Kif.new
|
@@ -15,8 +15,8 @@ module Jkf
|
|
15
15
|
::Jkf::Parser::Ki2.new
|
16
16
|
when /csa/
|
17
17
|
::Jkf::Parser::Csa.new
|
18
|
-
|
19
|
-
|
18
|
+
when /jkf|json/
|
19
|
+
JSON
|
20
20
|
end
|
21
21
|
str = File.read(File.expand_path(filename), encoding: encoding).toutf8
|
22
22
|
parser.parse(str)
|
data/lib/jkf/converter.rb
CHANGED
@@ -4,7 +4,9 @@ module Jkf
|
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
7
|
+
require "json"
|
8
|
+
require "jkf/converter/base"
|
9
|
+
require "jkf/converter/kifuable"
|
10
|
+
require "jkf/converter/kif"
|
11
|
+
require "jkf/converter/ki2"
|
12
|
+
require "jkf/converter/csa"
|
data/lib/jkf/converter/csa.rb
CHANGED
@@ -1,135 +1,88 @@
|
|
1
1
|
module Jkf::Converter
|
2
|
-
class Csa
|
3
|
-
VERSION =
|
4
|
-
|
5
|
-
def convert(jkf)
|
6
|
-
hash = if jkf.is_a?(Hash)
|
7
|
-
jkf
|
8
|
-
else
|
9
|
-
JSON.parse(jkf)
|
10
|
-
end
|
2
|
+
class Csa < Base
|
3
|
+
VERSION = "2.2".freeze
|
11
4
|
|
5
|
+
def convert_root(jkf)
|
12
6
|
result = version
|
13
|
-
result += convert_information(
|
14
|
-
result += convert_initial(
|
15
|
-
result += convert_moves(
|
7
|
+
result += convert_information(jkf["header"]) if jkf["header"]
|
8
|
+
result += convert_initial(jkf["initial"]) if jkf["initial"]
|
9
|
+
result += convert_moves(jkf["moves"]) if jkf["moves"]
|
16
10
|
result
|
17
11
|
end
|
18
12
|
|
13
|
+
protected
|
14
|
+
|
19
15
|
def convert_information(header)
|
20
|
-
result =
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
result = ""
|
17
|
+
if header["先手"] || header["下手"]
|
18
|
+
result += "N+" + (header.delete("先手") || header.delete("下手") || "") + "\n"
|
19
|
+
end
|
20
|
+
if header["後手"] || header["上手"]
|
21
|
+
result += "N-" + (header.delete("後手") || header.delete("上手") || "") + "\n"
|
22
|
+
end
|
23
|
+
header.each { |(k, v)| result += "$#{csa_header_key(k)}:#{v}\n" }
|
24
24
|
result
|
25
25
|
end
|
26
26
|
|
27
27
|
def convert_initial(initial)
|
28
|
-
result =
|
29
|
-
data = initial[
|
30
|
-
if initial[
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
line += if piece == {}
|
36
|
-
" * "
|
37
|
-
else
|
38
|
-
csa_color(piece['color']) + piece['kind']
|
39
|
-
end
|
40
|
-
}
|
41
|
-
result += line + "\n"
|
42
|
-
}
|
43
|
-
else
|
44
|
-
result += 'PI'
|
45
|
-
case initial['preset']
|
46
|
-
when 'HIRATE'
|
47
|
-
when 'KY' # 香落ち
|
48
|
-
result += '11KY'
|
49
|
-
when 'KY_R' # 右香落ち
|
50
|
-
result += '91KY'
|
51
|
-
when 'KA' # 角落ち
|
52
|
-
result += '22KA'
|
53
|
-
when 'HI' # 飛車落ち
|
54
|
-
result += '82HI'
|
55
|
-
when 'HIKY' # 飛香落ち
|
56
|
-
result += '22HI11KY91KY'
|
57
|
-
when '2' # 二枚落ち
|
58
|
-
result += '82HI22KA'
|
59
|
-
when '3' # 三枚落ち
|
60
|
-
result += '82HI22KA91KY'
|
61
|
-
when '4' # 四枚落ち
|
62
|
-
result += '82HI22KA11KY91KY'
|
63
|
-
when '5' # 五枚落ち
|
64
|
-
result += '82HI22KA81KE11KY91KY'
|
65
|
-
when '5_L' # 左五枚落ち
|
66
|
-
result += '82HI22KA21KE11KY91KY'
|
67
|
-
when '6' # 六枚落ち
|
68
|
-
result += '82HI22KA21KE81KE11KY91KY'
|
69
|
-
when '8' # 八枚落ち
|
70
|
-
result += '82HI22KA31GI71GI21KE81KE11KY91KY'
|
71
|
-
when '10' # 十枚落ち
|
72
|
-
result += '82HI22KA41KI61KI31GI71GI21KE81KE11KY91KY'
|
73
|
-
end
|
74
|
-
end
|
28
|
+
result = ""
|
29
|
+
data = initial["data"]
|
30
|
+
result += if initial["preset"] == "OTHER"
|
31
|
+
convert_board(data["board"])
|
32
|
+
else
|
33
|
+
convert_preset(initial["preset"])
|
34
|
+
end
|
75
35
|
# 持駒
|
76
|
-
if data[
|
77
|
-
|
78
|
-
data[
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
36
|
+
if data["hands"]
|
37
|
+
result += convert_hands(data["hands"], 0)
|
38
|
+
result += convert_hands(data["hands"], 1)
|
39
|
+
end
|
40
|
+
result += csa_color(data["color"]) + "\n" if data["color"]
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def convert_hands(hands, color)
|
45
|
+
result = ""
|
46
|
+
sum = 0
|
47
|
+
hands[color].each_value { |n| sum += n }
|
48
|
+
if sum > 0
|
49
|
+
result += "P#{csa_color(color)}"
|
50
|
+
hands[color].to_a.reverse_each { |(k, v)| v.times { result += "00#{k}" } }
|
51
|
+
result += "\n"
|
91
52
|
end
|
92
|
-
result += csa_color(data['color']) + "\n" if data['color']
|
93
53
|
result
|
94
54
|
end
|
95
55
|
|
96
56
|
def convert_moves(moves)
|
97
|
-
result =
|
57
|
+
result = ""
|
98
58
|
moves.each do |move|
|
99
59
|
next if move == {}
|
100
|
-
result += convert_move(move[
|
101
|
-
result += convert_special(move[
|
102
|
-
if move[
|
103
|
-
result += "," + convert_time(move[
|
104
|
-
elsif move[
|
60
|
+
result += convert_move(move["move"]) if move["move"]
|
61
|
+
result += convert_special(move["special"], move["color"]) if move["special"]
|
62
|
+
if move["time"]
|
63
|
+
result += "," + convert_time(move["time"])
|
64
|
+
elsif move["move"] || move["special"]
|
105
65
|
result += "\n"
|
106
66
|
end
|
107
|
-
result += convert_comments(move[
|
67
|
+
result += convert_comments(move["comments"]) if move["comments"]
|
108
68
|
end
|
109
69
|
result
|
110
70
|
end
|
111
71
|
|
112
72
|
def convert_move(move)
|
113
|
-
result = csa_color(move[
|
114
|
-
result +=
|
115
|
-
|
116
|
-
else
|
117
|
-
"00"
|
118
|
-
end
|
119
|
-
result += "#{move['to']['x']}#{move['to']['y']}"
|
120
|
-
result += move['piece']
|
121
|
-
result
|
73
|
+
result = csa_color(move["color"])
|
74
|
+
result += move["from"] ? pos2str(move["from"]) : "00"
|
75
|
+
result + pos2str(move["to"]) + move["piece"]
|
122
76
|
end
|
123
77
|
|
124
|
-
def convert_special(special, color=nil)
|
78
|
+
def convert_special(special, color = nil)
|
125
79
|
result = "%"
|
126
80
|
result += csa_color(color) if color
|
127
|
-
result
|
128
|
-
result
|
81
|
+
result + special
|
129
82
|
end
|
130
83
|
|
131
84
|
def convert_time(time)
|
132
|
-
sec = time[
|
85
|
+
sec = time["now"]["m"] * 60 + time["now"]["s"]
|
133
86
|
"T#{sec}\n"
|
134
87
|
end
|
135
88
|
|
@@ -137,10 +90,62 @@ module Jkf::Converter
|
|
137
90
|
comments.map { |comment| "'#{comment}" }.join("\n") + "\n"
|
138
91
|
end
|
139
92
|
|
140
|
-
|
93
|
+
def convert_board(board)
|
94
|
+
result = ""
|
95
|
+
9.times do |y|
|
96
|
+
result += "P#{y + 1}"
|
97
|
+
9.times do |x|
|
98
|
+
piece = board[8 - x][y]
|
99
|
+
result += if piece == {}
|
100
|
+
" * "
|
101
|
+
else
|
102
|
+
csa_color(piece["color"]) + piece["kind"]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
result += "\n"
|
106
|
+
end
|
107
|
+
result
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert_preset(preset)
|
111
|
+
"PI" +
|
112
|
+
case preset
|
113
|
+
when "HIRATE"
|
114
|
+
when "KY" # 香落ち
|
115
|
+
"11KY"
|
116
|
+
when "KY_R" # 右香落ち
|
117
|
+
"91KY"
|
118
|
+
when "KA" # 角落ち
|
119
|
+
"22KA"
|
120
|
+
when "HI" # 飛車落ち
|
121
|
+
"82HI"
|
122
|
+
when "HIKY" # 飛香落ち
|
123
|
+
"22HI11KY91KY"
|
124
|
+
when "2" # 二枚落ち
|
125
|
+
"82HI22KA"
|
126
|
+
when "3" # 三枚落ち
|
127
|
+
"82HI22KA91KY"
|
128
|
+
when "4" # 四枚落ち
|
129
|
+
"82HI22KA11KY91KY"
|
130
|
+
when "5" # 五枚落ち
|
131
|
+
"82HI22KA81KE11KY91KY"
|
132
|
+
when "5_L" # 左五枚落ち
|
133
|
+
"82HI22KA21KE11KY91KY"
|
134
|
+
when "6" # 六枚落ち
|
135
|
+
"82HI22KA21KE81KE11KY91KY"
|
136
|
+
when "8" # 八枚落ち
|
137
|
+
"82HI22KA31GI71GI21KE81KE11KY91KY"
|
138
|
+
when "10" # 十枚落ち
|
139
|
+
"82HI22KA41KI61KI31GI71GI21KE81KE11KY91KY"
|
140
|
+
end
|
141
|
+
end
|
141
142
|
|
142
143
|
def csa_color(color)
|
143
|
-
color == 0 ?
|
144
|
+
color == 0 ? "+" : "-"
|
145
|
+
end
|
146
|
+
|
147
|
+
def pos2str(pos)
|
148
|
+
"%d%d" % [pos["x"], pos["y"]]
|
144
149
|
end
|
145
150
|
|
146
151
|
def version
|
@@ -149,11 +154,11 @@ module Jkf::Converter
|
|
149
154
|
|
150
155
|
def csa_header_key(key)
|
151
156
|
{
|
152
|
-
"棋戦"
|
153
|
-
"場所"
|
157
|
+
"棋戦" => "EVENT",
|
158
|
+
"場所" => "SITE",
|
154
159
|
"開始日時" => "START_TIME",
|
155
160
|
"終了日時" => "END_TIME",
|
156
|
-
"持ち時間" => "TIME_LIMIT"
|
161
|
+
"持ち時間" => "TIME_LIMIT"
|
157
162
|
}[key] || key
|
158
163
|
end
|
159
164
|
end
|