Skip to content

Instantly share code, notes, and snippets.

@havenwood
Created January 13, 2012 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save havenwood/1605450 to your computer and use it in GitHub Desktop.
Save havenwood/1605450 to your computer and use it in GitHub Desktop.
Chess

TODO:

  • Rook, Bishop, Queen able to move multiple squares...
  • Pass en passent.
  • Promotion of pawn to piece other than Queen.
  • Castling.
  • Check, Checkmate, Draw.
require_relative 'setup-board'
require_relative 'piece-rules'
include SetupBoard
include PieceRules
include PieceDirections
class BoardAndPieceInfo
attr_accessor :from, :to, :from_column, :to_column, :from_row, :to_row, :from_piece, :from_color, :to_piece, :to_color, :destination
end
class ChessBoard
attr_reader :board
def initialize
initialize_board
initialize_pieces
@move = BoardAndPieceInfo.new
end
def move from, to
@move.from, @move.to = from.capitalize, to.capitalize
set_from_and_to_board_locations
unless @board[@move.from].nil?
set_from_color_and_piece_type
if @board[@move.to].nil?
check_board_edges
check_legality_of_move
puts "#{@move.from_color.capitalize} #{@move.from_piece.capitalize} #{@move.from} to #{@move.to}."
move_piece
promote_pawns_if_necessary
elsif @move.from_color != @board[@move.to].keys.first
set_to_color_and_piece_type
check_board_edges
check_legality_of_capture
puts "#{@move.from_color.capitalize} #{@move.from_piece.capitalize} #{@move.from} takes #{@move.to_color.capitalize} #{@move.to_piece.capitalize} #{@move.to}."
move_piece
promote_pawns_if_necessary
else
puts "You cannot capture your own peice, try again."
end
else
puts "No peice to move, try again."
end
end
private
def set_from_and_to_board_locations
@move.from_column, @move.to_column = @move.from.split('').first, @move.to.split('').first
@move.from_row, @move.to_row = @move.from.split('').last.to_i, @move.to.split('').last.to_i
end
def set_from_color_and_piece_type
@move.from_piece = @board[@move.from].values.first
@move.from_color = @board[@move.from].keys.first
end
def set_to_color_and_piece_type
@move.to_piece = @board[@move.to].values.first
@move.to_color = @board[@move.to].keys.first
end
def check_legality_of_capture
if @move.from_piece == "pawn"
pawn_capture_rules
else
check_legality_of_move
end
end
def check_board_edges
unless ("A".."H").include? @move.to_column
raise "Stay on the board, between A and H. (You chose '*#{@move.to}')"
end
unless (1..8).include? @move.to_row
raise "Stay on the board, between 1 and 8. (You chose '#{@move.to}*'.)"
end
end
def move_piece
@move.destination = @move.to
@board[@move.to] = @board[@move.from]
@board[@move.from] = nil
end
def white_pawn_promotion_due
@move.from_piece = "pawn" && @move.from_color == :white && @move.to_row == 8
end
def black_pawn_promotion_due
@move.from_piece = "pawn" && @move.from_color == :black && @move.to_row == 1
end
def promote_pawns_if_necessary
if white_pawn_promotion_due
@board["#{@move.destination}"] = { white: "queen" }
puts "Pawn promoted to Queen."
elsif black_pawn_promotion_due
@board["#{@move.destination}"] = { black: "queen" }
puts "Pawn promoted to Queen."
end
end
end
module PieceRules
private
def check_legality_of_move
case @move.from_piece
when "pawn"
case @move.from_color
when :white
unless pawn_move_white
fail "Pawns cannot move like that"
end
when :black
unless pawn_move_black
fail "Pawns cannot move like that."
end
end
when "rook"
unless rook_move
fail "Rooks cannot move like that"
end
when "knight"
unless knight_move
fail "Knights cannot move like that."
end
when "bishop"
unless bishop_move
fail "Bishops cannot move like that."
end
when "queen"
unless queen_move
fail "The Queen cannot move like that."
end
when "king"
unless king_move
fail "The King cannot move like that."
end
end
end
def pawn_capture_rules
case @move.from_color
when :white
unless capture_direction_pawn_white && one_column_over
fail "Pawns cannot capture like that."
end
when :black
unless capture_direction_pawn_black && one_column_over
fail "Pawns cannot capture like that."
end
end
end
def pawn_move_white
same_column && (advance_one_row_white || opening_pawn_white) #TODO: Pass en passent. (Must know if prev player just did a double-move-pawn-opening.)
end
def pawn_move_black
same_column && (advance_one_row_black || opening_pawn_black) #TODO: Pass en passent.
end
def knight_move
(one_row_over && two_columns_over) || (one_column_over && two_rows_over)
end
def bishop_move
angular_move #TODO: Move multiple spaces. (Clipping.)
end
def rook_move
sideways_move #TODO: Move multiple spaces.
end
def king_move
one_angular_move || one_sideways_move #TODO: Castling. (Requires checking for King passing through check.) Check. Checkmate. Draw.
end
def queen_move
angular_move || sideways_move #TODO: Move multiple spaces.
end
end
module PieceDirections
def one_angular_move
one_column_over && one_row_over
end
def one_sideways_move
(one_row_over && same_column) || (one_column_over && same_row)
end
def same_column
@move.from_column == @move.to_column
end
def same_row
@move.from_row == @move.to_row
end
def one_row_over
@move.from_row == @move.to_row.next || @move.from_row == @move.to_row.pred
end
def two_rows_over
@move.from_row == @move.to_row.next.next || @move.from_row == @move.to_row.pred.pred
end
def one_column_over
@move.from_column == @move.to_column.next || @move.from_column.next == @move.to_column
end
def two_columns_over
@move.from_column == @move.to_column.next.next || @move.from_column.next.next == @move.to_column
end
def sideways_move
(one_row_over && same_column) || (one_column_over && same_row)
end
def angular_move
one_column_over && one_row_over
end
def advance_one_row_white
@move.from_row == @move.to_row.pred
end
def advance_one_row_black
@move.from_row == @move.to_row.next
end
def capture_direction_pawn_white
@move.from_row == @move.to_row.pred
end
def capture_direction_pawn_black
@move.from_row == @move.to_row.next
end
def opening_pawn_black
@move.from_row == 7 && @move.to_row == 5 if @board["#{@move.from_column}6"].nil?
end
def opening_pawn_white
(@move.from_row == 2 && @move.to_row == 4) if @board["#{@move.from_column}3"].nil?
end
end
module SetupBoard
def initialize_board
@board = {}
("A".."H").each { |letter| (1..8).each { |number| @board["#{letter}#{number}"] = nil } }
end
def initialize_pieces
pawns
rooks
bishops
knights
queens
kings
end
def pawns
@board.each_key { |space| @board[space] = { white: "pawn" } if space.include?("2") }
@board.each_key { |space| @board[space] = { black: "pawn" } if space.include?("7") }
end
def rooks
@board["H1"] = @board["A1"] = { white: "rook" }
@board["H8"] = @board["A8"] = { black: "rook" }
end
def bishops
@board["F1"] = @board["C1"] = { white: "bishop" }
@board["F8"] = @board["C8"] = { black: "bishop" }
end
def knights
@board["G1"] = @board["B1"] = { white: "knight" }
@board["G8"] = @board["B8"] = { black: "knight" }
end
def queens
@board["E1"] = { white: "queen" }
@board["E8"] = { black: "queen" }
end
def kings
@board["D1"] = { white: "king" }
@board["D8"] = { black: "king" }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment