summaryrefslogtreecommitdiff
path: root/lib/chessh/ssh/client/game
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chessh/ssh/client/game')
-rw-r--r--lib/chessh/ssh/client/game/game.ex37
-rw-r--r--lib/chessh/ssh/client/game/previous_game.ex121
-rw-r--r--lib/chessh/ssh/client/game/renderer.ex20
3 files changed, 149 insertions, 29 deletions
diff --git a/lib/chessh/ssh/client/game/game.ex b/lib/chessh/ssh/client/game/game.ex
index da2bd99..cd641f0 100644
--- a/lib/chessh/ssh/client/game/game.ex
+++ b/lib/chessh/ssh/client/game/game.ex
@@ -12,8 +12,6 @@ defmodule Chessh.SSH.Client.Game do
game: nil,
client_pid: nil,
binbo_pid: nil,
- width: 0,
- height: 0,
flipped: false,
color: nil,
player_session: nil
@@ -25,7 +23,6 @@ defmodule Chessh.SSH.Client.Game do
:syn.add_node_to_scopes([:games])
:ok = :syn.join(:games, {:game, game_id}, self())
- :binbo.start()
{:ok, binbo_pid} = :binbo.new_server()
:binbo.new_game(binbo_pid, fen)
@@ -177,11 +174,9 @@ defmodule Chessh.SSH.Client.Game do
flipped: player_color == :dark
})
- send(
- client_pid,
- {:send_to_ssh, [Utils.clear_codes() | Renderer.render_board_state(new_state)]}
- )
-
+ # Clear screen and do initial render
+ send(client_pid, {:send_to_ssh, Utils.clear_codes()})
+ render(new_state)
{:ok, new_state}
end
@@ -227,8 +222,8 @@ defmodule Chessh.SSH.Client.Game do
end
def input(
- width,
- height,
+ _width,
+ _height,
action,
%State{
move_from: move_from,
@@ -300,8 +295,6 @@ defmodule Chessh.SSH.Client.Game do
state
| cursor: new_cursor,
move_from: new_move_from,
- width: width,
- height: height,
flipped: if(action == "f", do: !flipped, else: flipped)
})
@@ -349,13 +342,7 @@ defmodule Chessh.SSH.Client.Game do
end
end
- send(client_pid, {:send_to_ssh, Renderer.render_board_state(new_state)})
- new_state
- end
-
- def render(width, height, %State{client_pid: client_pid} = state) do
- new_state = %State{state | width: width, height: height}
- send(client_pid, {:send_to_ssh, Renderer.render_board_state(new_state)})
+ render(new_state)
new_state
end
@@ -370,7 +357,7 @@ defmodule Chessh.SSH.Client.Game do
from,
to,
%State{
- game: %Game{id: game_id, turn: turn},
+ game: %Game{game_moves: game_moves, id: game_id, turn: turn},
binbo_pid: binbo_pid,
flipped: flipped,
color: turn
@@ -404,7 +391,8 @@ defmodule Chessh.SSH.Client.Game do
fen: fen,
moves: game.moves + 1,
turn: if(game.turn == :dark, do: :light, else: :dark),
- last_move: attempted_move
+ last_move: attempted_move,
+ game_moves: if(game_moves, do: game_moves <> " ", else: "") <> attempted_move
},
changeset_from_status(status)
)
@@ -498,4 +486,11 @@ defmodule Chessh.SSH.Client.Game do
end
|> Map.merge(extra_highlights)
end
+
+ def render(_width, _height, %State{} = state), do: render(state)
+
+ def render(%State{client_pid: client_pid} = state) do
+ send(client_pid, {:send_to_ssh, Renderer.render_board_state(state)})
+ state
+ end
end
diff --git a/lib/chessh/ssh/client/game/previous_game.ex b/lib/chessh/ssh/client/game/previous_game.ex
new file mode 100644
index 0000000..38172fd
--- /dev/null
+++ b/lib/chessh/ssh/client/game/previous_game.ex
@@ -0,0 +1,121 @@
+defmodule Chessh.SSH.Client.PreviousGame do
+ @start_fen "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
+
+ alias Chessh.{Game, Utils}
+ alias Chessh.SSH.Client.Game.Renderer
+ alias IO.ANSI
+
+ require Logger
+
+ defmodule State do
+ defstruct move_fens: %{},
+ move_idx: 0,
+ binbo_pid: nil,
+ game: %Game{},
+ client_pid: nil,
+ flipped: false
+ end
+
+ use Chessh.SSH.Client.Screen
+
+ def init([
+ %State{
+ client_pid: client_pid,
+ game: %Game{
+ game_moves: game_moves
+ }
+ } = state
+ ]) do
+ {:ok, binbo_pid} = :binbo.new_server()
+ :binbo.new_game(binbo_pid, @start_fen)
+
+ {move_fens, _moves} =
+ game_moves
+ |> String.trim()
+ |> String.split(" ")
+ |> Enum.reduce({%{"0" => @start_fen}, 1}, fn move, {move_idx_fen_map, curr_turn} ->
+ {:ok, _status} = :binbo.move(binbo_pid, move)
+ {:ok, fen} = :binbo.get_fen(binbo_pid)
+
+ {Map.put(move_idx_fen_map, "#{curr_turn}", fen), curr_turn + 1}
+ end)
+
+ new_state = %State{
+ state
+ | binbo_pid: binbo_pid,
+ move_fens: move_fens
+ }
+
+ send(client_pid, {:send_to_ssh, Utils.clear_codes()})
+ render(new_state)
+
+ {:ok, new_state}
+ end
+
+ def input(
+ _width,
+ _height,
+ action,
+ %State{
+ move_idx: move_idx,
+ flipped: flipped,
+ game: %Game{
+ moves: num_moves
+ }
+ } = state
+ ) do
+ new_move_idx =
+ case action do
+ :left ->
+ Utils.wrap_around(move_idx, -1, num_moves)
+
+ :right ->
+ Utils.wrap_around(move_idx, 1, num_moves)
+
+ _ ->
+ move_idx
+ end
+
+ new_state = %State{
+ state
+ | move_idx: new_move_idx,
+ flipped: if(action == "f", do: !flipped, else: flipped)
+ }
+
+ render(new_state)
+ new_state
+ end
+
+ def render(
+ %State{
+ flipped: flipped,
+ client_pid: client_pid,
+ move_fens: move_fens,
+ move_idx: move_idx,
+ game: %Game{id: game_id, moves: total_moves}
+ } = state
+ ) do
+ {:ok, fen} = Map.fetch(move_fens, "#{move_idx}")
+
+ lines =
+ ["Game #{game_id} | Move #{move_idx} / #{total_moves}"] ++
+ Renderer.draw_board(fen, flipped) ++
+ ["<- previous | next ->"]
+
+ send(
+ client_pid,
+ {:send_to_ssh,
+ [ANSI.home()] ++
+ Enum.map(
+ Enum.zip(1..length(lines), lines),
+ fn {i, line} ->
+ [ANSI.cursor(i, 0), ANSI.clear_line(), line]
+ end
+ )}
+ )
+
+ state
+ end
+
+ def render(_width, _height, %State{} = state), do: render(state)
+end
diff --git a/lib/chessh/ssh/client/game/renderer.ex b/lib/chessh/ssh/client/game/renderer.ex
index c7d3a96..b9071a9 100644
--- a/lib/chessh/ssh/client/game/renderer.ex
+++ b/lib/chessh/ssh/client/game/renderer.ex
@@ -69,8 +69,6 @@ defmodule Chessh.SSH.Client.Game.Renderer do
end
def render_board_state(%Game.State{
- width: _width,
- height: _height,
highlighted: highlighted,
flipped: flipped,
game:
@@ -169,12 +167,18 @@ defmodule Chessh.SSH.Client.Game.Renderer do
)
end
- defp draw_board(
- fen,
- {tile_width, tile_height} = tile_dims,
- highlights,
- flipped
- ) do
+ def draw_board(
+ fen,
+ flipped
+ ),
+ do: draw_board(fen, {@tile_width, @tile_height}, %{}, flipped)
+
+ def draw_board(
+ fen,
+ {tile_width, tile_height} = tile_dims,
+ highlights,
+ flipped
+ ) do
board_coord_to_piece_art = make_board_coordinate_to_piece_art_map(fen)
tile_rows = make_board_tiles(tile_dims)