Draw board #3
@ -73,7 +73,6 @@ defmodule Chessh.SSH.Client do
|
|||||||
new_state = module.handle_input(action, state)
|
new_state = module.handle_input(action, state)
|
||||||
|
|
||||||
send(tui_pid, {:send_data, render(new_state)})
|
send(tui_pid, {:send_data, render(new_state)})
|
||||||
|
|
||||||
{:noreply, new_state}
|
{:noreply, new_state}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,17 +2,18 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
alias Chessh.SSH.Client
|
alias Chessh.SSH.Client
|
||||||
alias IO.ANSI
|
alias IO.ANSI
|
||||||
|
|
||||||
require Logger
|
|
||||||
|
|
||||||
defmodule State do
|
defmodule State do
|
||||||
defstruct cursor_x: 0,
|
defstruct cursor: %{x: 0, y: 0},
|
||||||
cursor_y: 0
|
highlighted: %{},
|
||||||
|
move_from: nil
|
||||||
end
|
end
|
||||||
|
|
||||||
use Chessh.SSH.Client.Screen
|
use Chessh.SSH.Client.Screen
|
||||||
|
|
||||||
@chess_board_height 8
|
@chess_board_height 8
|
||||||
@chess_board_width 8
|
@chess_board_width 8
|
||||||
|
@tile_width 7
|
||||||
|
@tile_height 4
|
||||||
|
|
||||||
@dark_piece_color ANSI.magenta()
|
@dark_piece_color ANSI.magenta()
|
||||||
@light_piece_color ANSI.red()
|
@light_piece_color ANSI.red()
|
||||||
@ -35,9 +36,10 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
|
|
||||||
def make_board({tile_width, tile_height}) do
|
def make_board({tile_width, tile_height}) do
|
||||||
rows =
|
rows =
|
||||||
Enum.map(0..(@chess_board_height - 1), fn i ->
|
Enum.map(0..(@chess_board_height - 1), fn row ->
|
||||||
Enum.map(0..(@chess_board_width - 1), fn j ->
|
Enum.map(0..(@chess_board_width - 1), fn col ->
|
||||||
List.duplicate(if(tileIsLight(i, j), do: ' ', else: '▊'), tile_width)
|
if(tileIsLight(row, col), do: ' ', else: '▊')
|
||||||
|
|> List.duplicate(tile_width)
|
||||||
end)
|
end)
|
||||||
|> Enum.join("")
|
|> Enum.join("")
|
||||||
end)
|
end)
|
||||||
@ -90,7 +92,11 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_board(fen, {tile_width, tile_height} = tile_dims) do
|
def draw_board(
|
||||||
|
fen,
|
||||||
|
{tile_width, tile_height} = tile_dims,
|
||||||
|
highlights
|
||||||
|
) do
|
||||||
coordinate_to_piece = make_coordinate_to_piece_art_map(fen)
|
coordinate_to_piece = make_coordinate_to_piece_art_map(fen)
|
||||||
board = make_board(tile_dims)
|
board = make_board(tile_dims)
|
||||||
|
|
||||||
@ -104,6 +110,18 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
fn {char, col}, %{current_color: current_color, row_chars: row_chars} = row_state ->
|
fn {char, col}, %{current_color: current_color, row_chars: row_chars} = row_state ->
|
||||||
curr_x = div(col, tile_width)
|
curr_x = div(col, tile_width)
|
||||||
key = "#{curr_y}, #{curr_x}"
|
key = "#{curr_y}, #{curr_x}"
|
||||||
|
relative_to_tile_col = col - curr_x * tile_width
|
||||||
|
|
||||||
|
prefix =
|
||||||
|
if relative_to_tile_col == 0 do
|
||||||
|
case Map.fetch(highlights, {curr_y, curr_x}) do
|
||||||
|
{:ok, color} ->
|
||||||
|
color
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
ANSI.default_background()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
case Map.fetch(coordinate_to_piece, key) do
|
case Map.fetch(coordinate_to_piece, key) do
|
||||||
{:ok, {shade, type}} ->
|
{:ok, {shade, type}} ->
|
||||||
@ -112,7 +130,6 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
|
|
||||||
piece_line_len = String.length(piece_line)
|
piece_line_len = String.length(piece_line)
|
||||||
pad_left_right = div(tile_width - piece_line_len, 2)
|
pad_left_right = div(tile_width - piece_line_len, 2)
|
||||||
relative_to_tile_col = col - curr_x * tile_width
|
|
||||||
|
|
||||||
if relative_to_tile_col >= pad_left_right &&
|
if relative_to_tile_col >= pad_left_right &&
|
||||||
relative_to_tile_col < tile_width - pad_left_right do
|
relative_to_tile_col < tile_width - pad_left_right do
|
||||||
@ -128,20 +145,20 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
%{
|
%{
|
||||||
row_state
|
row_state
|
||||||
| current_color: color,
|
| current_color: color,
|
||||||
row_chars: row_chars ++ [color, new_char]
|
row_chars: row_chars ++ [prefix, color, new_char]
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
%{
|
%{
|
||||||
row_state
|
row_state
|
||||||
| current_color: current_color,
|
| current_color: current_color,
|
||||||
row_chars: row_chars ++ [new_char]
|
row_chars: row_chars ++ [prefix, new_char]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
%{
|
%{
|
||||||
row_state
|
row_state
|
||||||
| current_color: ANSI.default_color(),
|
| current_color: ANSI.default_color(),
|
||||||
row_chars: row_chars ++ [ANSI.default_color(), char]
|
row_chars: row_chars ++ [prefix, ANSI.default_color(), char]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -150,12 +167,12 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
%{
|
%{
|
||||||
row_state
|
row_state
|
||||||
| current_color: ANSI.default_color(),
|
| current_color: ANSI.default_color(),
|
||||||
row_chars: row_chars ++ [ANSI.default_color(), char]
|
row_chars: row_chars ++ [prefix, ANSI.default_color(), char]
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
%{
|
%{
|
||||||
row_state
|
row_state
|
||||||
| row_chars: row_chars ++ [char]
|
| row_chars: row_chars ++ [prefix, char]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -167,8 +184,15 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def render(%Client.State{} = _state) do
|
def render(%Client.State{
|
||||||
board = make_board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", {7, 4})
|
state_stack: [{_this_module, %State{highlighted: highlighted}} | _]
|
||||||
|
}) do
|
||||||
|
board =
|
||||||
|
draw_board(
|
||||||
|
"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
|
||||||
|
{@tile_width, @tile_height},
|
||||||
|
highlighted
|
||||||
|
)
|
||||||
|
|
||||||
[ANSI.home()] ++
|
[ANSI.home()] ++
|
||||||
Enum.map(
|
Enum.map(
|
||||||
@ -179,9 +203,55 @@ defmodule Chessh.SSH.Client.Board do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_input(action, %Client.State{} = state) do
|
def handle_input(
|
||||||
|
action,
|
||||||
|
%Client.State{
|
||||||
|
state_stack: [
|
||||||
|
{this_module,
|
||||||
|
%State{
|
||||||
|
move_from: move_from,
|
||||||
|
cursor: %{x: cursor_x, y: cursor_y} = cursor
|
||||||
|
} = screen_state}
|
||||||
|
| rest_stack
|
||||||
|
]
|
||||||
|
} = state
|
||||||
|
) do
|
||||||
|
new_cursor =
|
||||||
case action do
|
case action do
|
||||||
_ -> state
|
: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
|
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
|
||||||
|
|
||||||
|
%Client.State{
|
||||||
|
state
|
||||||
|
| state_stack: [
|
||||||
|
{this_module,
|
||||||
|
%State{
|
||||||
|
screen_state
|
||||||
|
| cursor: new_cursor,
|
||||||
|
move_from: new_move_from,
|
||||||
|
highlighted: %{
|
||||||
|
new_move_from => ANSI.green_background(),
|
||||||
|
{new_cursor.y, new_cursor.x} => ANSI.green_background()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
| rest_stack
|
||||||
|
]
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -23,15 +23,14 @@ defmodule Chessh.SSH.Client.Menu do
|
|||||||
MMMMMMMMMMM MMMMMMMMMMM MMMMMMMMMMMM"
|
MMMMMMMMMMM MMMMMMMMMMM MMMMMMMMMMMM"
|
||||||
|
|
||||||
@options [
|
@options [
|
||||||
{"Option 1", {Chessh.SSH.Client.Board, %{}}},
|
{"Option 1", {Chessh.SSH.Client.Board, %Chessh.SSH.Client.Board.State{}}},
|
||||||
{"Option 2", {Chessh.SSH.Client.Board, %{}}},
|
{"Option 2", {Chessh.SSH.Client.Board, %Chessh.SSH.Client.Board.State{}}}
|
||||||
{"Option 3", {Chessh.SSH.Client.Board, %{}}}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def render(%Client.State{
|
def render(%Client.State{
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
state_stack: [{_this_module, %State{selected: selected, y: dy, x: dx}} | _tail]
|
state_stack: [{_this_module, %State{selected: selected, y: dy, x: dx}} | _]
|
||||||
}) do
|
}) do
|
||||||
text = String.split(@logo, "\n")
|
text = String.split(@logo, "\n")
|
||||||
{logo_width, logo_height} = Utils.text_dim(@logo)
|
{logo_width, logo_height} = Utils.text_dim(@logo)
|
||||||
@ -57,7 +56,7 @@ defmodule Chessh.SSH.Client.Menu do
|
|||||||
) ++ [ANSI.home()]
|
) ++ [ANSI.home()]
|
||||||
end
|
end
|
||||||
|
|
||||||
def wrap_around(index, delta, length) do
|
defp wrap_around(index, delta, length) do
|
||||||
calc = index + delta
|
calc = index + delta
|
||||||
if(calc < 0, do: length, else: 0) + rem(calc, length)
|
if(calc < 0, do: length, else: 0) + rem(calc, length)
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user