feen 4.0.3 → 5.0.0.beta0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 98cae677c862ba15d503bd607228abfd3aa06f7b4524c30f1a8890f446978784
4
- data.tar.gz: ce5628e2b182d15d7e51567b67550338308a87508bf4422cae6e710b04aa6e33
3
+ metadata.gz: 53d90951a531e63bc118104956d29e7c71c90075ab4d42d57506ec5197a783cb
4
+ data.tar.gz: 2cbf73113cc4a429420c3c4e0f30c448380a397bf39f264e617fa85119193f7f
5
5
  SHA512:
6
- metadata.gz: b294ea3521b0e34fbce443942d7c9aec06388f290025977d6995312f0a01492aedd498ea6a9e41b5eb19f9762ae79a6970a512f192fda2ab09ec890cd77c606d
7
- data.tar.gz: 6dd225e8abcf4189f4124225a35d26c1f1faf39e804204f2467bf11350539394f9ea52eeabb3835d1d3ab232c74b1136e341f21669b469a126395473034bdac7
6
+ metadata.gz: 3919811f24c5ad1f82dfd257eeefe3515efbcb6fd433a1feb20597e4c6a0fbe6a24c33bef56ea7f612e87fac3124b6334b261c1e987a02f7ecf43a6da745f950
7
+ data.tar.gz: 7b16a8ecd4d80444d1ee14477be61906f3c9503f0a05083dc191822d8a663a6a4fee379c6b0d40fd9bec509c98f0ae863282e1512a6035b7f0624279cb774da0
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # FEEN.rb
1
+ # Feen.rb
2
2
 
