Class: JustChess::SquareSet
- Inherits:
-
Object
- Object
- JustChess::SquareSet
- Extended by:
- Forwardable
- Defined in:
- lib/just_chess/square_set.rb
Overview
Square Set
A collection of Squares with useful filtering functions
Instance Attribute Summary collapse
-
#squares ⇒ Array<Square>
readonly
The squares in the set.
Instance Method Summary collapse
-
#&(other) ⇒ SquareSet
Find the intersection of Squares between sets.
-
#+(other) ⇒ SquareSet
Concat two SquareSets together.
-
#-(other) ⇒ SquareSet
Remove squares from one SquareSet from another.
-
#<<(square) ⇒ SquareSet
Push a Square onto a SquareSet.
-
#as_json ⇒ Hash
serializes the squares as a hash.
-
#at_range(square, distance) ⇒ SquareSet
Find all squares at distance of square.
-
#between(a, b) ⇒ SquareSet
Returns squares between a and b.
-
#diagonal(square) ⇒ SquareSet
Find all squares diagonal from square.
-
#excluding_piece(piece_type) ⇒ SquareSet
Find all squares occupied by a piece not of a particular type.
-
#find_by_id(id) ⇒ Square
Find the square with the matching unique identifier.
-
#find_by_piece_id(piece_id) ⇒ Square
Find the square with the matching piece identifier.
-
#find_by_x_and_y(x, y) ⇒ Square
Find the square with the matching x and y co-ordinates.
-
#find_king_for_player(player_number) ⇒ Square
Find the square occupied by the player’s king.
-
#in_direction(square, direction_y) ⇒ SquareSet
Find all squares in the y direction of square.
-
#in_range(square, distance) ⇒ SquareSet
Find all squares within distance of square.
-
#initialize(squares:) ⇒ SquareSet
constructor
New objects can be instantiated by passing in a hash with squares.
-
#not_orthogonal_or_diagonal(square) ⇒ SquareSet
Find all squares not orthogonal or diagonal from square.
-
#occupied_by_opponent(player_number) ⇒ SquareSet
Takes a player number and returns all squares occupied by the opponent of the player.
-
#occupied_by_piece(piece_type) ⇒ SquareSet
Find all squares occupied by a piece of a particular type.
-
#occupied_by_player(player_number) ⇒ SquareSet
Takes a player number and returns all squares occupied by the player.
-
#orthogonal(square) ⇒ SquareSet
Find all squares orthogonal from square.
-
#orthogonal_or_diagonal(square) ⇒ SquareSet
Find all squares orthogonal or diagonal from square.
-
#select(&block) ⇒ SquareSet
Filter the squares with a block and behaves like Enumerable#select.
-
#threatened_by(player_number, game_state) ⇒ SquareSet
Returns all squares threatened by the specified player.
-
#unblocked(origin, square_set) ⇒ SquareSet
Returns destination from the origin that have a clear path.
-
#unmoved ⇒ SquareSet
Returns all squares with pieces that haven’t moved.
-
#unoccupied ⇒ SquareSet
Find all squares without pieces on them.
-
#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.
Constructor Details
#initialize(squares:) ⇒ SquareSet
25 26 27 28 29 30 31 32 33 |
# File 'lib/just_chess/square_set.rb', line 25 def initialize(squares: ) @squares = if squares.all? { |s| s.instance_of?(Hash) } squares.map { |s| Square.new(s) } elsif squares.all? { |s| s.instance_of?(Square) } squares else raise ArgumentError, "all squares must have the same class" end end |
Instance Attribute Details
#squares ⇒ Array<Square> (readonly)
Returns The squares in the set.
36 37 38 |
# File 'lib/just_chess/square_set.rb', line 36 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
101 102 103 |
# File 'lib/just_chess/square_set.rb', line 101 def &(other) select { |square| other.include?(square) } end |
#+(other) ⇒ SquareSet
Concat two SquareSets together
Example:
# Concat two SquareSets together
square_set + other
56 57 58 59 60 |
# File 'lib/just_chess/square_set.rb', line 56 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
71 72 73 74 75 |
# File 'lib/just_chess/square_set.rb', line 71 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
86 87 88 89 90 |
# File 'lib/just_chess/square_set.rb', line 86 def <<(square) _squares = squares << square self.class.new(squares: _squares) end |
#as_json ⇒ Hash
serializes the squares as a hash
403 404 405 |
# File 'lib/just_chess/square_set.rb', line 403 def as_json squares.map(&:as_json) end |
#at_range(square, 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)
234 235 236 |
# File 'lib/just_chess/square_set.rb', line 234 def at_range(square, distance) select { |s| Vector.new(square, s).magnitude.abs == distance } end |
#between(a, b) ⇒ 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)
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/just_chess/square_set.rb', line 184 def between(a, b) vector = Vector.new(a, b) if vector.diagonal? || vector.orthogonal? point_counter = a.point direction = vector.direction _squares = [] while point_counter != b.point point_counter = point_counter + direction square = find_by_x_and_y(point_counter.x, point_counter.y) if square && square.point != b.point _squares.push(square) end end else _squares = [] end self.class.new(squares: _squares) end |
#diagonal(square) ⇒ SquareSet
Find all squares diagonal from square
Example:
# Get all squares diagonal from square_a
square_set.diagonal(square_a)
276 277 278 |
# File 'lib/just_chess/square_set.rb', line 276 def diagonal(square) select { |s| Vector.new(square, s).diagonal? } end |
#excluding_piece(piece_type) ⇒ SquareSet
Find all squares occupied by a piece not of a particular type
359 360 361 |
# File 'lib/just_chess/square_set.rb', line 359 def excluding_piece(piece_type) select { |s| s.piece && !s.piece.is_a?(piece_type) } 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)
124 125 126 |
# File 'lib/just_chess/square_set.rb', line 124 def find_by_id(id) find { |s| s.id == id } end |
#find_by_piece_id(piece_id) ⇒ Square
Find the square with the matching piece identifier
Example:
# Find the square with a piece of id 4
square_set.find_by_piece_id(4)
153 154 155 |
# File 'lib/just_chess/square_set.rb', line 153 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)
140 141 142 |
# File 'lib/just_chess/square_set.rb', line 140 def find_by_x_and_y(x, y) find { |s| s.x == x && s.y == y } end |
#find_king_for_player(player_number) ⇒ Square
Find the square occupied by the player’s king
Example:
# Find the square occupied by player 2's king
square_set.find_king_for_player(2)
166 167 168 |
# File 'lib/just_chess/square_set.rb', line 166 def find_king_for_player(player_number) find { |s| s.piece && s.piece.is_a?(JustChess::King) && s.occupied_by_player?(player_number) } 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)
250 251 252 |
# File 'lib/just_chess/square_set.rb', line 250 def in_direction(square, direction_y) select { |s| Vector.new(square, s).direction.y == direction_y } end |
#in_range(square, 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)
218 219 220 |
# File 'lib/just_chess/square_set.rb', line 218 def in_range(square, distance) select { |s| Vector.new(square, s).magnitude.abs <= distance } end |
#not_orthogonal_or_diagonal(square) ⇒ 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)
302 303 304 |
# File 'lib/just_chess/square_set.rb', line 302 def not_orthogonal_or_diagonal(square) select { |s| Vector.new(square, s).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
329 330 331 |
# File 'lib/just_chess/square_set.rb', line 329 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
349 350 351 |
# File 'lib/just_chess/square_set.rb', line 349 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
319 320 321 |
# File 'lib/just_chess/square_set.rb', line 319 def occupied_by_player(player_number) select { |s| s.occupied_by_player?(player_number) } end |
#orthogonal(square) ⇒ SquareSet
Find all squares orthogonal from square
Example:
# Get all squares orthogonal from square_a
square_set.orthogonal(square_a)
263 264 265 |
# File 'lib/just_chess/square_set.rb', line 263 def orthogonal(square) select { |s| Vector.new(square, s).orthogonal? } end |
#orthogonal_or_diagonal(square) ⇒ 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)
289 290 291 |
# File 'lib/just_chess/square_set.rb', line 289 def orthogonal_or_diagonal(square) select { |s| Vector.new(square, s).orthogonal_or_diagonal? } end |
#select(&block) ⇒ SquareSet
Filter the squares with a block and behaves like Enumerable#select. It returns a SquareSet with the filtered squares.
109 110 111 112 113 |
# File 'lib/just_chess/square_set.rb', line 109 def select(&block) _squares = squares.select(&block) self.class.new(squares: _squares) end |
#threatened_by(player_number, game_state) ⇒ SquareSet
Returns all squares threatened by the specified player
392 393 394 395 396 397 398 |
# File 'lib/just_chess/square_set.rb', line 392 def threatened_by(player_number, game_state) _squares = occupied_by_player(player_number).map do |s| s.piece.capture_squares(s, game_state).squares end.flatten.uniq self.class.new(squares: _squares) end |
#unblocked(origin, square_set) ⇒ SquareSet
Returns destination from the origin that have a clear path
372 373 374 |
# File 'lib/just_chess/square_set.rb', line 372 def unblocked(origin, square_set) select { |destination| square_set.between(origin, destination).all?(&:unoccupied?) } end |
#unmoved ⇒ SquareSet
Returns all squares with pieces that haven’t moved
379 380 381 |
# File 'lib/just_chess/square_set.rb', line 379 def unmoved select { |s| s.piece && s.piece.has_not_moved? } end |
#unoccupied ⇒ SquareSet
Find all squares without pieces on them.
309 310 311 |
# File 'lib/just_chess/square_set.rb', line 309 def unoccupied select { |s| s.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
339 340 341 |
# File 'lib/just_chess/square_set.rb', line 339 def unoccupied_or_occupied_by_opponent(player_number) select { |s| s.unoccupied? || s.occupied_by_opponent?(player_number) } end |