Class: Board
- Inherits:
-
Object
- Object
- Board
- Defined in:
- lib/bangkok/board.rb
Instance Method Summary collapse
- #apply(move) ⇒ Object
- #apply_castle(move) ⇒ Object
- #at(square) ⇒ Object
- #empty_at?(square) ⇒ Boolean
- #find_piece(move) ⇒ Object
-
#initialize(listener) ⇒ Board
constructor
A new instance of Board.
- #remove_from_board(piece) ⇒ Object
Constructor Details
#initialize(listener) ⇒ Board
Returns a new instance of Board.
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/bangkok/board.rb', line 6 def initialize(listener) @listener = listener @pieces = [] [:R, :N, :B, :Q, :K, :B, :N, :R].each_with_index { | sym, file | @pieces << Piece.create(self, listener, :white, sym, Square.at(file, 0)) @pieces << Piece.create(self, listener, :black, sym, Square.at(file, 7)) } 8.times { | file | @pieces << Piece.create(self, listener, :white, :P, Square.at(file, 1)) @pieces << Piece.create(self, listener, :black, :P, Square.at(file, 6)) } end |
Instance Method Details
#apply(move) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/bangkok/board.rb', line 19 def apply(move) if move.castle? apply_castle(move) else piece = find_piece(move) other_piece = at(move.square) unless move.castle? piece.move_to(move.square) if other_piece # capture unless move.capture? raise "error: piece found at target (#{other_piece}) but move" + " #{move} is not a capture" end @listener.capture(piece, other_piece) remove_from_board(other_piece) end if move.pawn_promotion? raise "error: trying to promote a non-pawn" unless piece.piece == :P @listener.pawn_to_queen(piece) color = piece.color remove_from_board(piece) # will also trigger the listener @pieces << Piece.create(self, color, :Q, move.square) end end end |
#apply_castle(move) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/bangkok/board.rb', line 46 def apply_castle(move) new_king_file = nil new_rook_file = nil king = @pieces.detect { | p | p.piece == :K && p.color == move.color } rook = nil if move.queenside_castle? new_king_file = king.square.square.file - 2 rook = @pieces.detect { | p | p.piece == :R && p.color == move.color && p.square.file == 0 } new_rook_file = rook.square.file + 3 else # kingside castle new_king_file = king.square.file + 2 rook = @pieces.detect { | p | p.piece == :R && p.color == move.color && p.square.file == 7 } new_rook_file = rook.square.file - 2 end king.move_to(Square.at(new_king_file, king.square.rank)) rook.move_to(Square.at(new_rook_file, rook.square.rank)) end |
#at(square) ⇒ Object
79 80 81 |
# File 'lib/bangkok/board.rb', line 79 def at(square) return @pieces.detect { | p | p.square == square } end |
#empty_at?(square) ⇒ Boolean
75 76 77 |
# File 'lib/bangkok/board.rb', line 75 def empty_at?(square) return at(square).nil? end |
#find_piece(move) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/bangkok/board.rb', line 83 def find_piece(move) candidates = @pieces.find_all { | p | p.could_perform_move(move) } case candidates.length when 0 raise "error: no pieces found for move #{move}" when 1 return candidates[0] else # Disambiguate using move's orig. rank or file if move.from_rank_or_file.rank.nil? # file is non-nil candidates = candidates.find_all { | p | p.square.file == move.from_rank_or_file.file } else candidates = candidates.find_all { | p | p.square.rank == move.from_rank_or_file.rank } end case candidates.length when 0 raise "error: disambiguation found no pieces for #{move}" when 1 return candidates[0] else raise "error: too many pieces match #{move}" end end end |
#remove_from_board(piece) ⇒ Object
70 71 72 73 |
# File 'lib/bangkok/board.rb', line 70 def remove_from_board(piece) @pieces.delete(piece) piece.move_off_board() end |