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:
parent
7e2c841b59
commit
04e00e530b
@ -42,8 +42,8 @@ defmodule Chess.Board do
|
|||||||
if castling_move?(piece, from_file, to_file) do
|
if castling_move?(piece, from_file, to_file) do
|
||||||
board
|
board
|
||||||
|> castling_move(%{
|
|> castling_move(%{
|
||||||
"from" => [from_file, from_rank],
|
from: {from_file, from_rank},
|
||||||
"to" => [to_file, to_rank]
|
to: {to_file, to_rank}
|
||||||
})
|
})
|
||||||
|> Map.get(:board)
|
|> Map.get(:board)
|
||||||
else
|
else
|
||||||
@ -65,7 +65,7 @@ defmodule Chess.Board do
|
|||||||
|
|
||||||
def castling_move?(_, _, _), do: false
|
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, %{
|
move_piece(board, %{
|
||||||
"from" => [0, rank],
|
"from" => [0, rank],
|
||||||
"to" => [3, rank]
|
"to" => [3, rank]
|
||||||
|
|||||||
@ -68,7 +68,7 @@ defmodule Chess.GameState do
|
|||||||
|> Moves.available({file, rank})
|
|> Moves.available({file, rank})
|
||||||
|> Enum.all?(fn {to_file, to_rank} ->
|
|> Enum.all?(fn {to_file, to_rank} ->
|
||||||
board
|
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)
|
|> Map.get(:board)
|
||||||
|> king_in_check?(piece["colour"])
|
|> king_in_check?(piece["colour"])
|
||||||
end)
|
end)
|
||||||
|
|||||||
@ -79,7 +79,7 @@ defmodule Chess.Moves.Pieces.King.Castling do
|
|||||||
[{2, rank}, {3, rank}]
|
[{2, rank}, {3, rank}]
|
||||||
|> Enum.any?(fn {to_file, to_rank} ->
|
|> Enum.any?(fn {to_file, to_rank} ->
|
||||||
board
|
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)
|
|> Map.get(:board)
|
||||||
|> GameState.king_in_check?(colour)
|
|> GameState.king_in_check?(colour)
|
||||||
end)
|
end)
|
||||||
@ -89,7 +89,7 @@ defmodule Chess.Moves.Pieces.King.Castling do
|
|||||||
[{5, rank}, {6, rank}]
|
[{5, rank}, {6, rank}]
|
||||||
|> Enum.any?(fn {to_file, to_rank} ->
|
|> Enum.any?(fn {to_file, to_rank} ->
|
||||||
board
|
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)
|
|> Map.get(:board)
|
||||||
|> GameState.king_in_check?(colour)
|
|> GameState.king_in_check?(colour)
|
||||||
end)
|
end)
|
||||||
|
|||||||
@ -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__rank-labels">
|
||||||
<div class="board__label">1</div>
|
<div class="board__label">1</div>
|
||||||
<div class="board__label">2</div>
|
<div class="board__label">2</div>
|
||||||
@ -22,14 +22,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="board__body">
|
<div class="board__body">
|
||||||
<%= for rank <- 0..7 do %>
|
<%= for {rank, row} <- @board do %>
|
||||||
<div class="board__row">
|
<div class="board__row">
|
||||||
<%= for file <- 0..7 do %>
|
<%= for {file, piece} <- row do %>
|
||||||
<%= render ChessWeb.SquareView,
|
<%= render ChessWeb.SquareView,
|
||||||
"square.html",
|
"square.html",
|
||||||
rank: rank,
|
rank: rank,
|
||||||
file: file,
|
file: file,
|
||||||
piece: @game.board["#{file},#{rank}"],
|
piece: piece,
|
||||||
selected: {file, rank} == @selected,
|
selected: {file, rank} == @selected,
|
||||||
available: {file, rank} in @available %>
|
available: {file, rank} in @available %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|||||||
@ -5,6 +5,7 @@ defmodule ChessWeb.BoardLive do
|
|||||||
alias Chess.Store.Game
|
alias Chess.Store.Game
|
||||||
alias Chess.Repo
|
alias Chess.Repo
|
||||||
alias Chess.Board
|
alias Chess.Board
|
||||||
|
alias Chess.Moves
|
||||||
|
|
||||||
import Chess.Auth, only: [get_user!: 1]
|
import Chess.Auth, only: [get_user!: 1]
|
||||||
|
|
||||||
@ -19,11 +20,24 @@ defmodule ChessWeb.BoardLive do
|
|||||||
Game.for_user(user)
|
Game.for_user(user)
|
||||||
|> Repo.get!(game_id)
|
|> Repo.get!(game_id)
|
||||||
|
|
||||||
{:ok, assign(socket, game: game, user: user, selected: nil, available: [])}
|
{:ok, assign(socket, default_assigns(game, user))}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("click", %{"rank" => rank, "file" => file}, socket) do
|
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
|
end
|
||||||
|
|
||||||
defp handle_click(socket, file, rank) do
|
defp handle_click(socket, file, rank) do
|
||||||
@ -34,27 +48,56 @@ defmodule ChessWeb.BoardLive do
|
|||||||
colour = ChessWeb.GameView.player_colour(user, game)
|
colour = ChessWeb.GameView.player_colour(user, game)
|
||||||
|
|
||||||
assigns =
|
assigns =
|
||||||
case socket.assigns do
|
if colour == game.turn do
|
||||||
%{:selected => nil} ->
|
case socket.assigns do
|
||||||
case Board.piece(board, {file, rank}) do
|
%{selected: nil} ->
|
||||||
%{"colour" => ^colour} ->
|
handle_selection(board, colour, file, rank)
|
||||||
[{:selected, selected(file, rank)}]
|
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
[]
|
handle_move(socket.assigns, file, rank)
|
||||||
end
|
end
|
||||||
|
|
||||||
_ ->
|
|
||||||
[{:selected, nil}]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
assign(socket, assigns)
|
assign(socket, assigns)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp selected(file, rank) do
|
defp handle_selection(board, colour, file, rank) do
|
||||||
{
|
case Board.piece(board, {file, rank}) do
|
||||||
String.to_integer(file),
|
%{"colour" => ^colour} ->
|
||||||
String.to_integer(rank)
|
[
|
||||||
}
|
{: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
|
||||||
end
|
end
|
||||||
|
|||||||
@ -90,7 +90,7 @@ defmodule Chess.Store.GameTest do
|
|||||||
opponent_id: opponent.id
|
opponent_id: opponent.id
|
||||||
})
|
})
|
||||||
|
|
||||||
move_params = %{"from" => [4, 1], "to" => [4, 3]}
|
move_params = %{from: {4, 1}, to: {4, 3}}
|
||||||
|
|
||||||
changeset =
|
changeset =
|
||||||
Game.move_changeset(
|
Game.move_changeset(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user