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:



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/board_game_grid/square_set.rb', line 454

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:



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

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:



416
417
418
# File 'lib/board_game_grid/square_set.rb', line 416

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:



366
367
368
# File 'lib/board_game_grid/square_set.rb', line 366

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:



386
387
388
# File 'lib/board_game_grid/square_set.rb', line 386

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:



406
407
408
# File 'lib/board_game_grid/square_set.rb', line 406

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:



376
377
378
# File 'lib/board_game_grid/square_set.rb', line 376

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:



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

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:



353
354
355
# File 'lib/board_game_grid/square_set.rb', line 353

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

#same_file(origin) ⇒ SquareSet

Find all squares in the same file as square

Example:

# Get all squares in the same file as square_a
square_set.same_file(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



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

def same_file(origin)
  select { |square| square.x == origin.x }
end

#same_rank(origin) ⇒ SquareSet

Find all squares in the same rank as square

Example:

# Get all squares in the same rank as square_a
square_set.same_rank(square_a)

Parameters:

  • square (Square)

    the originating square

Returns:



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

def same_rank(origin)
  select { |square| square.y == origin.y }
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:



436
437
438
# File 'lib/board_game_grid/square_set.rb', line 436

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:



423
424
425
# File 'lib/board_game_grid/square_set.rb', line 423

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:



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

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