3
3
  [![Version](https://img.shields.io/github/v/tag/sashite/feen.rb?label=Version&logo=github)](https://github.com/sashite/feen.rb/releases)
4
4
  [![Yard documentation](https://img.shields.io/badge/Yard-documentation-blue.svg?logo=github)](https://rubydoc.info/github/sashite/feen.rb/main)
@@ -10,7 +10,13 @@
10
10
 
11
11
  ## Overview
12
12
 
13
- This is an implementation of [FEEN](https://developer.sashite.com/specs/fen-easy-extensible-notation), a generic format that can be used for serializing and deserializing chess positions.
13
+ This is an implementation of [FEEN](https://developer.sashite.com/specs/fen-easy-extensible-notation), a generic format that can be used for serializing and deserializing positions.
14
+
15
+ A __FEEN__ string consists of a single line of ASCII text containing three data fields, separated by a space. These are:
16
+
17
+ 1. Piece placement
18
+ 2. Side to move
19
+ 3. Pieces in hand
14
20
 
15
21
  The main chess variants may be supported, including [Chess](https://en.wikipedia.org/wiki/Chess), [Janggi](https://en.wikipedia.org/wiki/Janggi), [Makruk](https://en.wikipedia.org/wiki/Makruk), [Shogi](https://en.wikipedia.org/wiki/Shogi), [Xiangqi](https://en.wikipedia.org/wiki/Xiangqi).
16
22
 
@@ -23,7 +29,7 @@ More exotic variants may be also supported, like: [Dai dai shogi](https://en.wik
23
29
  Add this line to your application's Gemfile:
24
30
 
25
31
  ```ruby
26
- gem "feen"
32
+ gem "feen", ">= 5.0.0.beta0"
27
33
  ```
28
34
 
29
35
  And then execute:
@@ -35,20 +41,32 @@ bundle install
35
41
  Or install it yourself as:
36
42
 
37
43
  ```sh
38
- gem install feen
44
+ gem install feen --pre
39
45
  ```
40
46
 
41
47
  ## Usage
42
48
 
49
+ ### Serialization
50
+
51
+ A position can be serialized by filling in these fields:
52
+
53
+ - **Piece placement**: Describes the placement of pieces on the board with a hash that references each piece on the board. The keys could be numbers, or strings of characters representing coordinates.
54
+ - **Side to move**: A char that indicates who moves next. In chess, "`w`" would mean that White must move, and "`b`" that Black must move. In Shogi, "`s`" could mean that Sente must move, and "`g`" that Gote must move. In Xiangqi, "`r`" could mean that Red must move, and "`b`" that Black must move.
55
+ - **Pieces in hand**: An array of all captured pieces that remain _in hand_, like in Shogi.
56
+ - **Board shape**: An array of integers. For instance, it would be `[10, 9]` in Xiangqi. And it would be `[8, 8]` in Chess.
57
+
58
+ #### Examples
59
+
60
+ ##### A classic Tsume Shogi problem
61
+
43
62
  ```ruby
44
63
  require "feen"
45
64
 
46
- # Dump a classic Tsume Shogi problem
47
- FEEN.dump(
48
- in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
49
- shape: [9, 9],
50
- side_id: 0,
51
- square: {
65
+ Feen.dump(
66
+ side_to_move: "s",
67
+ pieces_in_hand: %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
68
+ board_shape: [9, 9],
69
+ piece_placement: {
52
70
  3 => "s",
53
71
  4 => "k",
54
72
  5 => "s",
@@ -56,11 +74,25 @@ FEEN.dump(
56
74
  43 => "+B"
57
75
  }
58
76
  )
59
- # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s"
77
+ # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s"
78
+ ```
79
+
80
+ ### Deserialization
81
+
82
+ Serialized positions can be converted back to fields.
83
+
84
+ #### Examples
85
+
86
+ ##### A classic Tsume Shogi problem
87
+
88
+ ```ruby
89
+ require "feen"
60
90
 
61
- # Parse a classic Tsume Shogi problem
62
- FEEN.parse("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s")
63
- # => {:square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}, :shape=>[9, 9], :in_hand=>["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"], :side_id=>0}
91
+ Feen.parse("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s")
92
+ # {:board_shape=>[9, 9],
93
+ # :pieces_in_hand=>["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
94
+ # :piece_placement=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"},
95
+ # :side_to_move=>"s"}
64
96
  ```
65
97
 
66
98
  ## License
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FEEN
3
+ module Feen
4
4
  module Dumper
5
- # The square class.
5
+ # The PiecePlacement class.
6
6
  #
7
7
  # @example Dump an empty board of Xiangqi
8
- # Board.new([10, 9]).to_s # => "9/9/9/9/9/9/9/9/9/9"
8
+ # PiecePlacement.new([10, 9]).to_s # => "9/9/9/9/9/9/9/9/9/9"
9
9
  #
10
10
  # @example Dump the Xiangqi starting position board
11
- # Board.new(
11
+ # PiecePlacement.new(
12
12
  # [10, 9],
13
13
  # {
14
14
  # 0 => "車",
@@ -45,12 +45,12 @@ module FEEN
45
45
  # 89 => "俥"
46
46
  # }
47
47
  # ).to_s # => "車,馬,象,士,將,士,象,馬,車/9/1,砲,5,砲,1/卒,1,卒,1,卒,1,卒,1,卒/9/9/兵,1,兵,1,兵,1,兵,1,兵/1,炮,5,炮,1/9/俥,傌,相,仕,帥,仕,相,傌,俥"
48
- class Square
48
+ class PiecePlacement
49
49
  # @param indexes [Array] The shape of the board.
50
- # @param board [Hash] The index of each piece on the board.
51
- def initialize(indexes, board)
50
+ # @param piece_placement [Hash] The index of each piece on the board.
51
+ def initialize(indexes, piece_placement = {})
52
52
  @indexes = indexes
53
- @squares = Array.new(length) { |i| board.fetch(i, nil) }
53
+ @squares = ::Array.new(length) { |i| piece_placement.fetch(i, nil) }
54
54
  end
55
55
 
56
56
  # @return [String] The string representing the board.
@@ -1,26 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FEEN
3
+ module Feen
4
4
  module Dumper
5
- # The pieces in hand module.
6
- module InHand
5
+ # A module that serializes pieces in hand lists into a string.
6
+ module PiecesInHand
7
7
  # Serialize pieces in hand lists into a string.
8
8
  #
9
9
  # @param piece_names [Array] A list of pieces in hand.
10
10
  #
11
11
  # @example Dump a list of pieces in hand
12
12
  # dump(["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"])
13
- # # => "S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s"
13
+ # # => "S,b,g*4,n*4,p*17,r*2,s"
14
14
  #
15
15
  # @example Dump an empty list of pieces in hand
16
16
  # dump([])
17
- # # => "-"
17
+ # # => nil
18
18
  #
19
- # @return [String] A string representing the pieces in hand.
19
+ # @return [String, nil] A serialized list of pieces in hand.
20
20
  def self.dump(piece_names)
21
- return "-" if piece_names.empty?
21
+ return if piece_names.empty?
22
22
 
23
- piece_names.sort.join(",")
23
+ hash = piece_names.group_by(&:itself).transform_values(&:count)
24
+ hash.map { |k, v| v > 1 ? "#{k}*#{v}" : k }.sort.join(",")
24
25
  end
25
26
  end
26
27
  end
data/lib/feen/dumper.rb CHANGED
@@ -1,25 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative File.join("dumper", "in_hand")
4
- require_relative File.join("dumper", "square")
5
- require_relative File.join("dumper", "turn")
3
+ require_relative File.join("dumper", "piece_placement")
4
+ require_relative File.join("dumper", "pieces_in_hand")
6
5
 
7
- module FEEN
6
+ module Feen
8
7
  # The dumper module.
9
8
  module Dumper
10
9
  # Dump position params into a FEEN string.
11
10
  #
12
- # @param in_hand [Array] The list of pieces in hand.
13
- # @param shape [Array] The shape of the board.
14
- # @param side_id [Integer] The identifier of the player who must play.
15
- # @param square [Hash] The index of each piece on the board.
11
+ # @param side_to_move [String] Identify the active side.
12
+ # @param pieces_in_hand [Array, nil] The list of pieces in hand.
13
+ # @param board_shape [Array] The shape of the board.
14
+ # @param piece_placement [Hash] The index of each piece on the board.
16
15
  #
17
16
  # @example Dump a classic Tsume Shogi problem
18
17
  # call(
19
- # "in_hand": %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
20
- # "shape": [9, 9],
21
- # "side_id": 0,
22
- # "square": {
18
+ # "side_to_move": "s",
19
+ # "pieces_in_hand": %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
20
+ # "board_shape": [9, 9],
21
+ # "piece_placement": {
23
22
  # 3 => "s",
24
23
  # 4 => "k",
25
24
  # 5 => "s",
@@ -27,15 +26,17 @@ module FEEN
27
26
  # 43 => "+B"
28
27
  # }
29
28
  # )
30
- # # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s"
29
+ # # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s"
31
30
  #
32
31
  # @return [String] The FEEN string representing the position.
33
- def self.call(in_hand:, shape:, side_id:, square:)
34
- [
35
- Square.new(shape, square).to_s,
36
- Turn.dump(side_id),
37
- InHand.dump(in_hand)
38
- ].join(" ")
32
+ def self.call(board_shape:, side_to_move:, piece_placement:, pieces_in_hand: nil)
33
+ array = [
34
+ PiecePlacement.new(board_shape, piece_placement).to_s,
35
+ side_to_move
36
+ ]
37
+
38
+ array << PiecesInHand.dump(pieces_in_hand) if Array(pieces_in_hand).any?
39
+ array.join(" ")
39
40
  end
40
41
  end
41
42
  end
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FEEN
3
+ module Feen
4
4
  module Parser
5
- # The shape class.
5
+ # The BoardShape class.
6
6
  #
7
7
  # @example Parse the shape of a shogiban
8
- # Shape.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_a # => [9, 9]
9
- class Shape
10
- # @param board [String] The flatten board.
11
- def initialize(board)
12
- @board = board
8
+ # BoardShape.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_a # => [9, 9]
9
+ class BoardShape
10
+ # @param board_str [String] The flatten board.
11
+ def initialize(board_str)
12
+ @board_str = board_str
13
13
  end
14
14
 
15
15
  # @return [Array] The size of each dimension of the board.
16
16
  def to_a
17
- indexes(@board, @board.scan(%r{/+}).sort.fetch(-1))
17
+ indexes(@board_str, @board_str.scan(%r{/+}).sort.fetch(-1))
18
18
  end
19
19
 
20
20
  private
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FEEN
3
+ module Feen
4
4
  module Parser
5
- # The square class.
5
+ # The PiecePlacement class.
6
6
  #
7
7
  # @example Parse a Shogi problem board and return an array
8
- # Board.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_a
8
+ # PiecePlacement.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_a
9
9
  # # => [
10
10
  # # nil, nil, nil, "s", "k", "s", nil, nil, nil,
11
11
  # # nil, nil, nil, nil, nil, nil, nil, nil, nil,
@@ -19,7 +19,7 @@ module FEEN
19
19
  # # ]
20
20
  #
21
21
  # @example Parse a Shogi problem board and return a hash
22
- # Board.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_h
22
+ # PiecePlacement.new("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9").to_h
23
23
  # # => {
24
24
  # # 3 => "s",
25
25
  # # 4 => "k",
@@ -27,15 +27,15 @@ module FEEN
27
27
  # # 22 => "+P",
28
28
  # # 43 => "+B"
29
29
  # # }
30
- class Square
31
- # @param board [String] The flatten board.
32
- def initialize(board)
33
- @board = board
30
+ class PiecePlacement
31
+ # @param piece_placement_str [String] The placement of pieces on the board.
32
+ def initialize(piece_placement_str)
33
+ @piece_placement_str = piece_placement_str
34
34
  end
35
35
 
36
- # @return [Array] The list of squares on the board.
36
+ # @return [Array] The list of pieces on the board.
37
37
  def to_a
38
- @board
38
+ @piece_placement_str
39
39
  .split(%r{[/,]+})
40
40
  .flat_map { |str| row(str) }
41
41
  end
@@ -1,15 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module FEEN
3
+ module Feen
4
4
  module Parser
5
5
  # The pieces in hand module.
6
- module InHand
6
+ module PiecesInHand
7
7
  # The list of pieces in hand grouped by players.
8
8
  #
9
- # @param piece_names_str [String] The serialized list of pieces in hand.
9
+ # @param pieces_in_hand [String, nil] The serialized list of pieces in hand.
10
10
  #
11
11
  # @example Parse a list of serialized pieces in hand
12
- # parse("S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s")
12
+ # parse("S,b,g*4,n*4,p*17,r*2,s")
13
13
  # # => ["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"]
14
14
  #
15
15
  # @example Parse an empty list of serialized pieces in hand
@@ -17,10 +17,17 @@ module FEEN
17
17
  # # => []
18
18
  #
19
19
  # @return [Array] The list of pieces in hand grouped by players.
20
- def self.parse(piece_names_str)
21
- return [] if piece_names_str == "-"
20
+ def self.parse(pieces_in_hand)
21
+ return if pieces_in_hand.nil?
22
22
 
23
- piece_names_str.split(",")
23
+ pieces_in_hand.split(",").flat_map do |piece|
24
+ if piece.include?("*")
25
+ letter, count = piece.split("*")
26
+ [letter] * count.to_i
27
+ else
28
+ piece
29
+ end
30
+ end.sort
24
31
  end
25
32
  end
26
33
  end
data/lib/feen/parser.rb CHANGED
@@ -1,11 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative File.join("parser", "in_hand")
4
- require_relative File.join("parser", "shape")
5
- require_relative File.join("parser", "square")
6
- require_relative File.join("parser", "turn")
3
+ require_relative File.join("parser", "board_shape")
4
+ require_relative File.join("parser", "pieces_in_hand")
5
+ require_relative File.join("parser", "piece_placement")
7
6
 
8
- module FEEN
7
+ module Feen
9
8
  # The parser module.
10
9
  module Parser
11
10
  # Parse a FEEN string into position params.
@@ -13,12 +12,12 @@ module FEEN
13
12
  # @param feen [String] The FEEN string representing a position.
14
13
  #
15
14
  # @example Parse a classic Tsume Shogi problem
16
- # call("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s")
15
+ # call("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s")
17
16
  # # => {
18
- # # "in_hand": ["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
19
- # # "shape": [9, 9],
20
- # # "side_id": 0,
21
- # # "square": {
17
+ # # "side_to_move": "s",
18
+ # # "pieces_in_hand": ["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
19
+ # # "board_shape": [9, 9],
20
+ # # "piece_placement": {
22
21
  # # 3 => "s",
23
22
  # # 4 => "k",
24
23
  # # 5 => "s",
@@ -28,13 +27,13 @@ module FEEN
28
27
  #
29
28
  # @return [Hash] The position params representing the position.
30
29
  def self.call(feen)
31
- square_str, side_id_str, in_hand_str = feen.split
30
+ piece_placement, side_to_move, pieces_in_hand = feen.split
32
31
 
33
32
  {
34
- in_hand: InHand.parse(in_hand_str),
35
- shape: Shape.new(square_str).to_a,
36
- side_id: Turn.parse(side_id_str),
37
- square: Square.new(square_str).to_h
33
+ board_shape: BoardShape.new(piece_placement).to_a,
34
+ pieces_in_hand: PiecesInHand.parse(pieces_in_hand),
35
+ piece_placement: PiecePlacement.new(piece_placement).to_h,
36
+ side_to_move:
38
37
  }
39
38
  end
40
39
  end
data/lib/feen.rb CHANGED
@@ -7,20 +7,20 @@ require_relative File.join("feen", "parser")
7
7
  # deserialization in FEEN format.
8
8
  #
9
9
  # @see https://developer.sashite.com/specs/fen-easy-extensible-notation
10
- module FEEN
10
+ module Feen
11
11
  # Dumps position params into a FEEN string.
12
12
  #
13
- # @param in_hand [Array] The list of pieces in hand.
14
- # @param shape [Array] The shape of the board.
15
- # @param side_id [Integer] The identifier of the player who must play.
16
- # @param square [Hash] The index of each piece on the board.
13
+ # @param pieces_in_hand [Array, nil] The list of pieces in hand.
14
+ # @param board_shape [Array] The shape of the board.
15
+ # @param side_to_move [String] The identifier of the player who must play.
16
+ # @param piece_placement [Hash] The index of each piece on the board.
17
17
  #
18
18
  # @example Dump a classic Tsume Shogi problem
19
19
  # dump(
20
- # "in_hand": %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
21
- # "shape": [9, 9],
22
- # "side_id": 0,
23
- # "square": {
20
+ # "side_to_move": "s",
21
+ # "pieces_in_hand": %w[S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p],
22
+ # "board_shape": [9, 9],
23
+ # "piece_placement": {
24
24
  # 3 => "s",
25
25
  # 4 => "k",
26
26
  # 5 => "s",
@@ -28,15 +28,15 @@ module FEEN
28
28
  # 43 => "+B"
29
29
  # }
30
30
  # )
31
- # # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s"
31
+ # # => "3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s"
32
32
  #
33
33
  # @return [String] The FEEN string representing the position.
34
- def self.dump(in_hand:, shape:, side_id:, square:)
34
+ def self.dump(board_shape:, side_to_move:, piece_placement:, pieces_in_hand: nil)
35
35
  Dumper.call(
36
- in_hand:,
37
- shape:,
38
- side_id:,
39
- square:
36
+ pieces_in_hand:,
37
+ board_shape:,
38
+ side_to_move:,
39
+ piece_placement:
40
40
  )
41
41
  end
42
42
 
@@ -45,12 +45,12 @@ module FEEN
45
45
  # @param feen [String] The FEEN string representing a position.
46
46
  #
47
47
  # @example Parse a classic Tsume Shogi problem
48
- # parse("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 0 S,b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s")
48
+ # parse("3,s,k,s,3/9/4,+P,4/9/7,+B,1/9/9/9/9 s S,b,g*4,n*4,p*17,r*2,s")
49
49
  # # => {
50
- # # "in_hand": ["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
51
- # # "shape": [9, 9],
52
- # # "side_id": 0,
53
- # # "square": {
50
+ # # "pieces_in_hand": ["S", "b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
51
+ # # "board_shape": [9, 9],
52
+ # # "side_to_move": "s",
53
+ # # "piece_placement": {
54
54
  # # 3 => "s",
55
55
  # # 4 => "k",
56
56
  # # 5 => "s",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feen
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.3
4
+ version: 5.0.0.beta0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-24 00:00:00.000000000 Z
11
+ date: 2023-04-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A Ruby interface for data serialization and deserialization in FEEN format.
14
14
  email: contact@cyril.email
@@ -20,14 +20,12 @@ files:
20
20
  - README.md
21
21
  - lib/feen.rb
22
22
  - lib/feen/dumper.rb
23
- - lib/feen/dumper/in_hand.rb
24
- - lib/feen/dumper/square.rb
25
- - lib/feen/dumper/turn.rb
23
+ - lib/feen/dumper/piece_placement.rb
24
+ - lib/feen/dumper/pieces_in_hand.rb
26
25
  - lib/feen/parser.rb
27
- - lib/feen/parser/in_hand.rb
28
- - lib/feen/parser/shape.rb
29
- - lib/feen/parser/square.rb
30
- - lib/feen/parser/turn.rb
26
+ - lib/feen/parser/board_shape.rb
27
+ - lib/feen/parser/piece_placement.rb
28
+ - lib/feen/parser/pieces_in_hand.rb
31
29
  homepage: https://github.com/sashite/feen.rb
32
30
  licenses:
33
31
  - MIT
@@ -44,9 +42,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
42
  version: 3.2.0
45
43
  required_rubygems_version: !ruby/object:Gem::Requirement
46
44
  requirements:
47
- - - ">="
45
+ - - ">"
48
46
  - !ruby/object:Gem::Version
49
- version: '0'
47
+ version: 1.3.1
50
48
  requirements: []
51
49
  rubygems_version: 3.4.6
52
50
  signing_key:
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FEEN
4
- module Dumper
5
- # The turn module.
6
- module Turn
7
- # @param side_id [Integer] The identifier of the active player.
8
- #
9
- # @example Dump the number that identify the player who have to play
10
- # dump(0) # => "0"
11
- #
12
- # @return [String] The number that identify the player who have to play.
13
- def self.dump(side_id)
14
- String(side_id)
15
- end
16
- end
17
- end
18
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module FEEN
4
- module Parser
5
- # The turn module.
6
- module Turn
7
- # @param side_id [String] The identifier of bottom-side and
8
- # top-side.
9
- #
10
- # @example Parse the number that identify the player who have to play
11
- # parse("0") # => 0
12
- #
13
- # @return [Integer] The number that identify the player who have to play.
14
- def self.parse(side_id)
15
- Integer(side_id)
16
- end
17
- end
18
- end
19
- end