feen 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.
@@ -1,56 +1,45 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'dumper/board'
4
- require_relative 'dumper/pieces_in_hand'
5
- require_relative 'dumper/turn'
3
+ require_relative "dumper/board"
4
+ require_relative "dumper/pieces_in_hand"
5
+ require_relative "dumper/turn"
6
6
 
7
7
  module FEEN
8
8
  # The dumper module.
9
9
  module Dumper
10
10
  # Dump position params into a FEEN string.
11
11
  #
12
- # @param active_side [Integer] The identifier of the player who must play.
12
+ # @param active_side_id [Integer] The identifier of the player who must play.
13
+ # @param board [Hash] The indexes of each piece on the board.
13
14
  # @param indexes [Array] The shape of the board.
14
- # @param pieces_in_hand_by_players [Array] The list of pieces in hand
15
+ # @param pieces_in_hand_grouped_by_sides [Array] The list of pieces in hand
15
16
  # grouped by players.
16
- # @param squares [Array] The list of squares on the board.
17
17
  #
18
- # @example Dump Four-player chess's starting position
18
+ # @example Dump a classic Tsume Shogi problem
19
19
  # call(
20
- # active_side: 0,
21
- # indexes: [14, 14],
22
- # pieces_in_hand_by_players: [
23
- # [],
24
- # [],
25
- # [],
26
- # []
27
- # ],
28
- # squares: [
29
- # nil , nil , nil , "yR", "yN", "yB", "yK", "yQ", "yB", "yN", "yR", nil , nil , nil ,
30
- # nil , nil , nil , "yP", "yP", "yP", "yP", "yP", "yP", "yP", "yP", nil , nil , nil ,
31
- # nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
32
- # "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
33
- # "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
34
- # "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
35
- # "bK", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gQ",
36
- # "bQ", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gK",
37
- # "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
38
- # "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
39
- # "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
40
- # nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
41
- # nil , nil , nil , "rP", "rP", "rP", "rP", "rP", "rP", "rP", "rP", nil , nil , nil ,
42
- # nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", "rN", "rR", nil , nil , nil
20
+ # "active_side_id": 0,
21
+ # "board": {
22
+ # "3": "s",
23
+ # "4": "k" ,
24
+ # "5": "s",
25
+ # "22": "+P",
26
+ # "43": "+B"
27
+ # },
28
+ # "indexes": [9, 9],
29
+ # "pieces_in_hand_grouped_by_sides": [
30
+ # %w[S],
31
+ # %w[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]
43
32
  # ]
44
33
  # )
45
- # # => "3,yR,yN,yB,yK,yQ,yB,yN,yR,3/3,yP,yP,yP,yP,yP,yP,yP,yP,3/14/bR,bP,10,gP,gR/bN,bP,10,gP,gN/bB,bP,10,gP,gB/bK,bP,10,gP,gQ/bQ,bP,10,gP,gK/bB,bP,10,gP,gB/bN,bP,10,gP,gN/bR,bP,10,gP,gR/14/3,rP,rP,rP,rP,rP,rP,rP,rP,3/3,rR,rN,rB,rQ,rK,rB,rN,rR,3 0 ///"
34
+ # # => "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"
46
35
  #
47
36
  # @return [String] The FEEN string representing the position.
48
- def self.call(active_side:, indexes:, pieces_in_hand_by_players:, squares:)
37
+ def self.call(active_side_id:, board:, indexes:, pieces_in_hand_grouped_by_sides:)
49
38
  [
50
- Board.new(*indexes).to_s(*squares),
51
- Turn.dump(active_side, pieces_in_hand_by_players.length),
52
- PiecesInHand.dump(*pieces_in_hand_by_players)
53
- ].join(' ')
39
+ Board.new(*indexes, **board).to_s,
40
+ Turn.dump(active_side_id, pieces_in_hand_grouped_by_sides.length),
41
+ PiecesInHand.dump(*pieces_in_hand_grouped_by_sides)
42
+ ].join(" ")
54
43
  end
55
44
  end
56
45
  end
@@ -1,27 +1,65 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'inconsistent_size_error'
4
-
5
3
  module FEEN
6
4
  module Dumper
7
5
  # The board class.
