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 one or more atomic actions described by a flat list of elements. Every 2 or 3 consecutive elements form an action:
[source, destination] # inferred piece
[source, destination, piece] # explicit QPI piece
Valid lengths: multiple of 3 OR multiple of 3 + 2 (minimum 2).
Instance Attribute Summary collapse
-
#actions ⇒ Array<Action>
readonly
Ordered sequence of actions.
-
#pmn_array ⇒ Array<String>
readonly
Original PMN elements (frozen).
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.
- #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?
-
#pieces ⇒ Array<String>
Unique specified pieces (excludes inferred).
-
#simple? ⇒ Boolean
Exactly one action?.
-
#size ⇒ Integer
(also: #length)
Number of actions.
-
#sources ⇒ Array<String>
Unique sources.
-
#to_a ⇒ Array<String>
Copy of original PMN elements.
-
#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).
31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/sashite/pmn/move.rb', line 31 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 InvalidMoveError, '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.
18 19 20 |
# File 'lib/sashite/pmn/move.rb', line 18 def actions @actions end |
#pmn_array ⇒ Array<String> (readonly)
Returns original PMN elements (frozen).
21 22 23 |
# File 'lib/sashite/pmn/move.rb', line 21 def pmn_array @pmn_array end |
Class Method Details
.from_actions(actions) ⇒ Move
Build a move from Action objects.
163 164 165 166 |
# File 'lib/sashite/pmn/move.rb', line 163 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.
133 134 135 136 137 |
# File 'lib/sashite/pmn/move.rb', line 133 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.
98 99 100 |
# File 'lib/sashite/pmn/move.rb', line 98 def board_moves actions.select(&:board_to_board?) end |
#compound? ⇒ Boolean
Returns multiple actions?.
60 61 62 |
# File 'lib/sashite/pmn/move.rb', line 60 def compound? actions.size > 1 end |
#destinations ⇒ Array<String>
Returns unique destinations.
108 109 110 |
# File 'lib/sashite/pmn/move.rb', line 108 def destinations actions.map(&:destination).uniq end |
#empty? ⇒ Boolean
Returns true if no actions.
81 82 83 |
# File 'lib/sashite/pmn/move.rb', line 81 def empty? actions.empty? end |
#first_action ⇒ Action?
65 66 67 |
# File 'lib/sashite/pmn/move.rb', line 65 def first_action actions.first end |
#has_captures? ⇒ Boolean
Returns any capture?.
93 94 95 |
# File 'lib/sashite/pmn/move.rb', line 93 def has_captures? actions.any?(&:capture?) end |
#has_drops? ⇒ Boolean
Returns any drop?.
88 89 90 |
# File 'lib/sashite/pmn/move.rb', line 88 def has_drops? actions.any?(&:drop?) end |
#has_inferred? ⇒ Boolean
Returns true if any action has inferred piece.
118 119 120 |
# File 'lib/sashite/pmn/move.rb', line 118 def has_inferred? actions.any?(&:inferred?) end |
#hash ⇒ Integer
141 142 143 |
# File 'lib/sashite/pmn/move.rb', line 141 def hash pmn_array.hash end |
#inspect ⇒ String
146 147 148 |
# File 'lib/sashite/pmn/move.rb', line 146 def inspect "#<#{self.class.name} actions=#{actions.size} pmn=#{pmn_array.inspect}>" end |
#last_action ⇒ Action?
70 71 72 |
# File 'lib/sashite/pmn/move.rb', line 70 def last_action actions.last end |
#pieces ⇒ Array<String>
Returns unique specified pieces (excludes inferred).
113 114 115 |
# File 'lib/sashite/pmn/move.rb', line 113 def pieces actions.filter_map(&:piece).uniq end |
#simple? ⇒ Boolean
Returns exactly one action?.
55 56 57 |
# File 'lib/sashite/pmn/move.rb', line 55 def simple? actions.size == 1 end |
#size ⇒ Integer Also known as: length
Returns number of actions.
75 76 77 |
# File 'lib/sashite/pmn/move.rb', line 75 def size actions.size end |
#sources ⇒ Array<String>
Returns unique sources.
103 104 105 |
# File 'lib/sashite/pmn/move.rb', line 103 def sources actions.map(&:source).uniq end |
#to_a ⇒ Array<String>
Returns copy of original PMN elements.
125 126 127 |
# File 'lib/sashite/pmn/move.rb', line 125 def to_a pmn_array.dup end |
#valid? ⇒ Boolean
Returns true if PMN length is valid and all actions are valid.
46 47 48 49 50 |
# File 'lib/sashite/pmn/move.rb', line 46 def valid? valid_length? && actions.all?(&:valid?) rescue StandardError false end |
#with_actions(actions_to_add) ⇒ Move
Returns new Move with appended actions.
154 155 156 157 |
# File 'lib/sashite/pmn/move.rb', line 154 def with_actions(actions_to_add) combined = pmn_array + actions_to_add.flat_map(&:to_a) self.class.new(*combined) end |