summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimponic <loganhunt@simponic.xyz>2023-01-06 22:29:01 -0700
committerSimponic <loganhunt@simponic.xyz>2023-01-06 22:29:01 -0700
commit779c75dbe44516c0e1911cf8a56698a1508466b7 (patch)
treecc6562e27d7b571c63d1fa4818f5d06492fc7f70
parent5b8dc2cb9800ed38ba1dc02fa5a135880a2c0bac (diff)
downloadchessh-779c75dbe44516c0e1911cf8a56698a1508466b7.tar.gz
chessh-779c75dbe44516c0e1911cf8a56698a1508466b7.zip
Highlight a square
-rw-r--r--lib/chessh/ssh/client.ex1
-rw-r--r--lib/chessh/ssh/screens/board.ex110
-rw-r--r--lib/chessh/ssh/screens/menu.ex9
3 files changed, 94 insertions, 26 deletions
diff --git a/lib/chessh/ssh/client.ex b/lib/chessh/ssh/client.ex
index fdd3875..290c9a7 100644
--- a/lib/chessh/ssh/client.ex
+++ b/lib/chessh/ssh/client.ex
@@ -73,7 +73,6 @@ defmodule Chessh.SSH.Client do
new_state = module.handle_input(action, state)
send(tui_pid, {:send_data, render(new_state)})
-
{:noreply, new_state}
end
end
diff --git a/lib/chessh/ssh/screens/board.ex b/lib/chessh/ssh/screens/board.ex
index 0aac50a..09babad 100644
--- a/lib/chessh/ssh/screens/board.ex
+++ b/lib/chessh/ssh/screens/board.ex
@@ -2,17 +2,18 @@ defmodule Chessh.SSH.Client.Board do
alias Chessh.SSH.Client
alias IO.ANSI
- require Logger
-
defmodule State do
- defstruct cursor_x: 0,
- cursor_y: 0
+ defstruct cursor: %{x: 0, y: 0},
+ highlighted: %{},
+ move_from: nil
end
use Chessh.SSH.Client.Screen
@chess_board_height 8
@chess_board_width 8
+ @tile_width 7
+ @tile_height 4
@dark_piece_color ANSI.magenta()
@light_piece_color ANSI.red()
@@ -35,9 +36,10 @@ defmodule Chessh.SSH.Client.Board do
def make_board({tile_width, tile_height}) do
rows =
- Enum.map(0..(@chess_board_height - 1), fn i ->
- Enum.map(0..(@chess_board_width - 1), fn j ->
- List.duplicate(if(tileIsLight(i, j), do: ' ', else: '▊'), tile_width)
+ Enum.map(0..(@chess_board_height - 1), fn row ->
+ Enum.map(0..(@chess_board_width - 1), fn col ->
+ if(tileIsLight(row, col), do: ' ', else: '▊')
+ |> List.duplicate(tile_width)
end)
|> Enum.join("")
end)
@@ -90,7 +92,11 @@ defmodule Chessh.SSH.Client.Board do
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)
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 ->
curr_x = div(col, tile_width)
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
{:ok, {shade, type}} ->
@@ -112,7 +130,6 @@ defmodule Chessh.SSH.Client.Board do
piece_line_len = String.length(piece_line)
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 &&
relative_to_tile_col < tile_width - pad_left_right do
@@ -128,20 +145,20 @@ defmodule Chessh.SSH.Client.Board do
%{
row_state
| current_color: color,
- row_chars: row_chars ++ [color, new_char]
+ row_chars: row_chars ++ [prefix, color, new_char]
}
else
%{
row_state
| current_color: current_color,
- row_chars: row_chars ++ [new_char]
+ row_chars: row_chars ++ [prefix, new_char]
}
end
else
%{
row_state
| current_color: ANSI.default_color(),
- row_chars: row_chars ++ [ANSI.default_color(), char]
+ row_chars: row_chars ++ [prefix, ANSI.default_color(), char]
}
end
@@ -150,12 +167,12 @@ defmodule Chessh.SSH.Client.Board do
%{
row_state
| current_color: ANSI.default_color(),
- row_chars: row_chars ++ [ANSI.default_color(), char]
+ row_chars: row_chars ++ [prefix, ANSI.default_color(), char]
}
else
%{
row_state
- | row_chars: row_chars ++ [char]
+ | row_chars: row_chars ++ [prefix, char]
}
end
end
@@ -167,8 +184,15 @@ defmodule Chessh.SSH.Client.Board do
end)
end
- def render(%Client.State{} = _state) do
- board = make_board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", {7, 4})
+ def render(%Client.State{
+ 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()] ++
Enum.map(
@@ -179,9 +203,55 @@ defmodule Chessh.SSH.Client.Board do
)
end
- def handle_input(action, %Client.State{} = state) do
- case action do
- _ -> state
- end
+ 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
+ :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
+
+ %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
diff --git a/lib/chessh/ssh/screens/menu.ex b/lib/chessh/ssh/screens/menu.ex
index 9baa059..d9df1b7 100644
--- a/lib/chessh/ssh/screens/menu.ex
+++ b/lib/chessh/ssh/screens/menu.ex
@@ -23,15 +23,14 @@ defmodule Chessh.SSH.Client.Menu do
MMMMMMMMMMM MMMMMMMMMMM MMMMMMMMMMMM"
@options [
- {"Option 1", {Chessh.SSH.Client.Board, %{}}},
- {"Option 2", {Chessh.SSH.Client.Board, %{}}},
- {"Option 3", {Chessh.SSH.Client.Board, %{}}}
+ {"Option 1", {Chessh.SSH.Client.Board, %Chessh.SSH.Client.Board.State{}}},
+ {"Option 2", {Chessh.SSH.Client.Board, %Chessh.SSH.Client.Board.State{}}}
]
def render(%Client.State{
width: width,
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
text = String.split(@logo, "\n")
{logo_width, logo_height} = Utils.text_dim(@logo)
@@ -57,7 +56,7 @@ defmodule Chessh.SSH.Client.Menu do
) ++ [ANSI.home()]
end
- def wrap_around(index, delta, length) do
+ defp wrap_around(index, delta, length) do
calc = index + delta
if(calc < 0, do: length, else: 0) + rem(calc, length)
end