Class: Tak::PTN
- Inherits:
-
Object
- Object
- Tak::PTN
- Defined in:
- lib/tak/ptn.rb
Constant Summary collapse
- NOTATION_REGEX =
/ (?<number>\d+)? (?<special_piece>[CS])? (?<position>[a-h][1-8]) ( (?<direction>[<>+-]) (?<stack>\d+)? )? /xi
- KTN_SPECIAL_TO_PTN =
{ 'C' => 'C', 'W' => 'S', nil => '' }
- KTN_PLACEMENT =
'P'
- KTN_MOVEMENT =
'M'
- PTN_NORTH =
'+'
- PTN_SOUTH =
'-'
- PTN_RIGHT =
'>'
- PTN_LEFT =
'<'
Instance Attribute Summary collapse
-
#direction ⇒ Object
readonly
Returns the value of attribute direction.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#ptn_match ⇒ Object
readonly
Returns the value of attribute ptn_match.
-
#special_piece ⇒ Object
readonly
Returns the value of attribute special_piece.
Class Method Summary collapse
Instance Method Summary collapse
- #above_handsize? ⇒ Boolean
- #alpha_range ⇒ Object
- #distrubutes_out_of_bounds? ⇒ Boolean
- #error(msg) ⇒ Object
-
#initialize(notation, board_size = 5) ⇒ PTN
constructor
A new instance of PTN.
-
#movement_and_placement? ⇒ Boolean
Placement of a special piece (Capstone or Standing) cannot also be a move.
- #out_of_bounds? ⇒ Boolean
- #over_stack? ⇒ Boolean
- #position ⇒ Object
- #size ⇒ Object
- #stack_total ⇒ Object
- #to_s ⇒ Object
- #type ⇒ Object
- #under_stack? ⇒ Boolean
- #valid? ⇒ Boolean
- #x ⇒ Object
- #y ⇒ Object
Constructor Details
#initialize(notation, board_size = 5) ⇒ PTN
Returns a new instance of PTN.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/tak/ptn.rb', line 29 def initialize(notation, board_size = 5) @ptn_match = NOTATION_REGEX.match(notation) @board_size = board_size @notation = notation if @ptn_match @number = @ptn_match[:number] @special_piece = @ptn_match[:special_piece] @position = @ptn_match[:position] @direction = @ptn_match[:direction] @stack = @ptn_match[:stack] end @errors = [] end |
Instance Attribute Details
#direction ⇒ Object (readonly)
Returns the value of attribute direction.
27 28 29 |
# File 'lib/tak/ptn.rb', line 27 def direction @direction end |
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
27 28 29 |
# File 'lib/tak/ptn.rb', line 27 def errors @errors end |
#ptn_match ⇒ Object (readonly)
Returns the value of attribute ptn_match.
27 28 29 |
# File 'lib/tak/ptn.rb', line 27 def ptn_match @ptn_match end |
#special_piece ⇒ Object (readonly)
Returns the value of attribute special_piece.
27 28 29 |
# File 'lib/tak/ptn.rb', line 27 def special_piece @special_piece end |
Class Method Details
.from_ktn(move) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/tak/ptn.rb', line 123 def self.from_ktn(move) move_type, *remainder = move.split(' ') ptn_string = case move_type when KTN_PLACEMENT square, special_piece = remainder stone = KTN_SPECIAL_TO_PTN[special_piece] "#{stone}#{square.downcase}" when KTN_MOVEMENT from_square, to_square, *distribution = remainder from_square_col, from_square_row = from_square.chars to_square_col, to_square_row = to_square.chars direction = if from_square_col == to_square_col to_square_row > from_square_row ? PTN_NORTH : PTN_SOUTH else to_square_col > from_square_col ? PTN_RIGHT : PTN_LEFT end hand_size = distribution.map(&:to_i).sum "#{hand_size}#{from_square.downcase}#{direction}#{distribution.join}" else '' end new(ptn_string) end |
Instance Method Details
#above_handsize? ⇒ Boolean
90 91 92 |
# File 'lib/tak/ptn.rb', line 90 def above_handsize? stack_total > @board_size || @number.to_i > @board_size end |
#alpha_range ⇒ Object
119 120 121 |
# File 'lib/tak/ptn.rb', line 119 def alpha_range @alpha_range ||= ('a'..'h').each.with_index(1).zip.flatten(1).to_h end |
#distrubutes_out_of_bounds? ⇒ Boolean
98 99 100 101 |
# File 'lib/tak/ptn.rb', line 98 def distrubutes_out_of_bounds? x + stack_total > @board_size || y.to_i + stack_total > @board_size end |
#error(msg) ⇒ Object
73 74 75 |
# File 'lib/tak/ptn.rb', line 73 def error(msg) @errors << msg end |
#movement_and_placement? ⇒ Boolean
Placement of a special piece (Capstone or Standing) cannot also be a move
78 79 80 |
# File 'lib/tak/ptn.rb', line 78 def movement_and_placement? !!(@special_piece && @number || @direction || @stack) end |
#out_of_bounds? ⇒ Boolean
94 95 96 |
# File 'lib/tak/ptn.rb', line 94 def out_of_bounds? x > @board_size || y.to_i > @board_size end |
#over_stack? ⇒ Boolean
82 83 84 |
# File 'lib/tak/ptn.rb', line 82 def over_stack? stack_total > @number.to_i end |
#position ⇒ Object
53 54 55 |
# File 'lib/tak/ptn.rb', line 53 def position [x, y] end |
#size ⇒ Object
69 70 71 |
# File 'lib/tak/ptn.rb', line 69 def size stack_total end |
#stack_total ⇒ Object
65 66 67 |
# File 'lib/tak/ptn.rb', line 65 def stack_total @stack_total ||= @stack ? @stack.chars.sum(&:to_i) : 0 end |
#to_s ⇒ Object
45 46 47 |
# File 'lib/tak/ptn.rb', line 45 def to_s "#{@number}#{@special_piece}#{@position}#{@direction}#{@stack}" end |
#type ⇒ Object
49 50 51 |
# File 'lib/tak/ptn.rb', line 49 def type @direction ? 'movement' : 'placement' end |
#under_stack? ⇒ Boolean
86 87 88 |
# File 'lib/tak/ptn.rb', line 86 def under_stack? stack_total < @number.to_i end |
#valid? ⇒ Boolean
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/tak/ptn.rb', line 103 def valid? @valid ||= begin # Break before we do anything else here. error 'Did not match PTN Format' and return false unless @ptn_match error 'Cannot move more pieces than the board size!' if above_handsize? error 'Cannot distribute more pieces than were picked up' if over_stack? error 'Cannot distribute less pieces than were picked up' if under_stack? error 'Cannot move and place a piece' if movement_and_placement? error 'Cannot place or move a piece out of bounds' if out_of_bounds? error 'Cannot distribute pieces out of bounds' if distrubutes_out_of_bounds? @errors.none? end end |
#x ⇒ Object
61 62 63 |
# File 'lib/tak/ptn.rb', line 61 def x @position.chars.last.to_i - 1 end |
#y ⇒ Object
57 58 59 |
# File 'lib/tak/ptn.rb', line 57 def y alpha_range[@position.chars.first] - 1 end |