6
+ #
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"
9
+ #
10
+ # @example Dump the Xiangqi starting position board
11
+ # Board.new(10, 9,
12
+ # "0": "車",
13
+ # "1": "馬",
14
+ # "2": "象",
15
+ # "3": "士",
16
+ # "4": "將",
17
+ # "5": "士",
18
+ # "6": "象",
19
+ # "7": "馬",
20
+ # "8": "車",
21
+ # "19": "砲",
22
+ # "25": "砲",
23
+ # "27": "卒",
24
+ # "29": "卒",
25
+ # "31": "卒",
26
+ # "33": "卒",
27
+ # "35": "卒",
28
+ # "54": "兵",
29
+ # "56": "兵",
30
+ # "58": "兵",
31
+ # "60": "兵",
32
+ # "62": "兵",
33
+ # "64": "炮",
34
+ # "70": "炮",
35
+ # "81": "俥",
36
+ # "82": "傌",
37
+ # "83": "相",
38
+ # "84": "仕",
39
+ # "85": "帥",
40
+ # "86": "仕",
41
+ # "87": "相",
42
+ # "88": "傌",
43
+ # "89": "俥").to_s # => "車,馬,象,士,將,士,象,馬,車/9/1,砲,5,砲,1/卒,1,卒,1,卒,1,卒,1,卒/9/9/兵,1,兵,1,兵,1,兵,1,兵/1,炮,5,炮,1/9/俥,傌,相,仕,帥,仕,相,傌,俥"
8
44
  class Board
9
45
  # @param indexes [Array] The shape of the board.
10
- def initialize(*indexes)
46
+ # @param board [Hash] The indexes of each piece on the board.
47
+ def initialize(*indexes, **board)
11
48
  @indexes = indexes
49
+ @squares = Array.new(length) { |i| board.fetch(i.to_s.to_sym, nil) }
12
50
  end
13
51
 
14
- # @param squares [Array] The list of squares on the board.
15
- #
16
52
  # @return [String] The string representing the board.
17
- def to_s(*squares)
18
- raise InconsistentSizeError unless squares.length == @indexes.inject(:*)
19
-
20
- unflatten(squares, *@indexes)
53
+ def to_s
54
+ unflatten(@squares, *@indexes)
21
55
  end
22
56
 
23
57
  private
24
58
 
59
+ def length
60
+ @indexes.inject(:*)
61
+ end
62
+
25
63
  def unflatten(squares, *remaining_indexes)
26
64
  return row(*squares) if remaining_indexes.length == 1
27
65
 
@@ -29,14 +67,14 @@ module FEEN
29
67
  .each_slice(squares.length / remaining_indexes.fetch(0))
30
68
  .to_a
31
69
  .map { |sub_squares| unflatten(sub_squares, *remaining_indexes[1..]) }
32
- .join('/' * remaining_indexes.length.pred)
70
+ .join("/" * remaining_indexes.length.pred)
33
71
  end
34
72
 
35
73
  def row(*squares)
36
74
  squares
37
75
  .map { |square| square.nil? ? 1 : square }
38
- .join(',')
39
- .gsub(/1,[1,]*1/) { |str| str.split(',').length }
76
+ .join(",")
77
+ .gsub(/1,[1,]*1/) { |str| str.split(",").length }
40
78
  end
41
79
  end
42
80
  end
@@ -3,16 +3,23 @@
3
3
  module FEEN
4
4
  module Dumper
5
5
  # The pieces in hand class.
6
+ #
7
+ # @example Serialize a list of pieces in hand grouped by sides
8
+ # PiecesInHand.dump(
9
+ # %w[S],
10
+ # %w[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]
11
+ # )
12
+ # # => "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"
6
13
  class PiecesInHand
7
14
  # Serialize pieces in hand lists into a string.
8
15
  #
9
- # @param pieces_in_hand_by_players [Array] The list of pieces in hand
16
+ # @param pieces_in_hand_grouped_by_sides [Array] The list of pieces in hand
10
17
  # grouped by players.
11
18
  #
12
19
  # @return [String] A string representing the pieces in hand of both
13
20
  # players.
14
- def self.dump(*pieces_in_hand_by_players)
15
- pieces_in_hand_by_players.map { |pieces| new(*pieces).to_s }.join('/')
21
+ def self.dump(*pieces_in_hand_grouped_by_sides)
22
+ pieces_in_hand_grouped_by_sides.map { |pieces| new(*pieces).to_s }.join("/")
16
23
  end
17
24
 
18
25
  # @param pieces [Array] A list of pieces in hand.
@@ -22,7 +29,7 @@ module FEEN
22
29
 
