mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
81 lines
2.2 KiB
Elixir
81 lines
2.2 KiB
Elixir
defmodule Chess.Moves.Generator do
|
|
@moduledoc """
|
|
Generates moves for a piece. We can generate moves in a straight line,
|
|
and these can be combined to make an entire pieces allowed moves. Or we
|
|
can generate moves based on a pattern of vectors. The knight works
|
|
like this.
|
|
"""
|
|
|
|
alias Chess.Board
|
|
|
|
# `movement` is either a vector (bishop, rook, queen)
|
|
# or a pattern (king, knight)
|
|
def moves(board, {file, rank}, movement) do
|
|
board
|
|
|> Board.piece({file, rank})
|
|
|> Map.get("colour")
|
|
|> _moves(board, {file, rank}, movement)
|
|
end
|
|
|
|
# Move generation for pieces that move in straight lines
|
|
defp _moves(_colour, _board, {0, _rank}, {-1, _}), do: []
|
|
defp _moves(_colour, _board, {_file, 0}, {_, -1}), do: []
|
|
defp _moves(_colour, _board, {7, _rank}, {1, _}), do: []
|
|
defp _moves(_colour, _board, {_file, 7}, {_, 1}), do: []
|
|
|
|
defp _moves(colour, board, {file, rank}, {fv, rv}) do
|
|
next_square = {file + fv, rank + rv}
|
|
|
|
cond do
|
|
can_capture_piece?(colour, board, next_square) ->
|
|
[next_square]
|
|
|
|
obstruction?(colour, board, next_square) ->
|
|
[]
|
|
|
|
true ->
|
|
[next_square | _moves(colour, board, next_square, {fv, rv})]
|
|
end
|
|
end
|
|
|
|
# Move generation for pieces that follow a pattern
|
|
defp _moves(_colour, _board, {_file, _rank}, []), do: []
|
|
|
|
defp _moves(colour, board, {file, rank}, [{fv, rv} | moves]) do
|
|
move_square = {file + fv, rank + rv}
|
|
|
|
cond do
|
|
outside_board?(move_square) ||
|
|
obstruction?(colour, board, move_square) ->
|
|
_moves(colour, board, {file, rank}, moves)
|
|
|
|
can_capture_piece?(colour, board, move_square) ->
|
|
[move_square | _moves(colour, board, {file, rank}, moves)]
|
|
|
|
true ->
|
|
[move_square | _moves(colour, board, {file, rank}, moves)]
|
|
end
|
|
end
|
|
|
|
defp outside_board?({file, rank}) do
|
|
file < 0 || file > 7 ||
|
|
rank < 0 || rank > 7
|
|
end
|
|
|
|
defp can_capture_piece?(colour, board, {file, rank}) do
|
|
piece =
|
|
board
|
|
|> Board.piece({file, rank})
|
|
|
|
piece && piece["colour"] != colour
|
|
end
|
|
|
|
defp obstruction?(colour, board, {file, rank}) do
|
|
piece =
|
|
board
|
|
|> Board.piece({file, rank})
|
|
|
|
piece && piece["colour"] == colour
|
|
end
|
|
end
|