diff --git a/lib/chess/moves.ex b/lib/chess/moves.ex index fce2b0e..c442a71 100644 --- a/lib/chess/moves.ex +++ b/lib/chess/moves.ex @@ -3,6 +3,7 @@ defmodule Chess.Moves do alias Chess.Moves.Pawn alias Chess.Moves.Rook + alias Chess.Moves.Bishop def available(board, {file, rank}) do piece = board["#{file},#{rank}"] @@ -13,7 +14,7 @@ defmodule Chess.Moves do %{"type" => "rook"} -> Rook.moves(board, {file, rank}) %{"type" => "bishop"} -> - [] + Bishop.moves(board, {file, rank}) %{"type" => "knight"} -> [] %{"type" => "king"} -> diff --git a/lib/chess/moves/bishop.ex b/lib/chess/moves/bishop.ex new file mode 100644 index 0000000..a46c9c7 --- /dev/null +++ b/lib/chess/moves/bishop.ex @@ -0,0 +1,34 @@ +defmodule Chess.Moves.Bishop do + @moduledoc false + + def moves(board, {file, rank}) do + moves_northeast(board, {file, rank}) ++ + moves_southeast(board, {file, rank}) ++ + moves_northwest(board, {file, rank}) ++ + moves_southwest(board, {file, rank}) + end + + defp moves_northeast(_board, {7, _rank}), do: [] + defp moves_northeast(_board, {_file, 7}), do: [] + defp moves_northeast(board, {file, rank}) do + [{file + 1, rank + 1} | moves_northeast(board, {file + 1, rank + 1})] + end + + defp moves_southeast(_board, {7, _rank}), do: [] + defp moves_southeast(_board, {_file, 0}), do: [] + defp moves_southeast(board, {file, rank}) do + [{file + 1, rank - 1} | moves_southeast(board, {file + 1, rank - 1})] + end + + defp moves_northwest(_board, {0, _rank}), do: [] + defp moves_northwest(_board, {_file, 7}), do: [] + defp moves_northwest(board, {file, rank}) do + [{file - 1, rank + 1} | moves_northwest(board, {file - 1, rank + 1})] + end + + defp moves_southwest(_board, {0, _rank}), do: [] + defp moves_southwest(_board, {_file, 0}), do: [] + defp moves_southwest(board, {file, rank}) do + [{file - 1, rank - 1} | moves_southwest(board, {file - 1, rank - 1})] + end +end diff --git a/test/chess/moves/bishop_test.exs b/test/chess/moves/bishop_test.exs new file mode 100644 index 0000000..0f7d385 --- /dev/null +++ b/test/chess/moves/bishop_test.exs @@ -0,0 +1,32 @@ +defmodule Chess.Moves.BishopTest do + use Chess.DataCase + + alias Chess.Moves.Bishop + + test "bishops can move diagonally" do + board = %{"4,5" => %{"type" => "bishop", "colour" => "white"}} + moves = Bishop.moves(board, {4, 5}) + + expected_moves = Enum.sort([ + {5, 6}, {6, 7}, + {5, 4}, {6, 3}, {7, 2}, + {3, 4}, {2, 3}, {1, 2}, {0, 1}, + {3, 6}, {2, 7}, + ]) + assert Enum.sort(moves) == expected_moves + end + + test "bishops cannot move further than the edge" do + board = %{"0,0" => %{"type" => "bishop", "colour" => "white"}} + moves = Bishop.moves(board, {0, 0}) + + expected_moves = Enum.sort([ + {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}, {6, 6}, {7, 7} + ]) + assert Enum.sort(moves) == expected_moves + end + + def board do + Chess.Board.default + end +end