23
30
  # @return [String] A string representing the pieces in hand.
24
31
  def to_s
25
- @pieces.join(',')
32
+ @pieces.join(",")
26
33
  end
27
34
  end
28
35
  end
@@ -2,14 +2,17 @@
2
2
 
3
3
  module FEEN
4
4
  module Dumper
5
- # The turn class.
5
+ # The turn module.
6
6
  module Turn
7
- # @param active_side [Integer] The identifier of the active player.
7
+ # @param active_side_id [Integer] The identifier of the active player.
8
8
  # @param sides_count [Integer] The number of players.
9
9
  #
10
+ # @example Dump the number that identify the player who have to play
11
+ # dump(0, 2) # => "0"
12
+ #
10
13
  # @return [String] The number that identify the player who have to play.
11
- def self.dump(active_side, sides_count)
12
- String(Integer(active_side) % Integer(sides_count))
14
+ def self.dump(active_side_id, sides_count)
15
+ String(Integer(active_side_id) % Integer(sides_count))
13
16
  end
14
17
  end
15
18
  end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'parser/board'
4
- require_relative 'parser/pieces_in_hand'
5
- require_relative 'parser/shape'
6
- require_relative 'parser/turn'
3
+ require_relative "parser/board"
4
+ require_relative "parser/pieces_in_hand"
5
+ require_relative "parser/shape"
6
+ require_relative "parser/turn"
7
7
 
8
8
  module FEEN
9
9
  # The parser module.
@@ -12,53 +12,42 @@ module FEEN
12
12
  #
13
13
  # @param feen [String] The FEEN string representing a position.
14
14
  #
15
- # @example Parse Four-player chess's starting position
16
- # call("3,yR,yN,yB,yK,yQ,yB,yN,yR,3/3,yP,yP,yP,yP,yP,yP,yP,yP,3/14/bR,bP,10,gP,gR/bN,bP,10,gP,gN/bB,bP,10,gP,gB/bK,bP,10,gP,gQ/bQ,bP,10,gP,gK/bB,bP,10,gP,gB/bN,bP,10,gP,gN/bR,bP,10,gP,gR/14/3,rP,rP,rP,rP,rP,rP,rP,rP,3/3,rR,rN,rB,rQ,rK,rB,rN,rR,3 0 ///")
15
+ # @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")
17
17
  # # => {
18
- # # active_side: 0,
19
- # # indexes: [14, 14],
20
- # # pieces_in_hand_by_players: [
21
- # # [],
22
- # # [],
23
- # # [],
24
- # # []
25
- # # ],
26
- # # squares: [
27
- # # nil , nil , nil , "yR", "yN", "yB", "yK", "yQ", "yB", "yN", "yR", nil , nil , nil ,
28
- # # nil , nil , nil , "yP", "yP", "yP", "yP", "yP", "yP", "yP", "yP", nil , nil , nil ,
29
- # # nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
30
- # # "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
31
- # # "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
32
- # # "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
33
- # # "bK", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gQ",
34
- # # "bQ", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gK",
35
- # # "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
36
- # # "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
37
- # # "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
38
- # # nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
39
- # # nil , nil , nil , "rP", "rP", "rP", "rP", "rP", "rP", "rP", "rP", nil , nil , nil ,
40
- # # nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", "rN", "rR", nil , nil , nil
18
+ # # "active_side_id": 0,
19
+ # # "board": {
20
+ # # "3": "s",
21
+ # # "4": "k" ,
22
+ # # "5": "s",
23
+ # # "22": "+P",
24
+ # # "43": "+B"
25
+ # # },
26
+ # # "indexes": [9, 9],
27
+ # # "pieces_in_hand_grouped_by_sides": [
28
+ # # %w[S],
29
+ # # %w[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]
41
30
  # # ]
42
31
  # # }
43
32
  #
44
33
  # @return [Hash] The position params representing the position.
45
34
  def self.call(feen)
46
- params(*feen.split(' '))
35
+ params(*feen.split(" "))
47
36
  end
48
37
 
49
38
  # Parse the FEEN string's three fields and return the position params.
50
39
  #
51
40
  # @param board [String] The flatten board.
52
- # @param active_side [String] The active side identifier.
41
+ # @param active_side_id [String] The active side identifier.
53
42
  # @param in_hand [String] The captured actors.
54
43
  #
55
44
  # @return [Hash] The position params representing the position.
