Skip to content

Instantly share code, notes, and snippets.

@mazz
Created November 16, 2022 05:11
Show Gist options
  • Save mazz/a36b6f8164281a91ba46047a0e83a73a to your computer and use it in GitHub Desktop.
Save mazz/a36b6f8164281a91ba46047a0e83a73a to your computer and use it in GitHub Desktop.
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