feen 4.0.3 → 5.0.0.beta1
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/README.md +36 -21
- data/lib/feen/dumper/{square.rb → piece_placement.rb} +10 -9
- data/lib/feen/dumper.rb +12 -17
- data/lib/feen/parser/board_shape.rb +39 -0
- data/lib/feen/parser.rb +26 -16
- data/lib/feen.rb +19 -23
- metadata +6 -11
- data/lib/feen/dumper/in_hand.rb +0 -27
- data/lib/feen/dumper/turn.rb +0 -18
- data/lib/feen/parser/in_hand.rb +0 -27
- data/lib/feen/parser/shape.rb +0 -37
- data/lib/feen/parser/square.rb +0 -61
- data/lib/feen/parser/turn.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fa56bccbb1911f15569f2f5643646986cbf83661efba3165c69978e7c85fd56
|
4
|
+
data.tar.gz: 13d706d1bfe1c09f6d015d0a8f28af621754677711074ec60ec96e395f1a1061
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5479cbd02c902aa8c45cc12ecfab31c7b7283eb1f8ec60b110c889505a7ebbcf76fa7b0d2e6ad44c60da954312fa85ae03cd4981d929207b0612754f1d62a033
|
7
|
+
data.tar.gz: b6268ce619808bf2c2f889261b55007edbfc030bc37b8edea7f73f505de55e8c0fc1cd4a268e8e2bdc71fe21c9fa33f904c8b26a23b92b471e406e109494bd97
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Feen.rb
|
2
2
|
|
3
3
|
[](https://github.com/sashite/feen.rb/releases)
|
4
4
|
[](https://rubydoc.info/github/sashite/feen.rb/main)
|
@@ -6,24 +6,18 @@
|
|
6
6
|
[](https://github.com/sashite/feen.rb/actions?query=workflow%3Arubocop+branch%3Amain)
|
7
7
|
[](https://github.com/sashite/feen.rb/raw/main/LICENSE.md)
|
8
8
|
|
9
|
-
> __FEEN__ (
|
9
|
+
> __FEEN__ (Forsyth–Edwards Expanded Notation) support for the Ruby language.
|
10
10
|
|
11
11
|
## Overview
|
12
12
|
|
13
|
-
This is an implementation of [FEEN](https://
|
14
|
-
|
15
|
-
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
|
-
|
17
|
-
More exotic variants may be also supported, like: [Dai dai shogi](https://en.wikipedia.org/wiki/Dai_dai_shogi), [Four-player chess](https://en.wikipedia.org/wiki/Four-player_chess), or [Three-dimensional chess](https://en.wikipedia.org/wiki/Three-dimensional_chess) 🖖
|
18
|
-
|
19
|
-

|
13
|
+
This is an implementation of [FEEN](https://github.com/sashite/specs/blob/main/forsyth-edwards-expanded-notation.md), a flexible and minimalist format for describing chess variant positions.
|
20
14
|
|
21
15
|
## Installation
|
22
16
|
|
23
17
|
Add this line to your application's Gemfile:
|
24
18
|
|
25
19
|
```ruby
|
26
|
-
gem "feen"
|
20
|
+
gem "feen", ">= 5.0.0.beta1"
|
27
21
|
```
|
28
22
|
|
29
23
|
And then execute:
|
@@ -35,20 +29,30 @@ bundle install
|
|
35
29
|
Or install it yourself as:
|
36
30
|
|
37
31
|
```sh
|
38
|
-
gem install feen
|
32
|
+
gem install feen --pre
|
39
33
|
```
|
40
34
|
|
41
35
|
## Usage
|
42
36
|
|
37
|
+
### Serialization
|
38
|
+
|
39
|
+
A position can be serialized by filling in these fields:
|
40
|
+
|
41
|
+
- **Board shape**: An array of integers. For instance, it would be `[10, 9]` for a Xiangqi board. Or it would be `[8, 8]` for a Chess board.
|
42
|
+
- **Piece placement**: Describes the placement of pieces on the board with a hash that references each piece on the board.
|
43
|
+
- **Side to move**: A char that indicates who moves next. In chess, "`w`" would mean that White can play a move.
|
44
|
+
|
45
|
+
#### Example
|
46
|
+
|
47
|
+
From a classic Tsume Shogi problem:
|
48
|
+
|
43
49
|
```ruby
|
44
50
|
require "feen"
|
45
51
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
side_id: 0,
|
51
|
-
square: {
|
52
|
+
Feen.dump(
|
53
|
+
board_shape: [9, 9],
|
54
|
+
side_to_move: "s",
|
55
|
+
piece_placement: {
|
52
56
|
3 => "s",
|
53
57
|
4 => "k",
|
54
58
|
5 => "s",
|
@@ -56,11 +60,22 @@ FEEN.dump(
|
|
56
60
|
43 => "+B"
|
57
61
|
}
|
58
62
|
)
|
59
|
-
# => "
|
63
|
+
# => "3sks3/9/4+P4/9/7+B1/9/9/9/9 s"
|
64
|
+
```
|
65
|
+
|
66
|
+
### Deserialization
|
67
|
+
|
68
|
+
Serialized positions can be converted back to fields.
|
69
|
+
|
70
|
+
#### Example
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require "feen"
|
60
74
|
|
61
|
-
|
62
|
-
|
63
|
-
#
|
75
|
+
Feen.parse("3sks3/9/4+P4/9/7+B1/9/9/9/9 s")
|
76
|
+
# {:board_shape=>[9, 9],
|
77
|
+
# :piece_placement=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"},
|
78
|
+
# :side_to_move=>"s"}
|
64
79
|
```
|
65
80
|
|
66
81
|
## License
|
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module
|
3
|
+
module Feen
|
4
4
|
module Dumper
|
5
|
-
# The
|
5
|
+
# The PiecePlacement class.
|
6
6
|
#
|
7
7
|
# @example Dump an empty board of Xiangqi
|
8
|
-
#
|
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
|
-
#
|
11
|
+
# PiecePlacement.new(
|
12
12
|
# [10, 9],
|
13
13
|
# {
|
14
14
|
# 0 => "車",
|
@@ -44,13 +44,13 @@ module FEEN
|
|
44
44
|
# 88 => "傌",
|
45
45
|
# 89 => "俥"
|
46
46
|
# }
|
47
|
-
# ).to_s # => "
|
48
|
-
class
|
47
|
+
# ).to_s # => "車馬象士將士象馬車/9/1砲5砲1/卒1卒1卒1卒1卒/9/9/兵1兵1兵1兵1兵/1炮5炮1/9/俥傌相仕帥仕相傌俥"
|
48
|
+
class PiecePlacement
|
49
49
|
# @param indexes [Array] The shape of the board.
|
50
|
-
# @param
|
51
|
-
def initialize(indexes,
|
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|
|
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.
|
@@ -79,6 +79,7 @@ module FEEN
|
|
79
79
|
.map { |square| square.nil? ? 1 : square }
|
80
80
|
.join(",")
|
81
81
|
.gsub(/1,[1,]*1/) { |str| str.split(",").length }
|
82
|
+
.delete(",")
|
82
83
|
end
|
83
84
|
end
|
84
85
|
end
|
data/lib/feen/dumper.rb
CHANGED
@@ -1,25 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative File.join("dumper", "
|
4
|
-
require_relative File.join("dumper", "square")
|
5
|
-
require_relative File.join("dumper", "turn")
|
3
|
+
require_relative File.join("dumper", "piece_placement")
|
6
4
|
|
7
|
-
module
|
5
|
+
module Feen
|
8
6
|
# The dumper module.
|
9
7
|
module Dumper
|
10
8
|
# Dump position params into a FEEN string.
|
11
9
|
#
|
12
|
-
# @param
|
13
|
-
# @param
|
14
|
-
# @param
|
15
|
-
# @param square [Hash] The index of each piece on the board.
|
10
|
+
# @param board_shape [Array] The shape of the board.
|
11
|
+
# @param side_to_move [String] Identify the active side.
|
12
|
+
# @param piece_placement [Hash] The index of each piece on the board.
|
16
13
|
#
|
17
14
|
# @example Dump a classic Tsume Shogi problem
|
18
15
|
# call(
|
19
|
-
# "
|
20
|
-
# "
|
21
|
-
# "
|
22
|
-
# "square": {
|
16
|
+
# "board_shape": [9, 9],
|
17
|
+
# "side_to_move": "s",
|
18
|
+
# "piece_placement": {
|
23
19
|
# 3 => "s",
|
24
20
|
# 4 => "k",
|
25
21
|
# 5 => "s",
|
@@ -27,14 +23,13 @@ module FEEN
|
|
27
23
|
# 43 => "+B"
|
28
24
|
# }
|
29
25
|
# )
|
30
|
-
# # => "
|
26
|
+
# # => "3sks3/9/4+P4/9/7+B1/9/9/9/9 s"
|
31
27
|
#
|
32
28
|
# @return [String] The FEEN string representing the position.
|
33
|
-
def self.call(
|
29
|
+
def self.call(board_shape:, side_to_move:, piece_placement:)
|
34
30
|
[
|
35
|
-
|
36
|
-
|
37
|
-
InHand.dump(in_hand)
|
31
|
+
PiecePlacement.new(board_shape, piece_placement).to_s,
|
32
|
+
side_to_move
|
38
33
|
].join(" ")
|
39
34
|
end
|
40
35
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Feen
|
4
|
+
module Parser
|
5
|
+
# The BoardShape class.
|
6
|
+
#
|
7
|
+
# @example Parse the shape of a shogiban
|
8
|
+
# BoardShape.new("3sks3/9/4+P4/9/7+B1/9/9/9/9").to_a # => [9, 9]
|
9
|
+
class BoardShape
|
10
|
+
# @param board_str [String] The flatten board.
|
11
|
+
def initialize(board_str, regex: /\+?[a-z]/i)
|
12
|
+
@board_str = board_str
|
13
|
+
@regex = regex
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Array] The size of each dimension of the board.
|
17
|
+
def to_a
|
18
|
+
indexes(@board_str, @board_str.scan(%r{/+}).sort.fetch(-1))
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def indexes(string, separator)
|
24
|
+
if separator.empty?
|
25
|
+
last_index = string.scan(/(\d+|#{@regex})/).inject(0) do |counter, match|
|
26
|
+
sub_string = match[0]
|
27
|
+
number = sub_string.match?(/\d+/) ? Integer(sub_string) : 1
|
28
|
+
counter + number
|
29
|
+
end
|
30
|
+
|
31
|
+
return [last_index]
|
32
|
+
end
|
33
|
+
|
34
|
+
sub_strings = string.split(separator)
|
35
|
+
[sub_strings.length] + indexes(sub_strings.fetch(0), separator[1..])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/feen/parser.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative File.join("parser", "
|
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")
|
7
4
|
|
8
|
-
module
|
5
|
+
module Feen
|
9
6
|
# The parser module.
|
10
7
|
module Parser
|
11
8
|
# Parse a FEEN string into position params.
|
@@ -13,12 +10,11 @@ module FEEN
|
|
13
10
|
# @param feen [String] The FEEN string representing a position.
|
14
11
|
#
|
15
12
|
# @example Parse a classic Tsume Shogi problem
|
16
|
-
# call("
|
13
|
+
# call("3sks3/9/4+P4/9/7+B1/9/9/9/9 s")
|
17
14
|
# # => {
|
18
|
-
# # "
|
19
|
-
# # "
|
20
|
-
# # "
|
21
|
-
# # "square": {
|
15
|
+
# # "board_shape": [9, 9],
|
16
|
+
# # "side_to_move": "s",
|
17
|
+
# # "piece_placement": {
|
22
18
|
# # 3 => "s",
|
23
19
|
# # 4 => "k",
|
24
20
|
# # 5 => "s",
|
@@ -27,15 +23,29 @@ module FEEN
|
|
27
23
|
# # }
|
28
24
|
#
|
29
25
|
# @return [Hash] The position params representing the position.
|
30
|
-
def self.call(feen)
|
31
|
-
|
26
|
+
def self.call(feen, regex: /\+?[a-z]/i)
|
27
|
+
piece_placement_str, side_to_move_str = feen.split
|
32
28
|
|
33
29
|
{
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
square: Square.new(square_str).to_h
|
30
|
+
board_shape: BoardShape.new(piece_placement_str, regex:).to_a,
|
31
|
+
piece_placement: piece_placement(piece_placement_str, regex:),
|
32
|
+
side_to_move: side_to_move_str
|
38
33
|
}
|
39
34
|
end
|
35
|
+
|
36
|
+
def self.piece_placement(string, regex:)
|
37
|
+
hash = {}
|
38
|
+
index = 0
|
39
|
+
string.scan(/(\d+|#{regex})/) do |match|
|
40
|
+
if /\d+/.match?(match[0])
|
41
|
+
index += match[0].to_i
|
42
|
+
else
|
43
|
+
hash[index] = match[0]
|
44
|
+
index += 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
hash
|
48
|
+
end
|
49
|
+
private_class_method :piece_placement
|
40
50
|
end
|
41
51
|
end
|
data/lib/feen.rb
CHANGED
@@ -6,21 +6,19 @@ require_relative File.join("feen", "parser")
|
|
6
6
|
# This module provides a Ruby interface for data serialization and
|
7
7
|
# deserialization in FEEN format.
|
8
8
|
#
|
9
|
-
# @see https://
|
10
|
-
module
|
9
|
+
# @see https://github.com/sashite/specs/blob/main/forsyth-edwards-expanded-notation.md
|
10
|
+
module Feen
|
11
11
|
# Dumps position params into a FEEN string.
|
12
12
|
#
|
13
|
-
# @param
|
14
|
-
# @param
|
15
|
-
# @param
|
16
|
-
# @param square [Hash] The index of each piece on the board.
|
13
|
+
# @param board_shape [Array] The shape of the board.
|
14
|
+
# @param side_to_move [String] The identifier of the player who must play.
|
15
|
+
# @param piece_placement [Hash] The index of each piece on the board.
|
17
16
|
#
|
18
17
|
# @example Dump a classic Tsume Shogi problem
|
19
18
|
# dump(
|
20
|
-
# "
|
21
|
-
# "
|
22
|
-
# "
|
23
|
-
# "square": {
|
19
|
+
# "board_shape": [9, 9],
|
20
|
+
# "side_to_move": "s",
|
21
|
+
# "piece_placement": {
|
24
22
|
# 3 => "s",
|
25
23
|
# 4 => "k",
|
26
24
|
# 5 => "s",
|
@@ -28,15 +26,14 @@ module FEEN
|
|
28
26
|
# 43 => "+B"
|
29
27
|
# }
|
30
28
|
# )
|
31
|
-
# # => "
|
29
|
+
# # => "3sks3/9/4+P4/9/7+B1/9/9/9/9 s"
|
32
30
|
#
|
33
31
|
# @return [String] The FEEN string representing the position.
|
34
|
-
def self.dump(
|
32
|
+
def self.dump(board_shape:, side_to_move:, piece_placement:)
|
35
33
|
Dumper.call(
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
square:
|
34
|
+
board_shape:,
|
35
|
+
side_to_move:,
|
36
|
+
piece_placement:
|
40
37
|
)
|
41
38
|
end
|
42
39
|
|
@@ -45,12 +42,11 @@ module FEEN
|
|
45
42
|
# @param feen [String] The FEEN string representing a position.
|
46
43
|
#
|
47
44
|
# @example Parse a classic Tsume Shogi problem
|
48
|
-
# parse("
|
45
|
+
# parse("3sks3/9/4+P4/9/7+B1/9/9/9/9 s")
|
49
46
|
# # => {
|
50
|
-
# # "
|
51
|
-
# # "
|
52
|
-
# # "
|
53
|
-
# # "square": {
|
47
|
+
# # "board_shape": [9, 9],
|
48
|
+
# # "side_to_move": "s",
|
49
|
+
# # "piece_placement": {
|
54
50
|
# # 3 => "s",
|
55
51
|
# # 4 => "k",
|
56
52
|
# # 5 => "s",
|
@@ -59,7 +55,7 @@ module FEEN
|
|
59
55
|
# # }
|
60
56
|
#
|
61
57
|
# @return [Hash] The position params representing the position.
|
62
|
-
def self.parse(feen)
|
63
|
-
Parser.call(feen)
|
58
|
+
def self.parse(feen, regex: /\+?[a-z]/i)
|
59
|
+
Parser.call(feen, regex:)
|
64
60
|
end
|
65
61
|
end
|
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
|
+
version: 5.0.0.beta1
|
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-
|
11
|
+
date: 2023-04-27 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,9 @@ files:
|
|
20
20
|
- README.md
|
21
21
|
- lib/feen.rb
|
22
22
|
- lib/feen/dumper.rb
|
23
|
-
- lib/feen/dumper/
|
24
|
-
- lib/feen/dumper/square.rb
|
25
|
-
- lib/feen/dumper/turn.rb
|
23
|
+
- lib/feen/dumper/piece_placement.rb
|
26
24
|
- lib/feen/parser.rb
|
27
|
-
- lib/feen/parser/
|
28
|
-
- lib/feen/parser/shape.rb
|
29
|
-
- lib/feen/parser/square.rb
|
30
|
-
- lib/feen/parser/turn.rb
|
25
|
+
- lib/feen/parser/board_shape.rb
|
31
26
|
homepage: https://github.com/sashite/feen.rb
|
32
27
|
licenses:
|
33
28
|
- MIT
|
@@ -44,9 +39,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
39
|
version: 3.2.0
|
45
40
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
46
41
|
requirements:
|
47
|
-
- - "
|
42
|
+
- - ">"
|
48
43
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
44
|
+
version: 1.3.1
|
50
45
|
requirements: []
|
51
46
|
rubygems_version: 3.4.6
|
52
47
|
signing_key:
|
data/lib/feen/dumper/in_hand.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FEEN
|
4
|
-
module Dumper
|
5
|
-
# The pieces in hand module.
|
6
|
-
module InHand
|
7
|
-
# Serialize pieces in hand lists into a string.
|
8
|
-
#
|
9
|
-
# @param piece_names [Array] A list of pieces in hand.
|
10
|
-
#
|
11
|
-
# @example Dump a list of pieces in hand
|
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"
|
14
|
-
#
|
15
|
-
# @example Dump an empty list of pieces in hand
|
16
|
-
# dump([])
|
17
|
-
# # => "-"
|
18
|
-
#
|
19
|
-
# @return [String] A string representing the pieces in hand.
|
20
|
-
def self.dump(piece_names)
|
21
|
-
return "-" if piece_names.empty?
|
22
|
-
|
23
|
-
piece_names.sort.join(",")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/feen/dumper/turn.rb
DELETED
@@ -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
|
data/lib/feen/parser/in_hand.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FEEN
|
4
|
-
module Parser
|
5
|
-
# The pieces in hand module.
|
6
|
-
module InHand
|
7
|
-
# The list of pieces in hand grouped by players.
|
8
|
-
#
|
9
|
-
# @param piece_names_str [String] The serialized list of pieces in hand.
|
10
|
-
#
|
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")
|
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
|
-
#
|
15
|
-
# @example Parse an empty list of serialized pieces in hand
|
16
|
-
# parse("-")
|
17
|
-
# # => []
|
18
|
-
#
|
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 == "-"
|
22
|
-
|
23
|
-
piece_names_str.split(",")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
data/lib/feen/parser/shape.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FEEN
|
4
|
-
module Parser
|
5
|
-
# The shape class.
|
6
|
-
#
|
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
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Array] The size of each dimension of the board.
|
16
|
-
def to_a
|
17
|
-
indexes(@board, @board.scan(%r{/+}).sort.fetch(-1))
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def indexes(string, separator)
|
23
|
-
if separator.empty?
|
24
|
-
last_index = string.split(",").inject(0) do |counter, sub_string|
|
25
|
-
number = sub_string.match?(/[0-9]+/) ? Integer(sub_string) : 1
|
26
|
-
counter + number
|
27
|
-
end
|
28
|
-
|
29
|
-
return [last_index]
|
30
|
-
end
|
31
|
-
|
32
|
-
sub_strings = string.split(separator)
|
33
|
-
[sub_strings.length] + indexes(sub_strings.fetch(0), separator[1..])
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/lib/feen/parser/square.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module FEEN
|
4
|
-
module Parser
|
5
|
-
# The square class.
|
6
|
-
#
|
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
|
9
|
-
# # => [
|
10
|
-
# # nil, nil, nil, "s", "k", "s", nil, nil, nil,
|
11
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
12
|
-
# # nil, nil, nil, nil, "+P", nil, nil, nil, nil,
|
13
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
14
|
-
# # nil, nil, nil, nil, nil, nil, nil, "+B", nil,
|
15
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
16
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
17
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
18
|
-
# # nil, nil, nil, nil, nil, nil, nil, nil, nil
|
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
|
-
# # }
|
30
|
-
class Square
|
31
|
-
# @param board [String] The flatten board.
|
32
|
-
def initialize(board)
|
33
|
-
@board = board
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Array] The list of squares on the board.
|
37
|
-
def to_a
|
38
|
-
@board
|
39
|
-
.split(%r{[/,]+})
|
40
|
-
.flat_map { |str| row(str) }
|
41
|
-
end
|
42
|
-
|
43
|
-
# @return [Hash] The index 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 => v)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def row(string)
|
57
|
-
string.match?(/[0-9]+/) ? ::Array.new(Integer(string)) : string
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/feen/parser/turn.rb
DELETED
@@ -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
|