56
- private_class_method def self.params(board, active_side, in_hand)
45
+ private_class_method def self.params(board, active_side_id, in_hand)
57
46
  {
58
- active_side: Turn.parse(active_side),
47
+ active_side_id: Turn.parse(active_side_id),
48
+ board: Board.new(board).to_h,
59
49
  indexes: Shape.new(board).to_a,
60
- pieces_in_hand_by_players: PiecesInHand.parse(in_hand),
61
- squares: Board.new(board).to_a
50
+ pieces_in_hand_grouped_by_sides: PiecesInHand.parse(in_hand)
62
51
  }
63
52
  end
64
53
  end
@@ -4,7 +4,7 @@ module FEEN
4
4
  module Parser
5
5
  # The board class.
6
6
  #
7
- # @example Parse a Shogi problem board
7
+ # @example Parse a Shogi problem board and return an array
8
8
  # Board.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,
@@ -17,6 +17,16 @@ module FEEN
17
17
  # # nil, nil, nil, nil, nil, nil, nil, nil, nil,
18
18
  # # nil, nil, nil, nil, nil, nil, nil, nil, nil
19
19
  # # ]
20
+ #
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
23
+ # # => {
24
+ # # "3": "s",
25
+ # # "4": "k" ,
26
+ # # "5": "s",
27
+ # # "22": "+P",
28
+ # # "43": "+B"
29
+ # # }
20
30
  class Board
21
31
  # @param board [String] The flatten board.
22
32
  def initialize(board)
@@ -30,6 +40,17 @@ module FEEN
30
40
  .flat_map { |str| row(str) }
31
41
  end
32
42
 
43
+ # @return [Hash] The indexes of each piece on the board.
44
+ def to_h
45
+ to_a
46
+ .each_with_index
47
+ .inject({}) do |h, (v, i)|
48
+ next h if v.nil?
49
+
50
+ h.merge(i.to_s.to_sym => v)
51
+ end
52
+ end
53
+
33
54
  private
34
55
 
35
56
  def row(string)
@@ -2,11 +2,11 @@
2
2
 
3
3
  module FEEN
4
4
  module Parser
5
- # The pieces in hand class.
5
+ # The pieces in hand module.
6
6
  module PiecesInHand
7
7
  # The list of pieces in hand grouped by players.
8
8
  #
9
- # @param pieces_in_hand_by_players_str [String] The serialized list of
9
+ # @param pieces_in_hand_grouped_by_sides_str [String] The serialized list of
10
10
  # pieces in hand grouped by players.
11
11
  #
12
12
  # @example Parse a list of serialized pieces in hand
@@ -17,10 +17,10 @@ module FEEN
17
17
  # # ]
18
18
  #
19
19
  # @return [Array] The list of pieces in hand grouped by players.
20
- def self.parse(pieces_in_hand_by_players_str)
21
- pieces_in_hand_by_players_str
22
- .split('/', -1)
23
- .map { |pieces_in_hand_str| pieces_in_hand_str.split(',') }
20
+ def self.parse(pieces_in_hand_grouped_by_sides_str)
21
+ pieces_in_hand_grouped_by_sides_str
22
+ .split("/", -1)
23
+ .map { |pieces_in_hand_str| pieces_in_hand_str.split(",") }
24
24
  end
25
25
  end
26
26
  end
@@ -21,7 +21,7 @@ module FEEN
21
21
 
22
22
  def indexes(string, separator)
23
23
  if separator.empty?
24
- last_index = string.split(',').inject(0) do |counter, sub_string|
24
+ last_index = string.split(",").inject(0) do |counter, sub_string|
25
25
  number = sub_string.match?(/[0-9]+/) ? Integer(sub_string) : 1
26
26
  counter + number
27
27
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module FEEN
4
4
  module Parser
5
- # The turn class.
5
+ # The turn module.
6
6
  module Turn
7
7
  # @param active_side_id [String] The identifier of bottom-side and
8
8
  # top-side.
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: feen
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
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-08-16 00:00:00.000000000 Z
11
+ date: 2020-08-24 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
@@ -119,7 +133,6 @@ files:
119
133
  - lib/feen.rb
120
134
  - lib/feen/dumper.rb
121
135
  - lib/feen/dumper/board.rb
122
- - lib/feen/dumper/inconsistent_size_error.rb
123
136
  - lib/feen/dumper/pieces_in_hand.rb
124
137
  - lib/feen/dumper/turn.rb
125
138
  - lib/feen/parser.rb