Highlight a square

This commit is contained in:
Simponic 2023-01-06 22:29:01 -07:00
parent 5b8dc2cb98
commit 779c75dbe4
Signed by untrusted user who does not match committer: simponic
GPG Key ID: 52B3774857EB24B1
3 changed files with 94 additions and 26 deletions

View File

@ -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

View File

@ -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

View File

@ -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