Class: Sashite::Pmn::Move

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*pmn_elements) ⇒ Move

Create a Move from PMN elements (variadic only).

Examples:

Move.new("e2","e4","C:P")
Move.new("e2","e4")

Parameters:

  • pmn_elements (Array<String>)

    passed as individual args

Raises:



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

#actionsArray<Action> (readonly)

Returns ordered sequence of actions.

Returns:

  • (Array<Action>)

    ordered sequence of actions



18
19
20
# File 'lib/sashite/pmn/move.rb', line 18

def actions
  @actions
end

#pmn_arrayArray<String> (readonly)

Returns original PMN elements (frozen).

Returns:

  • (Array<String>)

    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.

Parameters:

Returns:



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.

Parameters:

  • other (Object)

Returns:

  • (Boolean)

    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_movesArray<Action>

Returns only board-to-board actions.

Returns:

  • (Array<Action>)

    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?.

Returns:

  • (Boolean)

    multiple actions?



60
61
62
# File 'lib/sashite/pmn/move.rb', line 60

def compound?
  actions.size > 1
end

#destinationsArray<String>

Returns unique destinations.

Returns:

  • (Array<String>)

    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.

Returns:

  • (Boolean)

    true if no actions



81
82
83
# File 'lib/sashite/pmn/move.rb', line 81

def empty?
  actions.empty?
end

#first_actionAction?

Returns:



65
66
67
# File 'lib/sashite/pmn/move.rb', line 65

def first_action
  actions.first
end

#has_captures?Boolean

Returns any capture?.

Returns:

  • (Boolean)

    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?.

Returns:

  • (Boolean)

    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.

Returns:

  • (Boolean)

    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

#hashInteger

Returns:

  • (Integer)


141
142
143
# File 'lib/sashite/pmn/move.rb', line 141

def hash
  pmn_array.hash
end

#inspectString

Returns:

  • (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_actionAction?

Returns:



70
71
72
# File 'lib/sashite/pmn/move.rb', line 70

def last_action
  actions.last
end

#piecesArray<String>

Returns unique specified pieces (excludes inferred).

Returns:

  • (Array<String>)

    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?.

Returns:

  • (Boolean)

    exactly one action?



55
56
57
# File 'lib/sashite/pmn/move.rb', line 55

def simple?
  actions.size == 1
end

#sizeInteger Also known as: length

Returns number of actions.

Returns:

  • (Integer)

    number of actions



75
76
77
# File 'lib/sashite/pmn/move.rb', line 75

def size
  actions.size
end

#sourcesArray<String>

Returns unique sources.

Returns:

  • (Array<String>)

    unique sources



103
104
105
# File 'lib/sashite/pmn/move.rb', line 103

def sources
  actions.map(&:source).uniq
end

#to_aArray<String>

Returns copy of original PMN elements.

Returns:

  • (Array<String>)

    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.

Returns:

  • (Boolean)

    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.

Parameters:

  • actions_to_add (Array<Action>)

    actions to append

Returns:

  • (Move)

    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