class Ugoki::Position
The position abstraction.
Attributes
The list of pieces in hand owned by players.
@!attribute [r] in_hand_owned_pieces
@return [Array] The list of pieces in hand for the current side.
The shape of the board.
@!attribute [r] shape
@return [Array] The shape of the board.
Players are identified by a number according to the order in which they traditionally play from the starting position.
@!attribute [r] side_id
@return [Integer] The identifier of the player who must play.
The index of each piece on the board.
@!attribute [r] square
@return [Hash] The index of each piece on the board.
The index of each bottom-side piece on the board.
@!attribute [r] square_bottomside_pieces
@return [Hash] The index of each bottom-side piece on the board.
The index of each top-side piece on the board.
@!attribute [r] square_topside_pieces
@return [Hash] The index of each top-side piece on the board.
Public Class Methods
Initialize a position.
@param in_hand
[Array] The list of pieces in hand. @param shape [Array] The shape of the board. @param side_id
[Integer] The identifier of the player who must play. @param square [Hash] The index of each piece on the board.
@example Dump a classic Tsume Shogi problem
new( "in_hand": [S r r b g g g g s n n n n p p p p p p p p p p p p p p p p p], "shape": [9, 9], "side_id": 0, "square": { 3 => "s", 4 => "k", 5 => "s", 22 => "+P", 43 => "+B" } )
# File lib/ugoki/position.rb, line 80 def initialize(in_hand:, shape:, side_id:, square:) @in_hand = in_hand @shape = shape @side_id = side_id @square = square @square_bottomside_pieces = square.select { |_, name| name.upcase == name } @square_topside_pieces = square.select { |_, name| name.downcase == name } @in_hand_owned_pieces = if turn_to_topside? in_hand.select { |name| name.downcase == name } else in_hand.select { |name| name.upcase == name } end end
@param feen [String] The FEEN string representing a position.
@see developer.sashite.com/specs/forsyth-edwards-expanded-notation
@return [Ugoki::Position] The state of the game.
# File lib/ugoki/position.rb, line 13 def self.parse(feen) new(**::FEEN::Parser.call(feen)) end
Public Instance Methods
@param square_patterns [Hash] A hash of integers and symbols.
@example A hash of square patterns
{ 10 => nil, 20 => nil, 30 => nil, 40 => nil, 50 => nil, 60 => nil, 70 => nil }
@return [Boolean] Is the position matching the given pattern?
# File lib/ugoki/position.rb, line 115 def match?(square_patterns) square_patterns.all? { |square_id, state| correct?(square_id, state) } end
The list of pieces on the board owned by the current player, with squares.
@return [Hash] Top-side's pieces if turn to topside, bottom-side's ones
otherwise.
# File lib/ugoki/position.rb, line 100 def square_owned_pieces turn_to_topside? ? square_topside_pieces : square_bottomside_pieces end
@return [Boolean] Is turn to top-side?
# File lib/ugoki/position.rb, line 105 def turn_to_topside? !side_id.zero? end
Protected Instance Methods
@param square_id [Integer] The square ID. @param state [Symbol] The state of the square.
@return [Boolean] Is the state of the square correct?
# File lib/ugoki/position.rb, line 125 def correct?(square_id, state) content = square_content(square_id) case state when :occupied !content.nil? when :enemy if turn_to_topside? !content.nil? && content.upcase == content else !content.nil? && content.downcase == content end else state == content end end
@param square_id [Integer] The square ID.
@return [String, nil] The square content.
# File lib/ugoki/position.rb, line 145 def square_content(square_id) square.fetch(square_id, nil) end