Class: BoardGameGrid::SquareSet

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/board_game_grid/square_set.rb

Overview

Square Set

A collection of Squares with useful filtering functions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(squares: []) ⇒ SquareSet

New objects can be instantiated by passing in a hash with squares. They can be square objects or hashes.

Example:

# Instantiates a new Square Set
BoardGameGrid::SquareSet.new({
  squares: [
    { x: 1, y: 0, piece: { player_number: 1, king: false }}
  ]
})

Parameters:

  • squares (Array<Square,Hash>) (defaults to: [])

    An array of squares, each with x and y co-ordinates and a piece.



26
27
28
29
30
31
32
33
34
# File 'lib/board_game_grid/square_set.rb', line 26

def initialize(squares: [])
  @squares = if squares.all? { |element| element.instance_of?(Hash) }
    squares.map { |args| BoardGameGrid::Square.new(**args) }
  elsif squares.all? { |element| element.instance_of?(BoardGameGrid::Square) }
    squares
  else
    raise ArgumentError, "all squares must have the same class"
  end
end

Instance Attribute Details

#squaresArray<Square> (readonly)

Returns The squares in the set.

Returns:

  • (Array<Square>)

    The squares in the set.



37
38
39
# File 'lib/board_game_grid/square_set.rb', line 37

def squares
  @squares
end

Instance Method Details

#&(other) ⇒ SquareSet

Find the intersection of Squares between sets

Example:

# Find the intersection of Squares
square_set & other

Parameters:

Returns:



111
112
113
114
115
# File 'lib/board_game_grid/square_set.rb', line 111

def &(other)
  _squares = self.squares & other.squares  

  self.class.new(squares: _squares)
end

#+(other) ⇒ SquareSet

Concat two SquareSets together

Example:

# Concat two SquareSets together
square_set + other

Parameters:

Returns:



66
67
68
69
70
# File 'lib/board_game_grid/square_set.rb', line 66

def +(other)
  _squares = squares + other.squares

  self.class.new(squares: _squares)
end

#-(other) ⇒ SquareSet

Remove squares from one SquareSet from another

Example:

# Remove squares from one SquareSet
square_set - other

Parameters:

Returns:



81
82
83
84
85
# File 'lib/board_game_grid/square_set.rb', line 81

def -(other)
  _squares = squares - other.squares

  self.class.new(squares: _squares)
end

#<<(square) ⇒ SquareSet

Push a Square onto a SquareSet

Example:

# Push a Square onto a SquareSet
square_set << square

Parameters:

  • square (Square)

    the square being pushed on

Returns:



96
97
98
99
100
# File 'lib/board_game_grid/square_set.rb', line 96

def <<(square)
  _squares = squares << square

  self.class.new(squares: _squares)
end

#as_jsonHash

serializes the squares as a hash

Returns:

  • (Hash)


53
54
55
# File 'lib/board_game_grid/square_set.rb', line 53

def as_json
  squares.map(&:as_json)
end

#at_range(origin, distance) ⇒ SquareSet

Find all squares at distance of square

Example:

# Get all squares at 2 squares from square_a
square_set.at_range(square_a, 2)

Parameters:

  • square (Square)

    the originating square

  • distance (Fixnum)

    the specified distance from the square

Returns:



255
256
257
# File 'lib/board_game_grid/square_set.rb', line 255

def at_range(origin, distance)
  select { |square| Vector.new(origin, square).magnitude == distance }
end

#between(origin, destination) ⇒ SquareSet

Returns squares between a and b. Only squares that are in the same diagonal will return squares.

Example:

# Get all squares between square_a and square_b
square_set.between(square_a, square_b)

Parameters:

Returns:



428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/board_game_grid/square_set.rb', line 428

def between(origin, destination)
  vector = Vector.new(origin, destination)

  if vector.diagonal? || vector.orthogonal?
    point_counter = origin.point
    direction = vector.direction
    _squares = []

    while point_counter != destination.point
      point_counter = point_counter + direction
      square = find_by_x_and_y(point_counter.x, point_counter.y)
      if square && square.point != destination.point
        _squares.push(square)
      end
    end
  else
    _squares = []
  end

  self.class.new(squares: _squares)
end

#diagonal(origin) ⇒ SquareSet

Find all squares diagonal from square

Example:

# Get all squares diagonal from square_a
square_set.diagonal(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



314
315
316
# File 'lib/board_game_grid/square_set.rb', line 314

def diagonal(origin)
  select { |square| Vector.new(origin, square).diagonal? }
end

#excluding_piece(piece_type) ⇒ SquareSet

Find all squares occupied by a piece not of a particular type

Parameters:

  • piece_type (Class)

    the class of the piece.

Returns:



390
391
392
# File 'lib/board_game_grid/square_set.rb', line 390

def excluding_piece(piece_type)
  select { |s| s.piece && !s.piece.is_a?(piece_type) }
end

#files_away(origin, distance) ⇒ SquareSet

Find all squares a certain number of files away

Example:

# Get all squares at 2 ranks away from square_a
square_set.files_away(square_a, 2)

Parameters:

  • origin (Square)

    the originating square

  • distance (Fixnum)

    the specified distance from the square

Returns:



288
289
290
# File 'lib/board_game_grid/square_set.rb', line 288

def files_away(origin, distance)
  select { |square| Vector.new(origin, square).dx.abs == distance }
end

#find_by_id(id) ⇒ Square

Find the square with the matching unique identifier

Example:

# Find the square with id 4
square_set.find_by_id(4)

Parameters:

  • id (Fixnum)

    the unique identifier.

Returns:



178
179
180
# File 'lib/board_game_grid/square_set.rb', line 178

def find_by_id(id)
  select { |square| square.id == id }.first
end

#find_by_piece_id(piece_id) ⇒ Square

Find the square with the matching piece identifier

example:

# Find the square with a piece with id 4
square_set.find_by_piece_id(4)

Parameters:

  • piece_id (Fixnum)

    the unique identifier of the piece.

Returns:



207
208
209
# File 'lib/board_game_grid/square_set.rb', line 207

def find_by_piece_id(piece_id)
  find { |s| s.piece && s.piece.id == piece_id }
end

#find_by_x_and_y(x, y) ⇒ Square

Find the square with the matching x and y co-ordinates

Example:

# Find the square at 4,2
square_set.find_by_x_and_y(4, 2)

Parameters:

  • x (Fixnum)

    the x co-ordinate.

  • y (Fixnum)

    the y co-ordinate.

Returns:



194
195
196
# File 'lib/board_game_grid/square_set.rb', line 194

def find_by_x_and_y(x, y)
  select { |square| square.x == x && square.y == y }.first
end

#in_direction(square, direction_y) ⇒ SquareSet

Find all squares in the y direction of square

Example:

# Get all squares up from square_a
square_set.in_direction(square_a, -1)

Parameters:

  • square (Square)

    the originating square

  • direction_y (Fixnum)

    the direction, either up (-1) or down (1)

Returns:



223
224
225
# File 'lib/board_game_grid/square_set.rb', line 223

def in_direction(square, direction_y)
  select { |s| BoardGameGrid::Vector.new(square, s).direction.y == direction_y }
end

#in_range(origin, distance) ⇒ SquareSet

Find all squares within distance of square

Example:

# Get all squares within 2 squares of square_a
square_set.in_range(square_a, 2)

Parameters:

  • square (Square)

    the originating square

  • distance (Fixnum)

    the specified distance from the square

Returns:



239
240
241
# File 'lib/board_game_grid/square_set.rb', line 239

def in_range(origin, distance)
  select { |square| Vector.new(origin, square).magnitude <= distance }
end

#not_orthogonal_or_diagonal(origin) ⇒ SquareSet

Find all squares not orthogonal or diagonal from square

Example:

# Get all squares not orthogonal or diagonal from square_a
square_set.not_orthogonal_or_diagonal(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



340
341
342
# File 'lib/board_game_grid/square_set.rb', line 340

def not_orthogonal_or_diagonal(origin)
  select { |square| Vector.new(origin, square).not_orthogonal_or_diagonal? }
end

#occupied_by_opponent(player_number) ⇒ SquareSet

Takes a player number and returns all squares occupied by the opponent of the player

Parameters:

  • player_number (Fixnum)

    the player’s number.

Returns:



360
361
362
# File 'lib/board_game_grid/square_set.rb', line 360

def occupied_by_opponent(player_number)
  select { |s| s.occupied_by_opponent?(player_number) }
end

#occupied_by_piece(piece_type) ⇒ SquareSet

Find all squares occupied by a piece of a particular type

Parameters:

  • piece_type (Class)

    the class of the piece.

Returns:



380
381
382
# File 'lib/board_game_grid/square_set.rb', line 380

def occupied_by_piece(piece_type)
  select { |s| s.piece && s.piece.is_a?(piece_type) }
end

#occupied_by_player(player_number) ⇒ SquareSet

Takes a player number and returns all squares occupied by the player

Parameters:

  • player_number (Fixnum)

    the player’s number.

Returns:



350
351
352
# File 'lib/board_game_grid/square_set.rb', line 350

def occupied_by_player(player_number)
  select { |s| s.occupied_by_player?(player_number) }
end

#orthogonal(origin) ⇒ SquareSet

Find all squares orthogonal from square

Example:

# Get all squares orthogonal from square_a
square_set.orthogonal(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



301
302
303
# File 'lib/board_game_grid/square_set.rb', line 301

def orthogonal(origin)
  select { |square| Vector.new(origin, square).orthogonal? }
end

#orthogonal_or_diagonal(origin) ⇒ SquareSet

Find all squares orthogonal or diagonal from square

Example:

# Get all squares orthogonal or diagonal from square_a
square_set.orthogonal_or_diagonal(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



327
328
329
# File 'lib/board_game_grid/square_set.rb', line 327

def orthogonal_or_diagonal(origin)
  select { |square| Vector.new(origin, square).orthogonal_or_diagonal? }
end

#ranks_away(origin, distance) ⇒ SquareSet

Find all squares a certain number of ranks away

Example:

# Get all squares at 2 ranks away from square_a
square_set.ranks_away(square_a, 2)

Parameters:

  • origin (Square)

    the originating square

  • distance (Fixnum)

    the specified distance from the square

Returns:



272
273
274
# File 'lib/board_game_grid/square_set.rb', line 272

def ranks_away(origin, distance)
  select { |square| Vector.new(origin, square).dy.abs == distance }
end

#select(&block) ⇒ SquareSet

Filter the squares with a block and behaves like Enumerable#select. It returns a SquareSet with the filtered squares.

Returns:



136
137
138
139
140
# File 'lib/board_game_grid/square_set.rb', line 136

def select(&block)
  _squares = squares.select(&block)

  self.class.new(squares: _squares)
end

#unblocked(origin, square_set) ⇒ SquareSet

Returns destination from the origin that have a clear path

Parameters:

  • origin (Square)

    the originating square.

  • square_set (SquareSet)

    the board position.

Returns:



410
411
412
# File 'lib/board_game_grid/square_set.rb', line 410

def unblocked(origin, square_set)
  select { |destination| square_set.between(origin, destination).all?(&:unoccupied?) }
end

#uniqSquareSet

Get unique elements in the set. Behaves like Enumerable#uniq. It returns a SquareSet with the unique squares.

Returns:



146
147
148
149
150
# File 'lib/board_game_grid/square_set.rb', line 146

def uniq
  _squares = squares.uniq

  self.class.new(squares: _squares)
end

#unoccupiedSquareSet

Find all squares without pieces on them.

Returns:



397
398
399
# File 'lib/board_game_grid/square_set.rb', line 397

def unoccupied
  select(&:unoccupied?)
end

#unoccupied_or_occupied_by_opponent(player_number) ⇒ SquareSet

Takes a player number and returns all squares unoccupied or occupied by the opponent of the player

Parameters:

  • player_number (Fixnum)

    the player’s number.

Returns:



370
371
372
# File 'lib/board_game_grid/square_set.rb', line 370

def unoccupied_or_occupied_by_opponent(player_number)
  select { |s| s.unoccupied? || s.occupied_by_opponent?(player_number) }
end

#where(hash) ⇒ SquareSet

Filter the squares with a hash of attribute and matching values.

Example:

# Find all squares where piece is nil
square_set.where(piece: nil)

Parameters:

  • hash (Hash)

    attributes to query for.

Returns:



162
163
164
165
166
167
# File 'lib/board_game_grid/square_set.rb', line 162

def where(hash)
  res = hash.inject(squares) do |memo, (attribute, value)|
    memo.select { |square| square.attribute_match?(attribute, value) }
  end
  self.class.new(squares: res)
end

#|(other) ⇒ SquareSet

Find the union of Squares between sets

Example:

# Find the union of Squares
square_set | other

Parameters:

Returns:



126
127
128
129
130
# File 'lib/board_game_grid/square_set.rb', line 126

def |(other)
  _squares = self.squares | other.squares  

  self.class.new(squares: _squares)
end