Class: Sashite::Pmn::Move
- Inherits:
-
Object
- Object
- Sashite::Pmn::Move
- Defined in:
- lib/sashite/pmn/move.rb
Overview
Represents a complete move in PMN notation.
A Move is a sequence of zero or more atomic actions described by a flat list of elements:
[] # pass move (empty array)
[source, destination] # inferred piece
[source, destination, piece] # explicit QPI piece
Valid lengths:
- 0 (pass move)
- multiple of 3 OR multiple of 3 + 2 (minimum 2 for non-pass moves)
Instance Attribute Summary collapse
-
#actions ⇒ Array<Action>
readonly
Ordered sequence of actions (empty for pass moves).
-
#pmn_array ⇒ Array<String>
readonly
Original PMN elements (frozen, empty for pass moves).
Class Method Summary collapse
-
.from_actions(actions) ⇒ Move
Build a move from Action objects.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Equality by original PMN elements.
-
#board_moves ⇒ Array<Action>
Only board-to-board actions.
-
#compound? ⇒ Boolean
Multiple actions?.
-
#destinations ⇒ Array<String>
Unique destinations.
-
#empty? ⇒ Boolean
True if no actions (pass move).
- #first_action ⇒ Action?
-
#has_captures? ⇒ Boolean
Any capture?.
-
#has_drops? ⇒ Boolean
Any drop?.
-
#has_inferred? ⇒ Boolean
True if any action has inferred piece.
- #hash ⇒ Integer
-
#initialize(*pmn_elements) ⇒ Move
constructor
Create a Move from PMN elements (variadic only).
- #inspect ⇒ String
- #last_action ⇒ Action?
-
#pass? ⇒ Boolean
Is this a pass move (no actions)?.
-
#pieces ⇒ Array<String>
Unique specified pieces (excludes inferred).
-
#simple? ⇒ Boolean
Exactly one action?.
-
#size ⇒ Integer
(also: #length)
Number of actions (0 for pass moves).
-
#sources ⇒ Array<String>
Unique sources.
-
#to_a ⇒ Array<String>
Copy of original PMN elements (empty array for pass moves).
-
#valid? ⇒ Boolean
True if PMN length is valid and all actions are valid.
-
#with_actions(actions_to_add) ⇒ Move
New Move with appended actions.
Constructor Details
#initialize(*pmn_elements) ⇒ Move
Create a Move from PMN elements (variadic only).
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/sashite/pmn/move.rb', line 35 def initialize(*pmn_elements) # single-array form is intentionally not supported (entropy reduction) if pmn_elements.size == 1 && pmn_elements.first.is_a?(::Array) raise Error::Move, 'PMN must be passed as individual arguments, e.g. Move.new("e2","e4","C:P")' end validate_array!(pmn_elements) @pmn_array = pmn_elements.dup.freeze @actions = parse_actions(@pmn_array).freeze validate_actions! freeze end |
Instance Attribute Details
#actions ⇒ Array<Action> (readonly)
Returns ordered sequence of actions (empty for pass moves).
21 22 23 |
# File 'lib/sashite/pmn/move.rb', line 21 def actions @actions end |
#pmn_array ⇒ Array<String> (readonly)
Returns original PMN elements (frozen, empty for pass moves).
24 25 26 |
# File 'lib/sashite/pmn/move.rb', line 24 def pmn_array @pmn_array end |
Class Method Details
.from_actions(actions) ⇒ Move
Build a move from Action objects.
176 177 178 179 |
# File 'lib/sashite/pmn/move.rb', line 176 def self.from_actions(actions) pmn = actions.flat_map(&:to_a) new(*pmn) end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Returns equality by original PMN elements.
142 143 144 145 146 |
# File 'lib/sashite/pmn/move.rb', line 142 def ==(other) return false unless other.is_a?(Move) pmn_array == other.pmn_array end |
#board_moves ⇒ Array<Action>
Returns only board-to-board actions.
107 108 109 |
# File 'lib/sashite/pmn/move.rb', line 107 def board_moves actions.select(&:board_to_board?) end |
#compound? ⇒ Boolean
Returns multiple actions?.
69 70 71 |
# File 'lib/sashite/pmn/move.rb', line 69 def compound? actions.size > 1 end |
#destinations ⇒ Array<String>
Returns unique destinations.
117 118 119 |
# File 'lib/sashite/pmn/move.rb', line 117 def destinations actions.map(&:destination).uniq end |
#empty? ⇒ Boolean
Returns true if no actions (pass move).
90 91 92 |
# File 'lib/sashite/pmn/move.rb', line 90 def empty? actions.empty? end |
#first_action ⇒ Action?
74 75 76 |
# File 'lib/sashite/pmn/move.rb', line 74 def first_action actions.first end |
#has_captures? ⇒ Boolean
Returns any capture?.
102 103 104 |
# File 'lib/sashite/pmn/move.rb', line 102 def has_captures? actions.any?(&:capture?) end |
#has_drops? ⇒ Boolean
Returns any drop?.
97 98 99 |
# File 'lib/sashite/pmn/move.rb', line 97 def has_drops? actions.any?(&:drop?) end |
#has_inferred? ⇒ Boolean
Returns true if any action has inferred piece.
127 128 129 |
# File 'lib/sashite/pmn/move.rb', line 127 def has_inferred? actions.any?(&:inferred?) end |
#hash ⇒ Integer
150 151 152 |
# File 'lib/sashite/pmn/move.rb', line 150 def hash pmn_array.hash end |
#inspect ⇒ String
155 156 157 158 159 160 161 |
# File 'lib/sashite/pmn/move.rb', line 155 def inspect if pass? "#<#{self.class.name} pass=true>" else "#<#{self.class.name} actions=#{actions.size} pmn=#{pmn_array.inspect}>" end end |
#last_action ⇒ Action?
79 80 81 |
# File 'lib/sashite/pmn/move.rb', line 79 def last_action actions.last end |
#pass? ⇒ Boolean
Returns is this a pass move (no actions)?.
59 60 61 |
# File 'lib/sashite/pmn/move.rb', line 59 def pass? actions.empty? end |
#pieces ⇒ Array<String>
Returns unique specified pieces (excludes inferred).
122 123 124 |
# File 'lib/sashite/pmn/move.rb', line 122 def pieces actions.filter_map(&:piece).uniq end |
#simple? ⇒ Boolean
Returns exactly one action?.
64 65 66 |
# File 'lib/sashite/pmn/move.rb', line 64 def simple? actions.size == 1 end |
#size ⇒ Integer Also known as: length
Returns number of actions (0 for pass moves).
84 85 86 |
# File 'lib/sashite/pmn/move.rb', line 84 def size actions.size end |
#sources ⇒ Array<String>
Returns unique sources.
112 113 114 |
# File 'lib/sashite/pmn/move.rb', line 112 def sources actions.map(&:source).uniq end |
#to_a ⇒ Array<String>
Returns copy of original PMN elements (empty array for pass moves).
134 135 136 |
# File 'lib/sashite/pmn/move.rb', line 134 def to_a pmn_array.dup end |
#valid? ⇒ Boolean
Returns true if PMN length is valid and all actions are valid.
50 51 52 53 54 |
# File 'lib/sashite/pmn/move.rb', line 50 def valid? valid_length? && actions.all?(&:valid?) rescue ::StandardError false end |
#with_actions(actions_to_add) ⇒ Move
Returns new Move with appended actions.
167 168 169 170 |
# File 'lib/sashite/pmn/move.rb', line 167 def with_actions(actions_to_add) combined = pmn_array + actions_to_add.flat_map(&:to_a) self.class.new(*combined) end |