Skip to content

Commit

Permalink
refactor: ask move to tell the board what operation to perform
Browse files Browse the repository at this point in the history
the idea is, that castling and en passant can return the
special operation they need, like capturing a piece on
another position and castling actually moving two
pieces. maybe should actually be two classes
that perform operation on the board.
  • Loading branch information
Roland Studer committed Dec 25, 2021
1 parent 7db9256 commit 05864e0
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 14 deletions.
39 changes: 28 additions & 11 deletions lib/board.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,16 @@ def legal_target_positions_for(position)
end

def move(origin, target)
origin = Position.parse(origin)
target = Position.parse(target)

origin_square = get(origin)
target_square = get(target)

piece = origin_square.piece
piece.moved = true
capture(target_square)
get(target).piece = piece
origin_square.piece = nil
move_type = find_move_type(origin, target)
current_move = move_type.new(self, origin, target)
current_move.operations_on_board.each do |operation|
case operation[:type]
when :capture
capture(get(operation[:target]))
when :move
move_operation(operation[:origin], operation[:target])
end
end
end

def squares_occupied_by(color)
Expand Down Expand Up @@ -81,6 +80,16 @@ def capture(target_square)
target_square.piece = nil
end

def move_operation(origin, target)
origin_square = get(origin)
target_square = get(target)

piece = origin_square.piece
piece.moved = true
target_square.piece = piece
origin_square.piece = nil
end

def create_squares
@squares = (1..8).map.with_index do |row, row_index|
("A".."H").map.with_index do |col, col_index|
Expand All @@ -93,4 +102,12 @@ def create_squares
def find_king(color)
@squares.find { |square| square.piece == King.new(color) }
end

def find_move_type(origin, _target)
origin = Position.parse(origin)
types = get(origin).piece.move_types
types.find do |type|
type.new(self, origin).send(:position_candidates).include?(Position.parse(origin))
end || Move::Base
end
end
12 changes: 10 additions & 2 deletions lib/move/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
module Move
# unlimited horizontal movement for a piece
class Base
attr_reader :board, :position, :piece
attr_reader :board, :position, :piece, :target

def initialize(board, position)
def initialize(board, position, target = nil)
@board = board
@position = Position.parse(position)
@target = Position.parse(target)
@piece = board.get(position).piece
end

def operations_on_board
[
{ type: :capture, target: target },
{ type: :move, origin: position, target: target }
]
end

def legal_target_positions
positions = position_candidates
positions -= target_positions_that_are_occupied_by_friend
Expand Down
7 changes: 6 additions & 1 deletion lib/position.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ def self.new(letter, number)
end

def self.parse(input)
return input.map { |pos| Position.parse(pos) } if input.is_a? Array
return nil if input.nil?
return parse_array(input) if input.is_a? Array
return input if input.is_a? Position

letter = input.strip.chars[0].upcase
Expand All @@ -30,6 +31,10 @@ def self.parse(input)
new(letter, number)
end

def self.parse_array(array)
array.map { |pos| Position.parse(pos) }
end

def initialize(letter, number)
@letter = letter
@number = number.to_i
Expand Down
5 changes: 5 additions & 0 deletions test/board_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,9 @@ def test_returns_checkmate
board = Board.from_fen("8/8/6r1/4K1r1/6q1/2b5/3R4/8 w - - 0 1")
assert board.in_checkmate?(:white)
end

def test_get_move_type
board = Board.with_setup
assert Move::Vertical, board.send(:find_move_type, "C7", "C5")
end
end

0 comments on commit 05864e0

Please sign in to comment.