class Tak::PTN

Constants

KTN_MOVEMENT
KTN_PLACEMENT
KTN_SPECIAL_TO_PTN
NOTATION_REGEX
PTN_LEFT
PTN_NORTH
PTN_RIGHT
PTN_SOUTH

Attributes

direction[R]
errors[R]
ptn_match[R]
special_piece[R]

Public Class Methods

from_ktn(move) click to toggle source
# 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
new(notation, board_size = 5) click to toggle source
# 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

Public Instance Methods

above_handsize?() click to toggle source
# File lib/tak/ptn.rb, line 90
def above_handsize?
  stack_total > @board_size || @number.to_i > @board_size
end
alpha_range() click to toggle source
# 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?() click to toggle source
# 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) click to toggle source
# File lib/tak/ptn.rb, line 73
def error(msg)
  @errors << msg
end
movement_and_placement?() click to toggle source

Placement of a special piece (Capstone or Standing) cannot also be a move

# File lib/tak/ptn.rb, line 78
def movement_and_placement?
  !!(@special_piece && @number || @direction || @stack)
end
out_of_bounds?() click to toggle source
# File lib/tak/ptn.rb, line 94
def out_of_bounds?
  x > @board_size || y.to_i > @board_size
end
over_stack?() click to toggle source
# File lib/tak/ptn.rb, line 82
def over_stack?
  stack_total > @number.to_i
end
position() click to toggle source
# File lib/tak/ptn.rb, line 53
def position
  [x, y]
end
size() click to toggle source
# File lib/tak/ptn.rb, line 69
def size
  stack_total
end
stack_total() click to toggle source
# File lib/tak/ptn.rb, line 65
def stack_total
  @stack_total ||= @stack ? @stack.chars.sum(&:to_i) : 0
end
to_s() click to toggle source
# File lib/tak/ptn.rb, line 45
def to_s
  "#{@number}#{@special_piece}#{@position}#{@direction}#{@stack}"
end
type() click to toggle source
# File lib/tak/ptn.rb, line 49
def type
  @direction ? 'movement' : 'placement'
end
under_stack?() click to toggle source
# File lib/tak/ptn.rb, line 86
def under_stack?
  stack_total < @number.to_i
end
valid?() click to toggle source
# 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() click to toggle source
# File lib/tak/ptn.rb, line 61
def x
  @position.chars.last.to_i - 1
end
y() click to toggle source
# File lib/tak/ptn.rb, line 57
def y
  alpha_range[@position.chars.first] - 1
end