diff --git a/lib/chess/moves/pawn.ex b/lib/chess/moves/pawn.ex index dc375b0..aceebe6 100644 --- a/lib/chess/moves/pawn.ex +++ b/lib/chess/moves/pawn.ex @@ -2,11 +2,33 @@ defmodule Chess.Moves.Pawn do @moduledoc false def moves(board, {file, rank}) do + normal_moves(board, {file, rank}) ++ + taking_moves(board, {file, rank}) + end + + defp normal_moves(board, {file, rank}) do board["#{file},#{rank}"] |> Map.get("colour") |> _moves(board, {file, rank}) end + defp taking_moves(board, {file, rank}) do + colour = + board["#{file},#{rank}"] + |> Map.get("colour") + + colour + |> _taking_moves(board, {file, rank}, patterns(colour)) + end + + defp patterns("white") do + [{-1, 1}, {1, 1}] + end + + defp patterns("black") do + [{-1, -1}, {1, -1}] + end + defp _moves("white", board, {file, rank}) do cond do obstruction?(board, {file, rank + 1}) -> @@ -29,6 +51,21 @@ defmodule Chess.Moves.Pawn do end end + def _taking_moves(_colour, _board, {_file, _rank}, []), do: [] + def _taking_moves(colour, board, {file, rank}, [{fv, rv} | moves]) do + move_square = {file + fv, rank + rv} + if can_take_piece?(colour, board, move_square) do + [move_square | _taking_moves(colour, board, {file, rank}, moves)] + else + _taking_moves(colour, board, {file, rank}, moves) + end + end + + defp can_take_piece?(colour, board, {file, rank}) do + piece = board["#{file},#{rank}"] + piece && piece["colour"] != colour + end + defp obstruction?(board, {file, rank}) do board |> Map.has_key?("#{file},#{rank}") diff --git a/test/chess/moves/pawn_test.exs b/test/chess/moves/pawn_test.exs index 9f5ce0e..e1827fb 100644 --- a/test/chess/moves/pawn_test.exs +++ b/test/chess/moves/pawn_test.exs @@ -66,6 +66,28 @@ defmodule Chess.Moves.PawnTest do assert moves == expected_moves end + test "white pawn can take an opponents piece" do + board = %{ + "4,2" => %{"type" => "pawn", "colour" => "white"}, + "5,3" => %{"type" => "pawn", "colour" => "black"}, + } + moves = Pawn.moves(board, {4, 2}) + + expected_moves = [{4, 3}, {5, 3}] + assert moves == expected_moves + end + + test "black pawn can take an opponents piece" do + board = %{ + "6,6" => %{"type" => "pawn", "colour" => "black"}, + "5,5" => %{"type" => "pawn", "colour" => "white"}, + } + moves = Pawn.moves(board, {6, 6}) + + expected_moves = [{6, 5}, {6, 4}, {5, 5}] + assert moves == expected_moves + end + def default_board do Chess.Board.default end