From e2826fdbce90b0c06d6a43ce7d9b2872ce587c7d Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Sat, 7 Apr 2018 13:08:18 -0400 Subject: [PATCH] Split out game status checks and add piece colour search --- lib/chess/board.ex | 27 +++++++++++----------- lib/chess/game.ex | 21 +++++++++++++++++ test/chess/board_test.exs | 47 +++++++++------------------------------ test/chess/game_test.ex | 43 +++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 49 deletions(-) create mode 100644 lib/chess/game.ex create mode 100644 test/chess/game_test.ex diff --git a/lib/chess/board.ex b/lib/chess/board.ex index cb86af5..c89af74 100644 --- a/lib/chess/board.ex +++ b/lib/chess/board.ex @@ -1,8 +1,6 @@ defmodule Chess.Board do @moduledoc false - alias Chess.Moves.Piece - def transform(board) do Enum.map(0..7, fn (rank) -> Enum.map(0..7, fn (file) -> @@ -16,7 +14,15 @@ defmodule Chess.Board do |> Enum.filter(fn({_index, piece}) -> match?(%{"type" => ^type, "colour" => ^colour}, piece) end) - |> Enum.map(fn({index, _piece}) -> index_to_tuple(index) end) + |> indexes_to_tuples + end + + def search(board, %{"colour" => colour}) do + board + |> Enum.filter(fn({_index, piece}) -> + match?(%{"colour" => ^colour}, piece) + end) + |> indexes_to_tuples end def piece(board, {file, rank}) do @@ -32,16 +38,6 @@ defmodule Chess.Board do Map.put(board, "#{to_file},#{to_rank}", piece) end - def king_in_check?(board, colour) do - king = - board - |> search(%{"type" => "king", "colour" => colour}) - |> List.first - - board - |> Piece.attacked?(king) - end - def default do %{ "0,7" => %{"type" => "rook", "colour" => "black"}, @@ -82,6 +78,11 @@ defmodule Chess.Board do } end + defp indexes_to_tuples(list) do + list + |> Enum.map(fn({index, _piece}) -> index_to_tuple(index) end) + end + defp index_to_tuple(index) do index |> String.split(",") diff --git a/lib/chess/game.ex b/lib/chess/game.ex new file mode 100644 index 0000000..56075d0 --- /dev/null +++ b/lib/chess/game.ex @@ -0,0 +1,21 @@ +defmodule Chess.Game do + @moduledoc false + + alias Chess.Board + alias Chess.Moves.Piece + + def player_checkmated?(board, colour) do + board + |> Board.search(%{"colour" => colour}) + end + + def king_in_check?(board, colour) do + king = + board + |> Board.search(%{"type" => "king", "colour" => colour}) + |> List.first + + board + |> Piece.attacked?(king) + end +end diff --git a/test/chess/board_test.exs b/test/chess/board_test.exs index f7be08b..b19f7b5 100644 --- a/test/chess/board_test.exs +++ b/test/chess/board_test.exs @@ -22,6 +22,17 @@ defmodule Chess.BoardTest do assert Board.search(board, piece) == expected_result end + test "finds pieces on the board with a partial search" do + board = Board.default + + piece = %{"colour" => "white"} + expected_result = [ + {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1}, {6, 1}, {7, 1}, + {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, + ] |> Enum.sort + assert Board.search(board, piece) == expected_result + end + test "finds a single piece on the board" do board = Board.default @@ -40,40 +51,4 @@ defmodule Chess.BoardTest do "5,2" => %{"type" => "queen", "colour" => "white"}, } end - - test "recognise when the king is in check" do - board = %{ - "4,0" => %{"type" => "king", "colour" => "white"}, - "4,7" => %{"type" => "queen", "colour" => "black"}, - } - - assert Board.king_in_check?(board, "white") - end - - test "recognise when the king is not in check" do - board = %{ - "5,0" => %{"type" => "king", "colour" => "white"}, - "4,7" => %{"type" => "queen", "colour" => "black"}, - } - - refute Board.king_in_check?(board, "white") - end - - test "recognize when the king is in check by a knight" do - board = %{ - "4,0" => %{"type" => "king", "colour" => "white"}, - "3,2" => %{"type" => "knight", "colour" => "black"}, - } - - assert Board.king_in_check?(board, "white") - end - - test "recognize when the king is in check by a pawn" do - board = %{ - "4,0" => %{"type" => "king", "colour" => "white"}, - "3,1" => %{"type" => "pawn", "colour" => "black"}, - } - - assert Board.king_in_check?(board, "white") - end end diff --git a/test/chess/game_test.ex b/test/chess/game_test.ex new file mode 100644 index 0000000..4a634ea --- /dev/null +++ b/test/chess/game_test.ex @@ -0,0 +1,43 @@ +defmodule Chess.GameTest do + @moduledoc false + + use Chess.DataCase + + alias Chess.Game + + test "recognise when the king is in check" do + board = %{ + "4,0" => %{"type" => "king", "colour" => "white"}, + "4,7" => %{"type" => "queen", "colour" => "black"}, + } + + assert Game.king_in_check?(board, "white") + end + + test "recognise when the king is not in check" do + board = %{ + "5,0" => %{"type" => "king", "colour" => "white"}, + "4,7" => %{"type" => "queen", "colour" => "black"}, + } + + refute Game.king_in_check?(board, "white") + end + + test "recognize when the king is in check by a knight" do + board = %{ + "4,0" => %{"type" => "king", "colour" => "white"}, + "3,2" => %{"type" => "knight", "colour" => "black"}, + } + + assert Game.king_in_check?(board, "white") + end + + test "recognize when the king is in check by a pawn" do + board = %{ + "4,0" => %{"type" => "king", "colour" => "white"}, + "3,1" => %{"type" => "pawn", "colour" => "black"}, + } + + assert Game.king_in_check?(board, "white") + end +end