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

Now we're correctly handling moves

This commit is contained in:
Daniel Barber 2021-07-13 18:21:12 -05:00
parent 7e2c841b59
commit 04e00e530b
6 changed files with 72 additions and 29 deletions

View File

@ -42,8 +42,8 @@ defmodule Chess.Board do
if castling_move?(piece, from_file, to_file) do
board
|> castling_move(%{
"from" => [from_file, from_rank],
"to" => [to_file, to_rank]
from: {from_file, from_rank},
to: {to_file, to_rank}
})
|> Map.get(:board)
else
@ -65,7 +65,7 @@ defmodule Chess.Board do
def castling_move?(_, _, _), do: false
def castling_move(board, %{"from" => [4, rank], "to" => [2, _rank]}) do
def castling_move(board, %{from: {4, rank}, to: {2, _rank}}) do
move_piece(board, %{
"from" => [0, rank],
"to" => [3, rank]

View File

@ -68,7 +68,7 @@ defmodule Chess.GameState do
|> Moves.available({file, rank})
|> Enum.all?(fn {to_file, to_rank} ->
board
|> Board.move_piece(%{"from" => [file, rank], "to" => [to_file, to_rank]})
|> Board.move_piece(%{from: {file, rank}, to: {to_file, to_rank}})
|> Map.get(:board)
|> king_in_check?(piece["colour"])
end)

View File

@ -79,7 +79,7 @@ defmodule Chess.Moves.Pieces.King.Castling do
[{2, rank}, {3, rank}]
|> Enum.any?(fn {to_file, to_rank} ->
board
|> Board.move_piece(%{"from" => [4, rank], "to" => [to_file, to_rank]})
|> Board.move_piece(%{from: {4, rank}, to: {to_file, to_rank}})
|> Map.get(:board)
|> GameState.king_in_check?(colour)
end)
@ -89,7 +89,7 @@ defmodule Chess.Moves.Pieces.King.Castling do
[{5, rank}, {6, rank}]
|> Enum.any?(fn {to_file, to_rank} ->
board
|> Board.move_piece(%{"from" => [4, rank], "to" => [to_file, to_rank]})
|> Board.move_piece(%{from: {4, rank}, to: {to_file, to_rank}})
|> Map.get(:board)
|> GameState.king_in_check?(colour)
end)

View File

@ -1,4 +1,4 @@
<div class="board board--black-to-move board--player-is-<%= player_colour(@user, @game) %>">
<div class="board board--<%= @game.turn %>-to-move board--player-is-<%= player_colour(@user, @game) %>">
<div class="board__rank-labels">
<div class="board__label">1</div>
<div class="board__label">2</div>
@ -22,14 +22,14 @@
</div>
<div class="board__body">
<%= for rank <- 0..7 do %>
<%= for {rank, row} <- @board do %>
<div class="board__row">
<%= for file <- 0..7 do %>
<%= for {file, piece} <- row do %>
<%= render ChessWeb.SquareView,
"square.html",
rank: rank,
file: file,
piece: @game.board["#{file},#{rank}"],
piece: piece,
selected: {file, rank} == @selected,
available: {file, rank} in @available %>
<% end %>

View File

@ -5,6 +5,7 @@ defmodule ChessWeb.BoardLive do
alias Chess.Store.Game
alias Chess.Repo
alias Chess.Board
alias Chess.Moves
import Chess.Auth, only: [get_user!: 1]
@ -19,11 +20,24 @@ defmodule ChessWeb.BoardLive do
Game.for_user(user)
|> Repo.get!(game_id)
{:ok, assign(socket, game: game, user: user, selected: nil, available: [])}
{:ok, assign(socket, default_assigns(game, user))}
end
def handle_event("click", %{"rank" => rank, "file" => file}, socket) do
{:noreply, socket |> handle_click(file, rank)}
{
:noreply,
socket |> handle_click(String.to_integer(file), String.to_integer(rank))
}
end
defp default_assigns(game, user) do
%{
board: Board.transform(game.board),
game: game,
user: user,
selected: nil,
available: []
}
end
defp handle_click(socket, file, rank) do
@ -34,27 +48,56 @@ defmodule ChessWeb.BoardLive do
colour = ChessWeb.GameView.player_colour(user, game)
assigns =
case socket.assigns do
%{:selected => nil} ->
case Board.piece(board, {file, rank}) do
%{"colour" => ^colour} ->
[{:selected, selected(file, rank)}]
if colour == game.turn do
case socket.assigns do
%{selected: nil} ->
handle_selection(board, colour, file, rank)
_ ->
[]
end
_ ->
[{:selected, nil}]
_ ->
handle_move(socket.assigns, file, rank)
end
end
assign(socket, assigns)
end
defp selected(file, rank) do
{
String.to_integer(file),
String.to_integer(rank)
}
defp handle_selection(board, colour, file, rank) do
case Board.piece(board, {file, rank}) do
%{"colour" => ^colour} ->
[
{:selected, {file, rank}},
{:available, Moves.available(board, {file, rank})}
]
_ ->
[]
end
end
defp handle_move(
%{game: game, available: available, selected: selected},
file,
rank
) do
if {file, rank} in available do
new_game =
game
|> Moves.make_move(%{from: selected, to: {file, rank}})
|> case do
{:ok, %{game: new_game}} ->
new_game
end
new_board = Board.transform(new_game.board)
[
{:selected, nil},
{:available, []},
{:board, new_board},
{:game, new_game}
]
else
[{:selected, nil}, {:available, []}]
end
end
end

View File

@ -90,7 +90,7 @@ defmodule Chess.Store.GameTest do
opponent_id: opponent.id
})
move_params = %{"from" => [4, 1], "to" => [4, 3]}
move_params = %{from: {4, 1}, to: {4, 3}}
changeset =
Game.move_changeset(