Draw board #3
113
lib/chessh/ssh/client/board/board.ex
Normal file
113
lib/chessh/ssh/client/board/board.ex
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
defmodule Chessh.SSH.Client.Board do
|
||||||
|
alias IO.ANSI
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
@chess_board_height 8
|
||||||
|
@chess_board_width 8
|
||||||
|
@tile_width 7
|
||||||
|
@tile_height 4
|
||||||
|
|
||||||
|
@dark_piece_color ANSI.magenta()
|
||||||
|
@light_piece_color ANSI.red()
|
||||||
|
@from_select_background ANSI.green_background()
|
||||||
|
@to_select_background ANSI.blue_background()
|
||||||
|
|
||||||
|
defmodule State do
|
||||||
|
defstruct cursor: %{x: 0, y: 0},
|
||||||
|
highlighted: %{},
|
||||||
|
move_from: nil,
|
||||||
|
game_id: nil,
|
||||||
|
client_pid: nil
|
||||||
|
end
|
||||||
|
|
||||||
|
use Chessh.SSH.Client.Screen
|
||||||
|
|
||||||
|
def init([%State{game_id: game_id} = state | _]) do
|
||||||
|
:syn.add_node_to_scopes([:games])
|
||||||
|
:ok = :syn.join(:games, {:game, game_id}, self())
|
||||||
|
|
||||||
|
{:ok, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:attempted_move, move}, %State{client_pid: client_pid} = state) do
|
||||||
|
send(client_pid, {:send_to_ssh, ["hello, world!"]})
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
def input(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
action,
|
||||||
|
%State{
|
||||||
|
move_from: move_from,
|
||||||
|
game_id: game_id,
|
||||||
|
cursor: %{x: cursor_x, y: cursor_y} = cursor,
|
||||||
|
client_pid: client_pid
|
||||||
|
} = state
|
||||||
|
) do
|
||||||
|
new_cursor =
|
||||||
|
case action do
|
||||||
|
:left -> %{y: cursor_y, x: cursor_x - 1}
|
||||||
|
:right -> %{y: cursor_y, x: cursor_x + 1}
|
||||||
|
:down -> %{y: cursor_y + 1, x: cursor_x}
|
||||||
|
:up -> %{y: cursor_y - 1, x: cursor_x}
|
||||||
|
_ -> cursor
|
||||||
|
end
|
||||||
|
|
||||||
|
{new_move_from, move_to} =
|
||||||
|
if action == :return do
|
||||||
|
coords = {new_cursor.y, new_cursor.x}
|
||||||
|
|
||||||
|
case move_from do
|
||||||
|
nil -> {coords, nil}
|
||||||
|
_ -> {nil, coords}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
{move_from, nil}
|
||||||
|
end
|
||||||
|
|
||||||
|
if move_from && move_to do
|
||||||
|
attempted_move = "#{to_chess_coord(move_from)}#{to_chess_coord(move_to)}"
|
||||||
|
:syn.publish(:games, {:game, game_id}, {:new_move, attempted_move})
|
||||||
|
end
|
||||||
|
|
||||||
|
new_state = %State{
|
||||||
|
state
|
||||||
|
| cursor: new_cursor,
|
||||||
|
move_from: new_move_from,
|
||||||
|
highlighted: %{
|
||||||
|
new_move_from => @from_select_background,
|
||||||
|
{new_cursor.y, new_cursor.x} => @to_select_background
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
send(client_pid, {:send_to_ssh, render_state(width, height, new_state)})
|
||||||
|
new_state
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(width, height, %State{client_pid: client_pid} = state) do
|
||||||
|
send(client_pid, {:send_to_ssh, render_state(width, height, state)})
|
||||||
|
state
|
||||||
|
end
|
||||||
|
|
||||||
|
defp render_state(width, height, %State{} = _state) do
|
||||||
|
[ANSI.clear(), "#{width}#{height}"]
|
||||||
|
end
|
||||||
|
|
||||||
|
defp to_chess_coord({y, x})
|
||||||
|
when x >= 0 and x < @chess_board_width and y >= 0 and y < @chess_board_height do
|
||||||
|
"#{List.to_string([?a + x])}#{y + 1}"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp piece_type(char) do
|
||||||
|
case String.capitalize(char) do
|
||||||
|
"P" -> "pawn"
|
||||||
|
"N" -> "knight"
|
||||||
|
"R" -> "rook"
|
||||||
|
"B" -> "bishop"
|
||||||
|
"K" -> "king"
|
||||||
|
"Q" -> "queen"
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -25,8 +25,8 @@ defmodule Chessh.SSH.Client do
|
|||||||
@impl true
|
@impl true
|
||||||
def init([%State{} = state]) do
|
def init([%State{} = state]) do
|
||||||
{:ok, screen_pid} =
|
{:ok, screen_pid} =
|
||||||
GenServer.start_link(Chessh.SSH.Client.Menu, [
|
GenServer.start_link(Chessh.SSH.Client.Board, [
|
||||||
%Chessh.SSH.Client.Menu.State{client_pid: self()}
|
%Chessh.SSH.Client.Board.State{client_pid: self()}
|
||||||
])
|
])
|
||||||
|
|
||||||
{:ok, %{state | screen_processes: [screen_pid]}}
|
{:ok, %{state | screen_processes: [screen_pid]}}
|
||||||
|
@ -23,10 +23,6 @@ defmodule Chessh.SSH.Client.Menu do
|
|||||||
{:ok, state}
|
{:ok, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
# @options [
|
|
||||||
# {"Option 1", {Chessh.SSH.Client.Board, [%Chessh.SSH.Client.Board.State{}]}},
|
|
||||||
# {"Option 2", {Chessh.SSH.Client.Board, [%Chessh.SSH.Client.Board.State{}]}}
|
|
||||||
# ]
|
|
||||||
@options [
|
@options [
|
||||||
{"Option 1", {}},
|
{"Option 1", {}},
|
||||||
{"Option 2", {}},
|
{"Option 2", {}},
|
||||||
|
Loading…
Reference in New Issue
Block a user