Created
November 16, 2022 05:11
-
-
Save mazz/a36b6f8164281a91ba46047a0e83a73a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule ChessPhxWeb.MatchMainLive do | |
@moduledoc """ | |
List all orgs for the current_user. | |
""" | |
use ChessPhxWeb, :live_view | |
@impl true | |
def mount(_params, _session, socket) do | |
case Chex.new_game() do | |
{:ok, pid} -> | |
dbg(pid) | |
if connected?(socket), do: Chex.Server.subscribe(pid) | |
socket = | |
socket | |
|> assign(pid: pid) | |
|> assign(selected_square: nil) | |
|> assign(files: Chex.Board.files()) | |
|> assign(ranks: 1..8) | |
|> update_assigns_from_game(Chex.state(pid)) | |
{:ok, socket} | |
{:error, _error} -> | |
{:ok, socket} | |
end | |
end | |
@impl true | |
def handle_params(params, _url, socket) do | |
dbg(params) | |
{:noreply, apply_action(socket, socket.assigns.live_action, params)} | |
end | |
defp apply_action(socket, :new, _params) do | |
socket | |
# |> assign(:page_title, gettext("New organization")) | |
# |> assign(:org, %Org{}) | |
end | |
defp apply_action(socket, :index, _params) do | |
# case Chex.new_game() do | |
# {:ok, pid} -> | |
# socket = | |
# socket | |
# |> assign(game_pid: pid) | |
# # |> redirect(to: Routes.match_path(conn, :play)) | |
# socket | |
# {:error, error} -> | |
# dbg(error) | |
# # put_view(conn, PageView) | |
# # |> render("error.html", message: "Couldn't start a game") | |
# socket | |
# end | |
# socket | |
# |> assign(:page_title, gettext("Organizations")) | |
# |> assign(:org, nil) | |
socket | |
end | |
@impl true | |
def render(assigns) do | |
~H""" | |
<h1>Chess</h1> | |
<p>FEN: <%= @fen %></p> | |
<div class="row"> | |
<div class="column column-25"> | |
<a href="/new" class="button">New Game</a> | |
</div> | |
<div class="column column-50"> | |
<div style="position:relative;height:0;width:100%;padding-bottom:100%;"> | |
<div id="board-container"> | |
<%= for r <- @ranks do %> | |
<%= for f <- @files do %> | |
asdf | |
<div | |
id={"square_#{f}_#{r}"} | |
class={"square file-#{f} rank-#{r} square-#{Chex.Square.color({f, r})} #{if @selected_square == "#{f}#{r}", do: "square-selected"}"} | |
phx-click="square-clicked" | |
phx-value-name={"#{f}#{r}"} | |
phx-hook="Square" | |
></div> | |
<% end %> | |
<% end %> | |
</div> | |
<div id="pieces-container"> | |
<%= for {id, {name, color, {file, rank}}} <- @pieces do %> | |
<div | |
class={"piece piece-#{name}-#{color} file-#{file} rank-#{rank}"} | |
draggable="true" | |
phx-hook="Piece" | |
phx-click="square-clicked" | |
phx-value-name={"#{file}#{rank}"} | |
data-current-square={"#{file}#{rank}"} | |
id={"#{id}"} | |
></div> | |
<% end %> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="column column-50"> | |
<h3>White Captures</h3> | |
<%= for {name, _color, _sq} <- @white_captures do %> | |
<div class={"piece piece-captured piece-#{name}-black"}></div> | |
<% end %> | |
</div> | |
<div class="column column-50"> | |
<h3>Black Captures</h3> | |
<%= for {name, _color, _sq} <- @black_captures do %> | |
<div class={"piece piece-captured piece-#{name}-white"}></div> | |
<% end %> | |
</div> | |
</div> | |
</div> | |
<div class="column column-25"> | |
<h2><%= String.capitalize(assigns[:to_move]) %>'s turn.</h2> | |
<ol> | |
<%= for [white, black] <- assigns[:moves] do %> | |
<li><%= white %>, <%= black %></li> | |
<% end %> | |
</ol> | |
</div> | |
</div> | |
""" | |
end | |
def handle_event("square-clicked", %{"name" => n}, %{assigns: %{selected_square: n}} = socket) do | |
{:noreply, assign(socket, selected_square: nil)} | |
end | |
def handle_event("square-clicked", %{"name" => n}, %{assigns: %{selected_square: nil}} = socket) do | |
{:noreply, assign(socket, selected_square: n)} | |
end | |
def handle_event( | |
"square-clicked", | |
%{"name" => to}, | |
%{assigns: %{selected_square: from, pid: pid}} = socket | |
) do | |
case Chex.move(pid, from <> to) do | |
{:error, _reason} -> | |
{:noreply, assign(socket, selected_square: nil)} | |
game -> | |
dbg(pid) | |
# Ask computer to move | |
GenServer.cast(pid, :engine_move) | |
socket = | |
socket | |
|> assign(selected_square: nil) | |
|> update_assigns_from_game(game) | |
{:noreply, socket} | |
end | |
end | |
def handle_event("move-piece", %{"from" => sq, "to" => sq}, socket), do: {:noreply, socket} | |
def handle_event("move-piece", %{"from" => from, "to" => to}, socket) do | |
{:noreply, do_move(socket, socket.assigns.pid, from, to)} | |
end | |
@impl true | |
def handle_info(%Chex.Game{} = game, socket) do | |
{:noreply, update_assigns_from_game(socket, game)} | |
end | |
defp do_move(socket, pid, from, to) do | |
case Chex.move(pid, from <> to) do | |
{:error, _reason} -> | |
assign(socket, selected_square: nil) | |
game -> | |
dbg(pid) | |
# Ask computer to move | |
GenServer.cast(pid, :engine_move) | |
socket | |
|> assign(selected_square: nil) | |
|> update_assigns_from_game(game) | |
end | |
end | |
defp update_assigns_from_game(socket, game) do | |
socket | |
|> assign_pieces(game) | |
|> assign_to_move(game) | |
|> assign_moves(game) | |
|> assign_black_captures(game) | |
|> assign_white_captures(game) | |
|> assign_fen(game) | |
end | |
defp assign_pieces(socket, game) do | |
p = | |
game | |
|> Map.get(:board) | |
|> Map.from_struct() | |
|> Enum.reject(fn {_k, v} -> is_nil(v) end) | |
|> Enum.map(fn {current_sq, {name, color, {sf, sr}}} -> | |
{"#{sf}#{sr}", {name, color, current_sq}} | |
end) | |
|> Enum.sort() | |
assign(socket, pieces: p) | |
end | |
defp assign_to_move(socket, game) do | |
to_move = | |
game | |
|> Map.get(:active_color) | |
|> to_string() | |
assign(socket, to_move: to_move) | |
end | |
defp assign_moves(socket, game) do | |
moves = | |
game | |
|> Map.get(:moves) | |
|> Enum.reverse() | |
|> Enum.chunk_every(2, 2, [{{"", ""}, {"", ""}}]) | |
|> Enum.map(fn [{{wff, wfr}, {wtf, wtr}}, {{bff, bfr}, {btf, btr}}] -> | |
["#{wff}#{wfr}#{wtf}#{wtr}", "#{bff}#{bfr}#{btf}#{btr}"] | |
end) | |
assign(socket, moves: moves) | |
end | |
defp assign_black_captures(socket, game) do | |
captures = | |
game | |
|> Map.get(:captures) | |
|> Enum.filter(fn {_name, color, _sq} -> color == :white end) | |
|> Enum.reverse() | |
assign(socket, black_captures: captures) | |
end | |
defp assign_white_captures(socket, game) do | |
captures = | |
game | |
|> Map.get(:captures) | |
|> Enum.filter(fn {_name, color, _sq} -> color == :black end) | |
|> Enum.reverse() | |
assign(socket, white_captures: captures) | |
end | |
defp assign_fen(socket, game) do | |
IO.inspect(game, label: "assign_fen game") | |
fen = | |
game | |
|> Map.get(:fen) | |
assign(socket, fen: fen) | |
end | |
@impl true | |
def handle_event("close_modal", _, socket) do | |
{:noreply, push_patch(socket, to: Routes.orgs_path(socket, :index))} | |
end | |
# defp assign_invitations(socket) do | |
# invitations = Orgs.list_invitations_by_user(socket.assigns.current_user) | |
# assign(socket, :invitations, invitations) | |
# end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment