Skip to content

Instantly share code, notes, and snippets.

@Martin-Alexander
Last active August 1, 2019 01:49
Show Gist options
  • Save Martin-Alexander/e83c7a9b713df74c93b72ccecfb291a5 to your computer and use it in GitHub Desktop.
Save Martin-Alexander/e83c7a9b713df74c93b72ccecfb291a5 to your computer and use it in GitHub Desktop.
in_check.rb
def in_check?(input_string)
board = format_input_string(input_string)
king_coords = king_location(board)
king_x = king_coords[:x]
king_y = king_coords[:y]
# Pawns
return true if piece_at_coords(board, relative_coords(king_coords, { x: 1, y: -1 })) == "P"
return true if piece_at_coords(board, relative_coords(king_coords, { x: 1, y: 1 })) == "P"
# Rook South
((king_y + 1)..7).each do |row|
piece = piece_at_coords(board, { x: king_x, y: row })
if piece == "R" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Rook North
(0..(king_y - 1)).each do |row|
piece = piece_at_coords(board, { x: king_x, y: row })
if piece == "R" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Rook East
((king_x + 1)..7).each do |column|
piece = piece_at_coords(board, { x: column, y: king_y })
if piece == "R" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Rook West
(0..(king_x - 1)).each do |column|
piece = piece_at_coords(board, { x: column, y: king_y })
if piece == "R" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Bishop Northeast
distance_to_east_edge = 7 - king_coords[:x]
distance_to_north_edge = king_coords[:y]
diagonal_distance_to_edge = [distance_to_east_edge, distance_to_north_edge].min
(1..diagonal_distance_to_edge).each do |step_number|
piece = piece_at_coords(board, { x: king_x + step_number, y: king_y - step_number })
if piece == "B" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Bishop Southeast
distance_to_east_edge = 7 - king_coords[:x]
distance_to_south_edge = 7 - king_coords[:y]
diagonal_distance_to_edge = [distance_to_east_edge, distance_to_south_edge].min
(1..diagonal_distance_to_edge).each do |step_number|
piece = piece_at_coords(board, { x: king_x + step_number, y: king_y + step_number })
if piece == "B" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Bishop Southwest
distance_to_west_edge = king_coords[:x]
distance_to_south_edge = 7 - king_coords[:y]
diagonal_distance_to_edge = [distance_to_west_edge, distance_to_south_edge].min
(1..diagonal_distance_to_edge).each do |step_number|
piece = piece_at_coords(board, { x: king_x - step_number, y: king_y + step_number })
if piece == "B" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Bishop Northwest
distance_to_west_edge = king_coords[:x]
distance_to_north_edge = king_coords[:y]
diagonal_distance_to_edge = [distance_to_west_edge, distance_to_north_edge].min
(1..diagonal_distance_to_edge).each do |step_number|
piece = piece_at_coords(board, { x: king_x - step_number, y: king_y - step_number })
if piece == "B" || piece == "Q"
return true
elsif piece != "."
break
end
end
# Knight
knight_relative_coords = [
{x: 2, y: -1},
{x: 1, y: -2},
{x: 2, y: 1},
{x: 1, y: 2},
{x: -2, y: -1},
{x: -1, y: -2},
{x: -2, y: 1},
{x: -1, y: 2},
].map { |kight_coords| relative_coords(king_coords, kight_coords) }
.reject { |coords| out_of_bounds?(coords) }
knight_relative_coords.each do |knight_coord|
return true if piece_at_coords(board, knight_coord) == "N"
end
# King is safe ;)
return false
end
def format_input_string(input_string)
input_string.gsub(/\s/, "").chars
end
def king_location(board)
index_to_coords(board.index("K"))
end
def index_to_coords(index)
{
x: index % 8,
y: index / 8
}
end
def relative_coords(coords, transform_coords)
{
x: coords[:x] + transform_coords[:x],
y: coords[:y] + transform_coords[:y]
}
end
def piece_at_coords(board, coords)
board[coords_to_index(coords)]
end
def coords_to_index(coords)
coords[:y] * 8 + coords[:x]
end
def out_of_bounds?(coords)
coords[:y] > 7 || coords[:y] < 0 || coords[:x] > 7 || coords[:x] < 0
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment