feen 4.0.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![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)
|
@@ -6,24 +6,18 @@
|
|
6
6
|
[![RuboCop](https://github.com/sashite/feen.rb/workflows/RuboCop/badge.svg?branch=main)](https://github.com/sashite/feen.rb/actions?query=workflow%3Arubocop+branch%3Amain)
|
7
7
|
[![License](https://img.shields.io/github/license/sashite/feen.rb?label=License&logo=github)](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
|
-
![3D chess on Star Trek (from the episode "Court Martial")](https://github.com/sashite/feen.rb/raw/main/star-trek-chess.jpg)
|
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
|