sashite-gan 1.0.0 → 2.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/LICENSE.md +1 -1
- data/README.md +164 -35
- data/lib/sashite-gan.rb +4 -1
- data/lib/sashite/gan.rb +42 -36
- data/lib/sashite/gan/abbr.rb +68 -0
- data/lib/sashite/gan/error.rb +12 -0
- data/lib/sashite/gan/error/string.rb +10 -0
- data/lib/sashite/gan/error/style.rb +12 -0
- data/lib/sashite/gan/error/type.rb +12 -0
- data/lib/sashite/gan/parser.rb +31 -0
- data/lib/sashite/gan/piece.rb +138 -0
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d75df37e1d20e65cbf461231526922a343dcff9e2c113a6c2dc9a85c4183c51
|
4
|
+
data.tar.gz: 57c80ac8d301e5d06d1d65be1211802587524bda49c95b9b943b035d519f3eac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f63028d5668cd3f8d6f0b74b684f79d9664f7f896b1e606604775a113fd0554bebf2df5e461adbfe46baa4ef3f59df3057407406b19739f2d2ca9e7bb88bfdcb
|
7
|
+
data.tar.gz: ab4807633db42b7d7cdd8d770822d50d9b983fb2210a9b1a2bbd8650304bb991f1399db86a639b79766141cc149f0e6af0cb5dd5fede120efa509b2cd59e7640
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,52 +1,181 @@
|
|
1
|
-
#
|
1
|
+
# GAN.rb
|
2
2
|
|
3
|
-
|
3
|
+
[](https://travis-ci.org/sashite/gan.rb)
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
|
-
gem 'sashite-gan'
|
5
|
+
> A Ruby interface for data serialization in [General Actor Notation](https://developer.sashite.com/specs/general-actor-notation) format ♟️
|
10
6
|
|
11
|
-
|
7
|
+
## Installation
|
12
8
|
|
13
|
-
|
9
|
+
1. Add the dependency to your `Gemfile`:
|
14
10
|
|
15
|
-
|
11
|
+
```ruby
|
12
|
+
gem 'sashite-gan'
|
13
|
+
```
|
16
14
|
|
17
|
-
|
15
|
+
2. Run `bundle install`
|
18
16
|
|
19
17
|
## Usage
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
19
|
+
```ruby
|
20
|
+
require 'sashite-gan'
|
21
|
+
|
22
|
+
|
23
|
+
# Chess (Western chess)'s Rook, White
|
24
|
+
piece = Sashite::GAN.parse("C:R")
|
25
|
+
|
26
|
+
piece.abbr.to_s # => "R"
|
27
|
+
piece.style # => "C"
|
28
|
+
piece.topside? # => false
|
29
|
+
piece.bottomside? # => true
|
30
|
+
piece.to_s # => "C:R"
|
31
|
+
piece.topside.to_s # => "c:r"
|
32
|
+
piece.bottomside.to_s # => "C:R"
|
33
|
+
piece.oppositeside.to_s # => "c:r"
|
34
|
+
piece.promote.to_s # => "C:+R"
|
35
|
+
piece.unpromote.to_s # => "C:R"
|
36
|
+
|
37
|
+
|
38
|
+
# Chess (Western chess)'s King, Black
|
39
|
+
piece = Sashite::GAN.parse("c:-k")
|
40
|
+
|
41
|
+
piece.abbr.to_s # => "-k"
|
42
|
+
piece.style # => "c"
|
43
|
+
piece.topside? # => true
|
44
|
+
piece.bottomside? # => false
|
45
|
+
piece.to_s # => "c:-k"
|
46
|
+
piece.topside.to_s # => "c:-k"
|
47
|
+
piece.bottomside.to_s # => "C:-K"
|
48
|
+
piece.oppositeside.to_s # => "C:-K"
|
49
|
+
piece.promote.to_s # => "c:+-k"
|
50
|
+
piece.unpromote.to_s # => "c:-k"
|
51
|
+
|
52
|
+
|
53
|
+
# Makruk (Thai chess)'s Bishop, White
|
54
|
+
piece = Sashite::GAN.parse("M:B")
|
55
|
+
|
56
|
+
piece.abbr.to_s # => "B"
|
57
|
+
piece.style # => "M"
|
58
|
+
piece.topside? # => false
|
59
|
+
piece.bottomside? # => true
|
60
|
+
piece.to_s # => "M:B"
|
61
|
+
piece.topside.to_s # => "m:b"
|
62
|
+
piece.bottomside.to_s # => "M:B"
|
63
|
+
piece.oppositeside.to_s # => "m:b"
|
64
|
+
piece.promote.to_s # => "M:+B"
|
65
|
+
piece.unpromote.to_s # => "M:B"
|
66
|
+
|
67
|
+
|
68
|
+
# Shogi (Japanese chess)'s King, Gote
|
69
|
+
piece = Sashite::GAN.parse("s:-k")
|
70
|
+
|
71
|
+
piece.abbr.to_s # => "-k"
|
72
|
+
piece.style # => "s"
|
73
|
+
piece.topside? # => true
|
74
|
+
piece.bottomside? # => false
|
75
|
+
piece.to_s # => "s:-k"
|
76
|
+
piece.topside.to_s # => "s:-k"
|
77
|
+
piece.bottomside.to_s # => "S:-K"
|
78
|
+
piece.oppositeside.to_s # => "S:-K"
|
79
|
+
piece.promote.to_s # => "s:+-k"
|
80
|
+
piece.unpromote.to_s # => "s:-k"
|
81
|
+
|
82
|
+
|
83
|
+
# Shogi (Japanese chess)'s King, Sente
|
84
|
+
piece = Sashite::GAN.parse("S:-K")
|
85
|
+
|
86
|
+
piece.abbr.to_s # => "-K"
|
87
|
+
piece.style # => "S"
|
88
|
+
piece.topside? # => false
|
89
|
+
piece.bottomside? # => true
|
90
|
+
piece.to_s # => "S:-K"
|
91
|
+
piece.topside.to_s # => "s:-k"
|
92
|
+
piece.bottomside.to_s # => "S:-K"
|
93
|
+
piece.oppositeside.to_s # => "s:-k"
|
94
|
+
piece.promote.to_s # => "S:+-K"
|
95
|
+
piece.unpromote.to_s # => "S:-K"
|
96
|
+
|
97
|
+
|
98
|
+
# Shogi (Japanese chess)'s promoted Pawn, Sente
|
99
|
+
piece = Sashite::GAN.parse("S:+P")
|
100
|
+
|
101
|
+
piece.abbr.to_s # => "+P"
|
102
|
+
piece.style # => "S"
|
103
|
+
piece.topside? # => false
|
104
|
+
piece.bottomside? # => true
|
105
|
+
piece.to_s # => "S:+P"
|
106
|
+
piece.topside.to_s # => "s:+p"
|
107
|
+
piece.bottomside.to_s # => "S:+P"
|
108
|
+
piece.oppositeside.to_s # => "s:+p"
|
109
|
+
piece.promote.to_s # => "S:+P"
|
110
|
+
piece.unpromote.to_s # => "S:P"
|
111
|
+
|
112
|
+
|
113
|
+
# Xiangqi (Chinese chess)'s General, Red
|
114
|
+
piece = Sashite::GAN.parse("X:-G")
|
115
|
+
|
116
|
+
piece.abbr.to_s # => "-G"
|
117
|
+
piece.style # => "X"
|
118
|
+
piece.topside? # => false
|
119
|
+
piece.bottomside? # => true
|
120
|
+
piece.to_s # => "X:-G"
|
121
|
+
piece.topside.to_s # => "x:-g"
|
122
|
+
piece.bottomside.to_s # => "X:-G"
|
123
|
+
piece.oppositeside.to_s # => "x:-g"
|
124
|
+
piece.promote.to_s # => "X:+-G"
|
125
|
+
piece.unpromote.to_s # => "X:-G"
|
126
|
+
|
127
|
+
|
128
|
+
# Xiangqi (Chinese chess)'s Flying General, Red
|
129
|
+
piece = Sashite::GAN.parse("X:+-G")
|
130
|
+
|
131
|
+
piece.abbr.to_s # => "+-G"
|
132
|
+
piece.style # => "X"
|
133
|
+
piece.topside? # => false
|
134
|
+
piece.bottomside? # => true
|
135
|
+
piece.to_s # => "X:+-G"
|
136
|
+
piece.topside.to_s # => "x:+-g"
|
137
|
+
piece.bottomside.to_s # => "X:+-G"
|
138
|
+
piece.oppositeside.to_s # => "x:+-g"
|
139
|
+
piece.promote.to_s # => "X:+-G"
|
140
|
+
piece.unpromote.to_s # => "X:-G"
|
141
|
+
|
142
|
+
|
143
|
+
# Dai Dai Shogi (huge Japanese chess)'s Phoenix, Sente
|
144
|
+
piece = Sashite::GAN.parse("DAI_DAI_SHOGI:PH")
|
145
|
+
|
146
|
+
piece.abbr.to_s # => "PH"
|
147
|
+
piece.style # => "DAI_DAI_SHOGI"
|
148
|
+
piece.topside? # => false
|
149
|
+
piece.bottomside? # => true
|
150
|
+
piece.to_s # => "DAI_DAI_SHOGI:PH"
|
151
|
+
piece.topside.to_s # => "dai_dai_shogi:ph"
|
152
|
+
piece.bottomside.to_s # => "DAI_DAI_SHOGI:PH"
|
153
|
+
piece.oppositeside.to_s # => "dai_dai_shogi:ph"
|
154
|
+
piece.promote.to_s # => "DAI_DAI_SHOGI:+PH"
|
155
|
+
piece.unpromote.to_s # => "DAI_DAI_SHOGI:PH"
|
156
|
+
|
157
|
+
|
158
|
+
# A random FOO chess variant's promoted Z piece, Bottom-side
|
159
|
+
piece = Sashite::GAN.parse("FOO:+Z")
|
160
|
+
|
161
|
+
piece.abbr.to_s # => "+Z"
|
162
|
+
piece.style # => "FOO"
|
163
|
+
piece.topside? # => false
|
164
|
+
piece.bottomside? # => true
|
165
|
+
piece.to_s # => "FOO:+Z"
|
166
|
+
piece.topside.to_s # => "foo:+z"
|
167
|
+
piece.bottomside.to_s # => "FOO:+Z"
|
168
|
+
piece.oppositeside.to_s # => "foo:+z"
|
169
|
+
piece.promote.to_s # => "FOO:+Z"
|
170
|
+
piece.unpromote.to_s # => "FOO:Z"
|
171
|
+
```
|
43
172
|
|
44
173
|
## License
|
45
174
|
|
46
|
-
The
|
175
|
+
The code is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
47
176
|
|
48
177
|
## About Sashite
|
49
178
|
|
50
|
-
|
179
|
+
This [gem](https://rubygems.org/gems/sashite-gan) is maintained by [Sashite](https://sashite.com/).
|
51
180
|
|
52
181
|
With some [lines of code](https://github.com/sashite/), let's share the beauty of Chinese, Japanese and Western cultures through the game of chess!
|
data/lib/sashite-gan.rb
CHANGED
data/lib/sashite/gan.rb
CHANGED
@@ -1,43 +1,49 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
# General Actor Notation
|
5
|
-
class GAN
|
6
|
-
# @return [String] The representation of an actor.
|
7
|
-
def self.string(is_checkmateable:, is_promoted:, is_topside:, piece_abbr:, style_abbr:)
|
8
|
-
unless [false, true].include?(is_topside)
|
9
|
-
raise TypeError, is_topside.class.inspect
|
10
|
-
end
|
11
|
-
|
12
|
-
piece_code = piece_code_builder(
|
13
|
-
piece_abbr: piece_abbr,
|
14
|
-
is_checkmateable: is_checkmateable,
|
15
|
-
is_promoted: is_promoted
|
16
|
-
)
|
3
|
+
require_relative 'gan/parser'
|
17
4
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.piece_code_builder(piece_abbr:, is_checkmateable:, is_promoted:)
|
28
|
-
unless [false, true].include?(is_checkmateable)
|
29
|
-
raise TypeError, is_checkmateable.class.inspect
|
30
|
-
end
|
31
|
-
|
32
|
-
unless [false, true].include?(is_promoted)
|
33
|
-
raise TypeError, is_promoted.class.inspect
|
34
|
-
end
|
5
|
+
module Sashite
|
6
|
+
# The GAN (General Actor Notation) module.
|
7
|
+
#
|
8
|
+
# @see https://developer.sashite.com/specs/general-actor-notation
|
9
|
+
module GAN
|
10
|
+
SEPARATOR_CHAR = ':'
|
35
11
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
12
|
+
# Parse the GAN string into a Ruby object structure and return it.
|
13
|
+
#
|
14
|
+
# @example Chess (Western chess)'s Rook, White
|
15
|
+
# GAN.parse("C:R")
|
16
|
+
#
|
17
|
+
# @example Chess (Western chess)'s King, Black
|
18
|
+
# GAN.parse("c:-k")
|
19
|
+
#
|
20
|
+
# @example Makruk (Thai chess)'s Bishop, White
|
21
|
+
# GAN.parse("M:B")
|
22
|
+
#
|
23
|
+
# @example Shogi (Japanese chess)'s King, Gote
|
24
|
+
# GAN.parse("s:-k")
|
25
|
+
#
|
26
|
+
# @example Shogi (Japanese chess)'s King, Sente
|
27
|
+
# GAN.parse("S:-K")
|
28
|
+
#
|
29
|
+
# @example Shogi (Japanese chess)'s promoted Pawn, Sente
|
30
|
+
# GAN.parse("S:+P")
|
31
|
+
#
|
32
|
+
# @example Xiangqi (Chinese chess)'s General, Red
|
33
|
+
# GAN.parse("X:-G")
|
34
|
+
#
|
35
|
+
# @example Xiangqi (Chinese chess)'s Flying General, Red
|
36
|
+
# GAN.parse("X:+-G")
|
37
|
+
#
|
38
|
+
# @example Dai Dai Shogi (huge Japanese chess)'s Phoenix, Sente
|
39
|
+
# GAN.parse("DAI_DAI_SHOGI:PH")
|
40
|
+
#
|
41
|
+
# @example Another FOO chess variant's promoted Z piece, Bottom-side
|
42
|
+
# GAN.parse("FOO:+Z")
|
43
|
+
#
|
44
|
+
# @return [Piece] An instance of the piece.
|
45
|
+
def self.parse(string)
|
46
|
+
Parser.call(string)
|
40
47
|
end
|
41
|
-
private_class_method :piece_code_builder
|
42
48
|
end
|
43
49
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sashite
|
4
|
+
module GAN
|
5
|
+
# The piece's abbreviation.
|
6
|
+
class Abbr
|
7
|
+
# The piece's type.
|
8
|
+
#
|
9
|
+
# @!attribute [r] type
|
10
|
+
# @return [String] The type of the piece.
|
11
|
+
attr_reader :type
|
12
|
+
|
13
|
+
def initialize(type, is_promoted:, is_king:)
|
14
|
+
@type = TypeString(type)
|
15
|
+
@is_promoted = Boolean(is_promoted)
|
16
|
+
@is_king = Boolean(is_king)
|
17
|
+
|
18
|
+
freeze
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean] Is the piece a king?
|
22
|
+
def king?
|
23
|
+
@is_king
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Boolean] Is the piece promoted?
|
27
|
+
def promoted?
|
28
|
+
@is_promoted
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] The abbreviation of the piece.
|
32
|
+
def to_s
|
33
|
+
str = type
|
34
|
+
str = "-#{str}" if king?
|
35
|
+
str = "+#{str}" if promoted?
|
36
|
+
str
|
37
|
+
end
|
38
|
+
|
39
|
+
def inspect
|
40
|
+
to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# rubocop:disable Naming/MethodName
|
46
|
+
|
47
|
+
# Ensures `arg` is a boolean, and returns it. Otherwise, raises a
|
48
|
+
# `TypeError`.
|
49
|
+
def Boolean(arg)
|
50
|
+
raise ::TypeError, arg.class.inspect unless [false, true].include?(arg)
|
51
|
+
|
52
|
+
arg
|
53
|
+
end
|
54
|
+
|
55
|
+
# Ensures `arg` is a type, and returns it. Otherwise, raises an error.
|
56
|
+
def TypeString(arg)
|
57
|
+
raise ::TypeError, arg.class.inspect unless arg.is_a?(::String)
|
58
|
+
raise Error::Type, arg.inspect unless arg.match?(/\A[a-z]{1,2}\z/i)
|
59
|
+
|
60
|
+
arg
|
61
|
+
end
|
62
|
+
|
63
|
+
# rubocop:enable Naming/MethodName
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
require_relative 'error'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'error'
|
4
|
+
require_relative 'piece'
|
5
|
+
|
6
|
+
module Sashite
|
7
|
+
module GAN
|
8
|
+
# The notation parser.
|
9
|
+
module Parser
|
10
|
+
def self.call(arg)
|
11
|
+
raise Error::String, "Invalid: #{arg.inspect}" unless valid?(arg)
|
12
|
+
|
13
|
+
style, abbr = arg.split(SEPARATOR_CHAR)
|
14
|
+
|
15
|
+
Piece.new(
|
16
|
+
abbr.delete('-+'),
|
17
|
+
is_king: abbr.include?('-'),
|
18
|
+
is_promoted: abbr.include?('+'),
|
19
|
+
is_topside: style.downcase.eql?(style),
|
20
|
+
style: style
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.valid?(arg)
|
25
|
+
raise ::TypeError, arg.class.inspect unless arg.is_a?(::String)
|
26
|
+
|
27
|
+
arg.match?(/\A([a-z_]+:\+?-?[a-z]{1,2}|[A-Z_]+:\+?-?[A-Z]{1,2})\z/)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sashite
|
4
|
+
module GAN
|
5
|
+
# A piece abstraction.
|
6
|
+
class Piece
|
7
|
+
# The abbreviation of the piece.
|
8
|
+
#
|
9
|
+
# @!attribute [r] abbr
|
10
|
+
# @return [String] The abbreviation of the piece.
|
11
|
+
attr_reader :abbr
|
12
|
+
|
13
|
+
# The piece's style.
|
14
|
+
#
|
15
|
+
# @!attribute [r] style
|
16
|
+
# @return [String] The piece's style.
|
17
|
+
attr_reader :style
|
18
|
+
|
19
|
+
# Initialize a piece.
|
20
|
+
#
|
21
|
+
# @param type [String] The type of the piece.
|
22
|
+
# @param is_king [Boolean] Is it a King (or a Xiangqi General),
|
23
|
+
# so it could be checkmated?
|
24
|
+
# @param is_promoted [Boolean] Is it promoted?
|
25
|
+
# @param is_topside [Boolean] Is it owned by top-side player?
|
26
|
+
# @param style [String] The piece's style.
|
27
|
+
def initialize(type, is_king:, is_promoted:, is_topside:, style:)
|
28
|
+
@abbr = Abbr.new(type, is_king: is_king, is_promoted: is_promoted)
|
29
|
+
@is_topside = Boolean(is_topside)
|
30
|
+
@style = StyleString(style)
|
31
|
+
|
32
|
+
freeze
|
33
|
+
end
|
34
|
+
|
35
|
+
# Is it owned by top-side player?
|
36
|
+
#
|
37
|
+
# @return [Boolean] Returns `true` if the top-side player own the piece,
|
38
|
+
# `false` otherwise.
|
39
|
+
def topside?
|
40
|
+
@is_topside
|
41
|
+
end
|
42
|
+
|
43
|
+
# Is it owned by bottom-side player?
|
44
|
+
#
|
45
|
+
# @return [Boolean] Returns `true` if the bottom-side player own the
|
46
|
+
# piece, `false` otherwise.
|
47
|
+
def bottomside?
|
48
|
+
!topside?
|
49
|
+
end
|
50
|
+
|
51
|
+
# @see https://developer.sashite.com/specs/general-actor-notation
|
52
|
+
# @return [String] The notation of the piece.
|
53
|
+
def to_s
|
54
|
+
topside? ? raw.downcase : raw.upcase
|
55
|
+
end
|
56
|
+
|
57
|
+
def inspect
|
58
|
+
to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
# @return [Piece] The top-side side version of the piece.
|
62
|
+
def topside
|
63
|
+
topside? ? self : oppositeside
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Piece] The bottom-side side version of the piece.
|
67
|
+
def bottomside
|
68
|
+
topside? ? oppositeside : self
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [Piece] The opposite side version of the piece.
|
72
|
+
def oppositeside
|
73
|
+
self.class.new(abbr.type,
|
74
|
+
is_king: abbr.king?,
|
75
|
+
is_promoted: abbr.promoted?,
|
76
|
+
is_topside: !topside?,
|
77
|
+
style: style
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
# @return [Piece] The promoted version of the piece.
|
82
|
+
def promote
|
83
|
+
self.class.new(abbr.type,
|
84
|
+
is_king: abbr.king?,
|
85
|
+
is_promoted: true,
|
86
|
+
is_topside: topside?,
|
87
|
+
style: style
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @return [Piece] The unpromoted version of the piece.
|
92
|
+
def unpromote
|
93
|
+
self.class.new(abbr.type,
|
94
|
+
is_king: abbr.king?,
|
95
|
+
is_promoted: false,
|
96
|
+
is_topside: topside?,
|
97
|
+
style: style
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
# @return [String] The style and the abbreviation of the piece (without
|
104
|
+
# case).
|
105
|
+
def raw
|
106
|
+
params.join(SEPARATOR_CHAR)
|
107
|
+
end
|
108
|
+
|
109
|
+
# @return [Array] The style and the abbreviation of the piece.
|
110
|
+
def params
|
111
|
+
[style, abbr]
|
112
|
+
end
|
113
|
+
|
114
|
+
# rubocop:disable Naming/MethodName
|
115
|
+
|
116
|
+
# Ensures `arg` is a boolean, and returns it. Otherwise, raises a
|
117
|
+
# `TypeError`.
|
118
|
+
def Boolean(arg)
|
119
|
+
raise ::TypeError, arg.class.inspect unless [false, true].include?(arg)
|
120
|
+
|
121
|
+
arg
|
122
|
+
end
|
123
|
+
|
124
|
+
# Ensures `arg` is a style, and returns it. Otherwise, raises an error.
|
125
|
+
def StyleString(arg)
|
126
|
+
raise ::TypeError, arg.class.inspect unless arg.is_a?(::String)
|
127
|
+
raise Error::Style, arg.inspect unless arg.match?(/\A[a-z_]+\z/i)
|
128
|
+
|
129
|
+
arg
|
130
|
+
end
|
131
|
+
|
132
|
+
# rubocop:enable Naming/MethodName
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
require_relative 'abbr'
|
138
|
+
require_relative 'error'
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sashite-gan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: brutal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,8 +108,7 @@ dependencies:
|
|
94
108
|
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
|
-
description:
|
98
|
-
abstract strategy games.
|
111
|
+
description: A Ruby interface for data serialization in GAN format ♟️
|
99
112
|
email: contact@cyril.email
|
100
113
|
executables: []
|
101
114
|
extensions: []
|
@@ -105,6 +118,13 @@ files:
|
|
105
118
|
- README.md
|
106
119
|
- lib/sashite-gan.rb
|
107
120
|
- lib/sashite/gan.rb
|
121
|
+
- lib/sashite/gan/abbr.rb
|
122
|
+
- lib/sashite/gan/error.rb
|
123
|
+
- lib/sashite/gan/error/string.rb
|
124
|
+
- lib/sashite/gan/error/style.rb
|
125
|
+
- lib/sashite/gan/error/type.rb
|
126
|
+
- lib/sashite/gan/parser.rb
|
127
|
+
- lib/sashite/gan/piece.rb
|
108
128
|
homepage: https://developer.sashite.com/specs/general-actor-notation
|
109
129
|
licenses:
|
110
130
|
- MIT
|