portable_move_notation 2.1.1 → 2.2.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/README.md +8 -8
- data/lib/portable_move_notation/action.rb +19 -19
- data/lib/portable_move_notation/move.rb +11 -11
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9133acb705a120376e5045428a24e3625ff82641c1628b5885feabe69d00259a
|
4
|
+
data.tar.gz: f898676def7e06bc14df0a998a28eac970413a0793e5b43bd16b67d8fda23312
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee79ca0d901bc10a36fffd1d7a6af726fdfa4d73ccb53318722c3c73d71da51f2893f4e7a4e597e239cabdedf87faa98ff92d0f76527e0632c00de44f1083937
|
7
|
+
data.tar.gz: bd11df77a4ef1d2e6b96d4c648e65609630d711bb128a344cac7d7990b5b45cb7e398da3c978035c34d1fd22969406d40355fe04c00ca52e9a9a26ff6bd80746
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ require "portable_move_notation" # provides the PortableMoveNotation namespace
|
|
48
48
|
|
49
49
|
## Quick Start
|
50
50
|
|
51
|
-
Dump a single action (dropping a Shogi pawn on square 27):
|
51
|
+
Dump a single action (dropping a Shogi pawn on square "27"):
|
52
52
|
|
53
53
|
```ruby
|
54
54
|
require "portable_move_notation"
|
@@ -56,7 +56,7 @@ require "portable_move_notation"
|
|
56
56
|
move = PortableMoveNotation::Move.new(
|
57
57
|
PortableMoveNotation::Action.new(
|
58
58
|
src_square: nil,
|
59
|
-
dst_square: 27,
|
59
|
+
dst_square: "27",
|
60
60
|
piece_name: "p",
|
61
61
|
piece_hand: nil
|
62
62
|
)
|
@@ -70,7 +70,7 @@ Parse it back:
|
|
70
70
|
|
71
71
|
```ruby
|
72
72
|
restored = PortableMoveNotation::Move.from_json(move.to_json)
|
73
|
-
puts restored.actions.first.dst_square # => 27
|
73
|
+
puts restored.actions.first.dst_square # => "27"
|
74
74
|
```
|
75
75
|
|
76
76
|
---
|
@@ -83,10 +83,10 @@ puts restored.actions.first.dst_square # => 27
|
|
83
83
|
require "portable_move_notation"
|
84
84
|
|
85
85
|
king = PortableMoveNotation::Action.new(
|
86
|
-
src_square:
|
86
|
+
src_square: "e1", dst_square: "g1", piece_name: "K", piece_hand: nil
|
87
87
|
)
|
88
88
|
rook = PortableMoveNotation::Action.new(
|
89
|
-
src_square:
|
89
|
+
src_square: "h1", dst_square: "f1", piece_name: "R", piece_hand: nil
|
90
90
|
)
|
91
91
|
|
92
92
|
puts PortableMoveNotation::Move.new(king, rook).to_json
|
@@ -103,8 +103,8 @@ puts PortableMoveNotation::Move.new(king, rook).to_json
|
|
103
103
|
require "portable_move_notation"
|
104
104
|
require "json"
|
105
105
|
|
106
|
-
# Parse a simple JSON move with a pawn at square 27
|
107
|
-
data = JSON.parse('[{ "dst_square" => 27, "piece_name" => "p" }]')
|
106
|
+
# Parse a simple JSON move with a pawn at square "27"
|
107
|
+
data = JSON.parse('[{ "dst_square" => "27", "piece_name" => "p" }]')
|
108
108
|
puts PortableMoveNotation::Move.valid?(data) # => true
|
109
109
|
```
|
110
110
|
|
@@ -112,7 +112,7 @@ You can also validate single actions:
|
|
112
112
|
|
113
113
|
```ruby
|
114
114
|
# Check if an individual action is valid
|
115
|
-
action_data = { "dst_square" =>
|
115
|
+
action_data = { "dst_square" => "e4", "piece_name" => "P" }
|
116
116
|
puts PortableMoveNotation::Action.valid?(action_data) # => true
|
117
117
|
```
|
118
118
|
|
@@ -3,16 +3,16 @@
|
|
3
3
|
module PortableMoveNotation
|
4
4
|
# == Action
|
5
5
|
#
|
6
|
-
# An **Action** is the *atomic* unit of Portable
|
6
|
+
# An **Action** is the *atomic* unit of Portable Move Notation. Each instance
|
7
7
|
# describes **one** deterministic transformation applied to either the board
|
8
8
|
# or the mover's reserve.
|
9
9
|
#
|
10
10
|
# | Field | Meaning |
|
11
11
|
# |--------------|------------------------------------------------------------------------|
|
12
|
-
# | `src_square` |
|
13
|
-
# | `dst_square` |
|
12
|
+
# | `src_square` | String label of the square *vacated* – or +nil+ when dropping |
|
13
|
+
# | `dst_square` | String label of the square now **occupied** by {#piece_name} |
|
14
14
|
# | `piece_name` | Post‑action identifier on `dst_square` (may contain prefix/suffix) |
|
15
|
-
# | `piece_hand` | Bare letter that enters the mover's hand
|
15
|
+
# | `piece_hand` | Bare letter that enters the mover's hand – or +nil+ |
|
16
16
|
#
|
17
17
|
# The implicit side‑effects are rule‑agnostic:
|
18
18
|
# * `src_square` (when not +nil+) becomes empty.
|
@@ -22,17 +22,17 @@ module PortableMoveNotation
|
|
22
22
|
#
|
23
23
|
# === Examples
|
24
24
|
#
|
25
|
-
# @example Basic piece movement (Chess pawn e2
|
26
|
-
# PortableMoveNotation::Action.new(src_square:
|
25
|
+
# @example Basic piece movement (Chess pawn e2 → e4)
|
26
|
+
# PortableMoveNotation::Action.new(src_square: "e2", dst_square: "e4", piece_name: "P")
|
27
27
|
#
|
28
28
|
# @example Drop from hand (Shogi pawn onto 27)
|
29
|
-
# PortableMoveNotation::Action.new(src_square: nil, dst_square: 27, piece_name: "p")
|
29
|
+
# PortableMoveNotation::Action.new(src_square: nil, dst_square: "27", piece_name: "p")
|
30
30
|
#
|
31
31
|
# @example Capture with demotion (Bishop captures +p and acquires P in hand)
|
32
|
-
# PortableMoveNotation::Action.new(src_square: 36, dst_square: 27, piece_name: "B", piece_hand: "P")
|
32
|
+
# PortableMoveNotation::Action.new(src_square: "36", dst_square: "27", piece_name: "B", piece_hand: "P")
|
33
33
|
#
|
34
|
-
# @see https://sashite.dev/documents/pmn/ Portable
|
35
|
-
# @see https://sashite.dev/documents/pnn/ Piece
|
34
|
+
# @see https://sashite.dev/documents/pmn/ Portable Move Notation specification
|
35
|
+
# @see https://sashite.dev/documents/pnn/ Piece Name Notation specification
|
36
36
|
class Action
|
37
37
|
# Regular expression for validating piece identifiers as per PNN.
|
38
38
|
# Matches: optional '+'/ '-' prefix, a single ASCII letter, optional "'" suffix.
|
@@ -65,8 +65,8 @@ module PortableMoveNotation
|
|
65
65
|
# Builds an {Action} from keyword parameters.
|
66
66
|
#
|
67
67
|
# @param params [Hash] Keyword parameters.
|
68
|
-
# @option params [
|
69
|
-
# @option params [
|
68
|
+
# @option params [String, nil] :src_square Source coordinate, or +nil+ when dropping from hand.
|
69
|
+
# @option params [String] :dst_square Destination coordinate (required).
|
70
70
|
# @option params [String] :piece_name Post‑move piece identifier (required).
|
71
71
|
# @option params [String, nil] :piece_hand Captured piece letter entering hand.
|
72
72
|
# @return [Action]
|
@@ -84,9 +84,9 @@ module PortableMoveNotation
|
|
84
84
|
# Attributes
|
85
85
|
# ------------------------------------------------------------------
|
86
86
|
|
87
|
-
# @return [
|
87
|
+
# @return [String, nil] Source square (or +nil+ for drops)
|
88
88
|
attr_reader :src_square
|
89
|
-
# @return [
|
89
|
+
# @return [String] Destination square
|
90
90
|
attr_reader :dst_square
|
91
91
|
# @return [String] Post‑move piece identifier
|
92
92
|
attr_reader :piece_name
|
@@ -99,9 +99,9 @@ module PortableMoveNotation
|
|
99
99
|
|
100
100
|
# Instantiates a new {Action}.
|
101
101
|
#
|
102
|
-
# @param dst_square [
|
102
|
+
# @param dst_square [String] Destination coordinate.
|
103
103
|
# @param piece_name [String] Post‑move piece identifier.
|
104
|
-
# @param src_square [
|
104
|
+
# @param src_square [String, nil] Source coordinate or +nil+.
|
105
105
|
# @param piece_hand [String, nil] Captured piece entering hand.
|
106
106
|
# @raise [ArgumentError] If any value fails validation.
|
107
107
|
def initialize(dst_square:, piece_name:, src_square: nil, piece_hand: nil)
|
@@ -148,14 +148,14 @@ module PortableMoveNotation
|
|
148
148
|
|
149
149
|
private
|
150
150
|
|
151
|
-
# Validates that *square* is a non‑
|
151
|
+
# Validates that *square* is a non‑empty string.
|
152
152
|
#
|
153
153
|
# @param square [Object]
|
154
154
|
# @raise [ArgumentError] If invalid.
|
155
155
|
def validate_square(square)
|
156
|
-
return if square.is_a?(::
|
156
|
+
return if square.is_a?(::String) && !square.empty?
|
157
157
|
|
158
|
-
raise ::ArgumentError, "Square must be a non-
|
158
|
+
raise ::ArgumentError, "Square must be a non-empty string"
|
159
159
|
end
|
160
160
|
|
161
161
|
# Validates {#piece_name} format.
|
@@ -6,7 +6,7 @@ module PortableMoveNotation
|
|
6
6
|
# == Move
|
7
7
|
#
|
8
8
|
# A **Move** is an *ordered list* of {Action} instances that, applied **in
|
9
|
-
# order**, realise a deterministic change of game state under Portable
|
9
|
+
# order**, realise a deterministic change of game state under Portable Move
|
10
10
|
# Notation (PMN). A move can be as small as a single pawn push or as large as
|
11
11
|
# a compound fairy‐move that relocates several pieces at once.
|
12
12
|
#
|
@@ -15,15 +15,15 @@ module PortableMoveNotation
|
|
15
15
|
# given game is beyond its responsibility and must be enforced by an engine
|
16
16
|
# or referee layer.
|
17
17
|
#
|
18
|
-
# === Quick
|
18
|
+
# === Quick start
|
19
19
|
#
|
20
20
|
# ```ruby
|
21
21
|
# require "portable_move_notation"
|
22
22
|
#
|
23
23
|
# # Plain chess pawn move: e2 → e4
|
24
24
|
# pawn = PortableMoveNotation::Action.new(
|
25
|
-
# src_square:
|
26
|
-
# dst_square:
|
25
|
+
# src_square: "e2",
|
26
|
+
# dst_square: "e4",
|
27
27
|
# piece_name: "P"
|
28
28
|
# )
|
29
29
|
#
|
@@ -32,23 +32,23 @@ module PortableMoveNotation
|
|
32
32
|
# # => JSON representation of the move
|
33
33
|
#
|
34
34
|
# parsed = PortableMoveNotation::Move.from_json(move.to_json)
|
35
|
-
# parsed.actions.first.dst_square # =>
|
35
|
+
# parsed.actions.first.dst_square # => "e4"
|
36
36
|
# ```
|
37
37
|
#
|
38
38
|
# === Composite example (Chess kingside castling)
|
39
39
|
#
|
40
40
|
# ```ruby
|
41
41
|
# king = PortableMoveNotation::Action.new(
|
42
|
-
# src_square:
|
42
|
+
# src_square: "e1", dst_square: "g1", piece_name: "K"
|
43
43
|
# )
|
44
44
|
# rook = PortableMoveNotation::Action.new(
|
45
|
-
# src_square:
|
45
|
+
# src_square: "h1", dst_square: "f1", piece_name: "R"
|
46
46
|
# )
|
47
47
|
#
|
48
48
|
# castle = PortableMoveNotation::Move.new(king, rook)
|
49
49
|
# ```
|
50
50
|
#
|
51
|
-
# @see https://sashite.dev/documents/pmn/ Portable
|
51
|
+
# @see https://sashite.dev/documents/pmn/ Portable Move Notation specification
|
52
52
|
class Move
|
53
53
|
# --------------------------------------------------------------------
|
54
54
|
# Class helpers
|
@@ -63,7 +63,7 @@ module PortableMoveNotation
|
|
63
63
|
# @return [Boolean] +true+ when every element passes {Action.valid?}.
|
64
64
|
#
|
65
65
|
# @example Validate PMN parsed from JSON
|
66
|
-
# data = JSON.parse('[{"dst_square":
|
66
|
+
# data = JSON.parse('[{"dst_square":"e7","piece_name":"p"}]')
|
67
67
|
# PortableMoveNotation::Move.valid?(data) # => true
|
68
68
|
def self.valid?(pmn_data)
|
69
69
|
return false unless pmn_data.is_a?(::Array) && !pmn_data.empty?
|
@@ -79,7 +79,7 @@ module PortableMoveNotation
|
|
79
79
|
# @raise [KeyError] If an action hash lacks required keys.
|
80
80
|
#
|
81
81
|
# @example
|
82
|
-
# json = '[{"src_square":
|
82
|
+
# json = '[{"src_square":null,"dst_square":"e7","piece_name":"p"}]'
|
83
83
|
# PortableMoveNotation::Move.from_json(json)
|
84
84
|
def self.from_json(json_string)
|
85
85
|
from_pmn(::JSON.parse(json_string))
|
@@ -110,7 +110,7 @@ module PortableMoveNotation
|
|
110
110
|
# @raise [KeyError] If +actions+ is missing.
|
111
111
|
#
|
112
112
|
# @example
|
113
|
-
# Move.from_params(actions: [src_square: nil, dst_square:
|
113
|
+
# Move.from_params(actions: [src_square: nil, dst_square: "e7", piece_name: "p"])
|
114
114
|
def self.from_params(actions:)
|
115
115
|
array = Array(actions).map do |obj|
|
116
116
|
obj.is_a?(Action) ? obj : Action.from_params(**obj)
|