mirror of
https://github.com/danbee/chess
synced 2025-03-04 08:39:06 +00:00
Get the board rendering
This commit is contained in:
parent
55f0af78a0
commit
b960dd668c
@ -1,15 +1,6 @@
|
||||
defmodule Chess.Board do
|
||||
@moduledoc false
|
||||
|
||||
def transform(board) do
|
||||
Enum.map(0..7, fn rank ->
|
||||
Enum.map(0..7, fn file ->
|
||||
board
|
||||
|> piece({file, rank})
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
def search(board, %{"type" => type, "colour" => colour}) do
|
||||
board
|
||||
|> Enum.filter(fn {_index, piece} ->
|
||||
@ -26,10 +17,6 @@ defmodule Chess.Board do
|
||||
|> indexes_to_tuples
|
||||
end
|
||||
|
||||
def piece(board, {file, rank}) do
|
||||
board["#{file},#{rank}"]
|
||||
end
|
||||
|
||||
def move_piece(board, %{
|
||||
"from" => [from_file, from_rank],
|
||||
"to" => [to_file, to_rank]
|
||||
|
||||
@ -22,22 +22,20 @@
|
||||
</div>
|
||||
|
||||
<div class="board__body">
|
||||
<%= for {rank, row} <- @board do %>
|
||||
<div class="board__row">
|
||||
<%= for {file, piece} <- row do %>
|
||||
<%= render ChessWeb.SquareView,
|
||||
"square.html",
|
||||
rank: rank,
|
||||
file: file,
|
||||
piece: piece,
|
||||
selected: {file, rank} == @selected,
|
||||
available: {file, rank} in @available %>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= for rank <- 0..7 do %>
|
||||
<%= for file <- 0..7 do %>
|
||||
<%= render ChessWeb.SquareView,
|
||||
"square.html",
|
||||
rank: rank,
|
||||
file: file,
|
||||
piece: piece(@board, {file, rank}),
|
||||
selected: {file, rank} == @selected,
|
||||
available: {file, rank} in @available %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="game-state game-state--<%= @game.state %>">
|
||||
<%= states[@game.state] %>
|
||||
<%= states(@game.state) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,24 @@
|
||||
<div class="game-info">
|
||||
<p>
|
||||
Playing <%= opponent(@game, @user.id).name %>
|
||||
<img class="game-info__opponent-status" src="/images/eye-closed.svg" alt="offline">
|
||||
</p>
|
||||
</div>
|
||||
<div class="game-info">
|
||||
<p>
|
||||
Playing <%= opponent(@game, @user.id).name %>
|
||||
<img class="game-info__opponent-status" src="/images/eye-closed.svg" alt="offline">
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="move-list">
|
||||
<table class="table table--condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="move-list__line-number"><span class="visually-hidden">Move no.</span></th>
|
||||
<th class="move-list__header--white">White</th>
|
||||
<th class="move-list__header--black">Black</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" class="move-list__line-number">1.</th>
|
||||
<td class="move-list__move move-list__move--white">e4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<table class="games-list">
|
||||
<tbody>
|
||||
<%= for game <- @games do %>
|
||||
<tr class="<%= turn_class(@conn, game) %>">
|
||||
<tr class="<%= turn_class(current_user(@conn), game) %>">
|
||||
<td>
|
||||
<span class="games-list__player-indicator">
|
||||
<img src="images/pawn_<%= player_colour(current_user(@conn), game) %>.svg">
|
||||
@ -16,10 +16,10 @@
|
||||
class: "btn btn-default btn-xs" %>
|
||||
</td>
|
||||
<td>
|
||||
<%= state(@conn, game) %>
|
||||
<%= state(current_user(@conn), game) %>
|
||||
</td>
|
||||
<td>
|
||||
<%= won_lost(@conn, game) %>
|
||||
<%= won_lost(current_user(@conn), game) %>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<%= link gettext("Delete"),
|
||||
|
||||
@ -11,23 +11,5 @@
|
||||
ChessWeb.GameInfoLive,
|
||||
session: %{"user_id" => current_user(@conn).id, "game_id" => @game.id}
|
||||
) %>
|
||||
|
||||
<div class="move-list">
|
||||
<table class="table table--condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="move-list__line-number"><span class="visually-hidden">Move no.</span></th>
|
||||
<th class="move-list__header--white">White</th>
|
||||
<th class="move-list__header--black">Black</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row" class="move-list__line-number">1.</th>
|
||||
<td class="move-list__move move-list__move--white">e4</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -3,11 +3,12 @@ defmodule ChessWeb.GameView do
|
||||
|
||||
alias Chess.GameState
|
||||
|
||||
import Phoenix.Component
|
||||
import Chess.Auth, only: [current_user: 1]
|
||||
|
||||
def won_lost(conn, game) do
|
||||
def won_lost(user, game) do
|
||||
if game_over?(game) && game.state == "checkmate" do
|
||||
(your_turn?(conn, game) &&
|
||||
(your_turn?(user, game) &&
|
||||
gettext("You lost")) ||
|
||||
gettext("You won")
|
||||
end
|
||||
@ -17,12 +18,12 @@ defmodule ChessWeb.GameView do
|
||||
GameState.game_over?(game)
|
||||
end
|
||||
|
||||
def state(conn, game) do
|
||||
def state(user, game) do
|
||||
cond do
|
||||
GameState.game_over?(game) ->
|
||||
states()[game.state]
|
||||
states(game.state)
|
||||
|
||||
your_turn?(conn, game) ->
|
||||
your_turn?(user, game) ->
|
||||
gettext("Your turn")
|
||||
|
||||
true ->
|
||||
@ -30,29 +31,32 @@ defmodule ChessWeb.GameView do
|
||||
end
|
||||
end
|
||||
|
||||
def turn_class(conn, game) do
|
||||
if your_turn?(conn, game) && !GameState.game_over?(game) do
|
||||
def turn_class(user, game) do
|
||||
if your_turn?(user, game) && !GameState.game_over?(game) do
|
||||
"games-list__your-turn"
|
||||
end
|
||||
end
|
||||
|
||||
def your_turn?(conn, game) do
|
||||
conn
|
||||
|> current_user()
|
||||
def your_turn?(user, game) do
|
||||
user
|
||||
|> player_colour(game) == game.turn
|
||||
end
|
||||
|
||||
def player_colour(conn, game) do
|
||||
(current_user(conn).id == game.user_id && "white") || "black"
|
||||
def player_colour(user, game) do
|
||||
(user.id == game.user_id && "white") || "black"
|
||||
end
|
||||
|
||||
def files(conn, game) do
|
||||
ranks(conn, game)
|
||||
def piece(board, {file, rank}) do
|
||||
board["#{file},#{rank}"]
|
||||
end
|
||||
|
||||
def files(user, game) do
|
||||
ranks(user, game)
|
||||
|> Enum.reverse()
|
||||
end
|
||||
|
||||
def ranks(conn, game) do
|
||||
if game.user_id == current_user(conn).id do
|
||||
def ranks(user, game) do
|
||||
if game.user_id == user.id do
|
||||
7..0
|
||||
else
|
||||
0..7
|
||||
@ -75,11 +79,14 @@ defmodule ChessWeb.GameView do
|
||||
end
|
||||
end
|
||||
|
||||
defp states do
|
||||
%{
|
||||
"checkmate" => gettext("Checkmate!"),
|
||||
"stalemate" => gettext("Stalemate"),
|
||||
"check" => gettext("Check")
|
||||
}
|
||||
def states(state) do
|
||||
Map.get(
|
||||
%{
|
||||
"checkmate" => gettext("Checkmate!"),
|
||||
"stalemate" => gettext("Stalemate"),
|
||||
"check" => gettext("Check")
|
||||
},
|
||||
state
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -7,8 +7,6 @@ defmodule ChessWeb.BoardLive do
|
||||
alias Chess.Board
|
||||
alias Chess.Moves
|
||||
|
||||
import Chess.Auth, only: [get_user!: 1]
|
||||
|
||||
def render(assigns) do
|
||||
Phoenix.View.render(ChessWeb.GameView, "board.html", assigns)
|
||||
end
|
||||
@ -34,7 +32,7 @@ defmodule ChessWeb.BoardLive do
|
||||
|
||||
defp default_assigns(game, user) do
|
||||
%{
|
||||
board: Board.transform(game.board),
|
||||
board: game.board,
|
||||
game: game,
|
||||
user: user,
|
||||
selected: nil,
|
||||
@ -86,22 +84,21 @@ defmodule ChessWeb.BoardLive do
|
||||
rank
|
||||
) do
|
||||
if {file, rank} in available do
|
||||
new_game =
|
||||
game
|
||||
|> Moves.make_move(%{from: selected, to: {file, rank}})
|
||||
|> case do
|
||||
{:ok, %{game: game}} ->
|
||||
board = Board.transform(game.board)
|
||||
game
|
||||
|> Moves.make_move(%{from: selected, to: {file, rank}})
|
||||
|> case do
|
||||
{:ok, %{game: game}} ->
|
||||
board = Board.transform(game.board)
|
||||
|
||||
broadcast_move(game, board)
|
||||
broadcast_move(game, board)
|
||||
|
||||
[
|
||||
{:selected, nil},
|
||||
{:available, []},
|
||||
{:board, board},
|
||||
{:game, game}
|
||||
]
|
||||
end
|
||||
[
|
||||
{:selected, nil},
|
||||
{:available, []},
|
||||
{:board, board},
|
||||
{:game, game}
|
||||
]
|
||||
end
|
||||
else
|
||||
[{:selected, nil}, {:available, []}]
|
||||
end
|
||||
|
||||
@ -5,6 +5,8 @@ defmodule ChessWeb.GameInfoLive do
|
||||
alias Chess.Store.Game
|
||||
alias Chess.Repo
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
def render(assigns) do
|
||||
Phoenix.View.render(ChessWeb.GameView, "game_info.html", assigns)
|
||||
end
|
||||
@ -14,6 +16,8 @@ defmodule ChessWeb.GameInfoLive do
|
||||
|
||||
game =
|
||||
Game.for_user(user)
|
||||
|> preload(:user)
|
||||
|> preload(:opponent)
|
||||
|> Repo.get!(game_id)
|
||||
|
||||
{:ok, assign(socket, game: game, user: user)}
|
||||
|
||||
6
mix.lock
6
mix.lock
@ -13,8 +13,8 @@
|
||||
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
|
||||
"dart_sass": {:hex, :dart_sass, "0.5.1", "d45f20a8e324313689fb83287d4702352793ce8c9644bc254155d12656ade8b6", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "24f8a1c67e8b5267c51a33cbe6c0b5ebf12c2c83ace88b5ac04947d676b4ec81"},
|
||||
"db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"},
|
||||
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
|
||||
"ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"ecto": {:hex, :ecto, "3.9.6", "2f420c173efcb2e22fa4f8fc41e75e02b3c5bd4cffef12085cae5418c12e530d", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df17bc06ba6f78a7b764e4a14ef877fe5f4499332c5a105ace11fe7013b72c84"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.7.3", "c37fdae1b52d2cc51069713a58c2314877c1ad40800a57efb213f77b078a460d", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "24ada3e3996adbed1fa024ca14995ef2ba3d0d17b678b0f3f2b1f66e6ce2b274"},
|
||||
"esbuild": {:hex, :esbuild, "0.6.0", "9ba6ead054abd43cb3d7b14946a0cdd1493698ccd8e054e0e5d6286d7f0f509c", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "30f9a05d4a5bab0d3e37398f312f80864e1ee1a081ca09149d06d474318fd040"},
|
||||
@ -27,7 +27,7 @@
|
||||
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
|
||||
"httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
|
||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||
"jose": {:hex, :jose, "1.11.5", "3bc2d75ffa5e2c941ca93e5696b54978323191988eb8d225c2e663ddfefd515e", [:mix, :rebar3], [], "hexpm", "dcd3b215bafe02ea7c5b23dafd3eb8062a5cd8f2d904fd9caa323d37034ab384"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user