1
0
mirror of https://github.com/danbee/chess synced 2025-03-04 08:39:06 +00:00

Checks whether a player is checkmated

This commit is contained in:
Daniel Barber 2018-04-07 13:35:48 -04:00
parent e2826fdbce
commit 6b31491ad4
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
5 changed files with 136 additions and 65 deletions

View File

@ -1,21 +0,0 @@
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

40
lib/chess/game_state.ex Normal file
View File

@ -0,0 +1,40 @@
defmodule Chess.GameState do
@moduledoc false
alias Chess.Board
alias Chess.Moves
alias Chess.Moves.Piece
def player_checkmated?(board, colour) do
board
|> Board.search(%{"colour" => colour})
|> Enum.all?(fn({file, rank}) ->
board
|> cannot_escape_check?({file, rank})
end)
end
def cannot_escape_check?(board, {file, rank}) do
piece =
board
|> Board.piece({file, rank})
board
|> Moves.available({file, rank})
|> Enum.all?(fn({to_file, to_rank}) ->
board
|> Board.move_piece(%{"from" => [file, rank], "to" => [to_file, to_rank]})
|> king_in_check?(piece["colour"])
end)
end
def king_in_check?(board, colour) do
king =
board
|> Board.search(%{"type" => "king", "colour" => colour})
|> List.first
board
|> Piece.attacked?(king)
end
end

View File

@ -10,6 +10,7 @@ defmodule Chess.Store.Game do
alias Chess.Board
alias Chess.Store.Game
alias Chess.GameState
schema "games" do
field :board, :map, default: Board.default()
@ -49,7 +50,7 @@ defmodule Chess.Store.Game do
end
def validate_king_in_check(changeset, %Game{turn: turn}, %{board: board}) do
if Board.king_in_check?(board, turn) do
if GameState.king_in_check?(board, turn) do
changeset
|> add_error(
:board,

View File

@ -0,0 +1,94 @@
defmodule Chess.GameStateTest do
@moduledoc false
use Chess.DataCase
alias Chess.GameState
test "king is in check" do
board = %{
"4,0" => %{"type" => "king", "colour" => "white"},
"4,7" => %{"type" => "queen", "colour" => "black"},
}
assert GameState.king_in_check?(board, "white")
end
test "king is not in check" do
board = %{
"5,0" => %{"type" => "king", "colour" => "white"},
"4,7" => %{"type" => "queen", "colour" => "black"},
}
refute GameState.king_in_check?(board, "white")
end
test "king is in check by a knight" do
board = %{
"4,0" => %{"type" => "king", "colour" => "white"},
"3,2" => %{"type" => "knight", "colour" => "black"},
}
assert GameState.king_in_check?(board, "white")
end
test "king is in check by a pawn" do
board = %{
"4,0" => %{"type" => "king", "colour" => "white"},
"3,1" => %{"type" => "pawn", "colour" => "black"},
}
assert GameState.king_in_check?(board, "white")
end
test "king is in checkmate by queen and rook" do
board = %{
"0,0" => %{"type" => "king", "colour" => "white"},
"0,4" => %{"type" => "queen", "colour" => "black"},
"1,4" => %{"type" => "rook", "colour" => "black"},
}
assert GameState.player_checkmated?(board, "white")
end
test "king is not in checkmate by a queen" do
board = %{
"0,0" => %{"type" => "king", "colour" => "white"},
"0,4" => %{"type" => "queen", "colour" => "black"},
}
refute GameState.player_checkmated?(board, "white")
end
test "king is checkmate by a queen and a knight" do
board = %{
"0,0" => %{"type" => "king", "colour" => "white"},
"1,1" => %{"type" => "queen", "colour" => "black"},
"2,3" => %{"type" => "knight", "colour" => "black"},
}
assert GameState.player_checkmated?(board, "white")
end
test "knight can block checkmate by queen and rook" do
board = %{
"0,0" => %{"type" => "king", "colour" => "white"},
"2,0" => %{"type" => "knight", "colour" => "white"},
"0,5" => %{"type" => "queen", "colour" => "black"},
"1,5" => %{"type" => "rook", "colour" => "black"},
}
refute GameState.player_checkmated?(board, "white")
end
test "bishop can take checking queen" do
board = %{
"0,0" => %{"type" => "king", "colour" => "white"},
"2,3" => %{"type" => "bishop", "colour" => "white"},
"0,5" => %{"type" => "queen", "colour" => "black"},
"1,5" => %{"type" => "rook", "colour" => "black"},
}
refute GameState.player_checkmated?(board, "white")
end
end

View File

@ -1,43 +0,0 @@
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