mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
86 lines
2.5 KiB
Elixir
86 lines
2.5 KiB
Elixir
defmodule Chess.Moves.Piece do
|
|
@moduledoc false
|
|
|
|
alias Chess.Board
|
|
alias Chess.Moves.Generator
|
|
alias Chess.Moves.Pieces.Knight
|
|
alias Chess.Moves.Pieces.Pawn
|
|
|
|
def attacked?(board, {file, rank}) do
|
|
attacked_by_rook_or_queen?(board, {file, rank}) ||
|
|
attacked_by_bishop_or_queen?(board, {file, rank}) ||
|
|
attacked_by_knight?(board, {file, rank}) ||
|
|
attacked_by_pawn?(board, {file, rank})
|
|
end
|
|
|
|
defp attacked_by_rook_or_queen?(board, {file, rank}) do
|
|
_attacked?(board, {file, rank}, {0, 1}, ["rook", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {0, -1}, ["rook", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {1, 0}, ["rook", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {-1, 0}, ["rook", "queen"])
|
|
end
|
|
|
|
defp attacked_by_bishop_or_queen?(board, {file, rank}) do
|
|
_attacked?(board, {file, rank}, {1, 1}, ["bishop", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {1, -1}, ["bishop", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {-1, 1}, ["bishop", "queen"]) ||
|
|
_attacked?(board, {file, rank}, {-1, -1}, ["bishop", "queen"])
|
|
end
|
|
|
|
defp attacked_by_knight?(board, {file, rank}) do
|
|
_attacked?(board, {file, rank}, Knight.pattern, "knight")
|
|
end
|
|
|
|
defp attacked_by_pawn?(board, {file, rank}) do
|
|
colour =
|
|
board
|
|
|> Board.piece({file, rank})
|
|
|> Map.get("colour")
|
|
|
|
board
|
|
|> _attacked_by_pawn?({file, rank}, Pawn.pattern(colour))
|
|
end
|
|
|
|
defp _attacked_by_pawn?(board, {file, rank}, pattern) do
|
|
moves =
|
|
board
|
|
|> Generator.moves({file, rank}, pattern)
|
|
|
|
Enum.any?(moves, &(match_piece(board, &1, "pawn")))
|
|
end
|
|
|
|
defp _attacked?(_board, {0, _rank}, {-1, _}, _), do: false
|
|
defp _attacked?(_board, {_file, 0}, {_, -1}, _), do: false
|
|
defp _attacked?(_board, {7, _rank}, {1, _}, _), do: false
|
|
defp _attacked?(_board, {_file, 7}, {_, 1}, _), do: false
|
|
defp _attacked?(board, {file, rank}, {fv, rv}, pieces) do
|
|
board
|
|
|> Generator.moves({file, rank}, {fv, rv})
|
|
|> List.last
|
|
|> case do
|
|
{file, rank} ->
|
|
piece = board["#{file},#{rank}"]
|
|
|
|
Enum.any?(pieces, &(match?(%{"type" => ^&1}, piece)))
|
|
nil ->
|
|
false
|
|
end
|
|
end
|
|
|
|
defp _attacked?(board, {file, rank}, pattern, piece_type) do
|
|
moves =
|
|
board
|
|
|> Generator.moves({file, rank}, pattern)
|
|
|
|
Enum.any?(moves, &(match_piece(board, &1, piece_type)))
|
|
end
|
|
|
|
defp match_piece(board, {file, rank}, piece_type) do
|
|
piece =
|
|
board
|
|
|> Board.piece({file, rank})
|
|
|
|
piece["type"] == piece_type
|
|
end
|
|
end
|