Persistent game #5

Merged
Simponic merged 6 commits from persistent-game into main 2023-01-17 16:00:18 -05:00
2 changed files with 98 additions and 25 deletions
Showing only changes of commit 87eb950021 - Show all commits

View File

@ -15,7 +15,7 @@ defmodule Chessh.SSH.Client.Game do
width: 0, width: 0,
height: 0, height: 0,
flipped: false, flipped: false,
color: :light, color: nil,
player_session: nil player_session: nil
end end
@ -76,7 +76,7 @@ defmodule Chessh.SSH.Client.Game do
do: Game.changeset(game, %{dark_player_id: player_session.player_id}) do: Game.changeset(game, %{dark_player_id: player_session.player_id})
end end
{status, maybe_new_game} = {status, maybe_joined_game} =
if maybe_changeset do if maybe_changeset do
maybe_changeset maybe_changeset
|> Repo.update() |> Repo.update()
@ -84,21 +84,24 @@ defmodule Chessh.SSH.Client.Game do
{:undefined, nil} {:undefined, nil}
end end
new_game = if status == :ok && maybe_joined_game do
case {status, maybe_new_game} do :syn.publish(:games, {:game, game_id}, :player_joined)
{:ok, g} -> g end
_ -> game
end
binbo_pid = initialize_game(game_id, fen) binbo_pid = initialize_game(game_id, fen)
send(client_pid, {:send_to_ssh, Utils.clear_codes()}) send(client_pid, {:send_to_ssh, Utils.clear_codes()})
{:ok, new_game = Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player])
%State{
state new_state = %State{
| binbo_pid: binbo_pid, state
color: if(new_game.light_player_id == player_session.player_id, do: :light, else: :dark) | binbo_pid: binbo_pid,
}} color: if(new_game.light_player_id == player_session.player_id, do: :light, else: :dark),
game: new_game
}
Logger.debug("asdfaldfjalsdkfjal #{inspect(new_state)}")
{:ok, new_state}
end end
def init([ def init([
@ -106,7 +109,7 @@ defmodule Chessh.SSH.Client.Game do
state state
| _ | _
]) do ]) do
{:ok, %Game{id: game_id, fen: fen} = game} = {:ok, %Game{id: game_id, fen: fen}} =
Game.changeset( Game.changeset(
%Game{}, %Game{},
Map.merge( Map.merge(
@ -127,7 +130,12 @@ defmodule Chessh.SSH.Client.Game do
binbo_pid = initialize_game(game_id, fen) binbo_pid = initialize_game(game_id, fen)
send(client_pid, {:send_to_ssh, Utils.clear_codes()}) send(client_pid, {:send_to_ssh, Utils.clear_codes()})
{:ok, %State{state | game: game, binbo_pid: binbo_pid}} {:ok,
%State{
state
| game: Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player]),
binbo_pid: binbo_pid
}}
end end
def handle_info( def handle_info(
@ -136,12 +144,26 @@ defmodule Chessh.SSH.Client.Game do
) do ) do
:binbo.move(binbo_pid, move) :binbo.move(binbo_pid, move)
new_state = %State{state | game: Repo.get(Game, game_id)} new_state = %State{
state
| game: Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player])
}
send(client_pid, {:send_to_ssh, render_state(new_state)}) send(client_pid, {:send_to_ssh, render_state(new_state)})
{:noreply, new_state} {:noreply, new_state}
end end
def handle_info(
:player_joined,
%State{client_pid: client_pid, game: %Game{id: game_id}} = state
) do
game = Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player])
new_state = %State{state | game: game}
send(client_pid, {:send_to_ssh, render_state(new_state)})
{:noreply, new_state}
end
def input( def input(
width, width,
height, height,

View File

@ -1,6 +1,6 @@
defmodule Chessh.SSH.Client.Game.Renderer do defmodule Chessh.SSH.Client.Game.Renderer do
alias IO.ANSI alias IO.ANSI
alias Chessh.Utils alias Chessh.{Utils, Player}
alias Chessh.SSH.Client.Game alias Chessh.SSH.Client.Game
require Logger require Logger
@ -25,23 +25,74 @@ defmodule Chessh.SSH.Client.Game.Renderer do
"#{List.to_string([?a + x])}#{@chess_board_height - y}" "#{List.to_string([?a + x])}#{@chess_board_height - y}"
end end
def render_board_state(
fen,
%Game.State{
game:
%Chessh.Game{
light_player: light_player
} = game
} = state
)
when is_nil(light_player) do
render_board_state(fen, %Game.State{
state
| game: %Chessh.Game{game | light_player: %Player{username: "(no opponent)"}}
})
end
def render_board_state(
fen,
%Game.State{
game:
%Chessh.Game{
dark_player: dark_player
} = game
} = state
)
when is_nil(dark_player) do
render_board_state(fen, %Game.State{
state
| game: %Chessh.Game{game | dark_player: %Player{username: "(no opponent)"}}
})
end
def render_board_state(fen, %Game.State{ def render_board_state(fen, %Game.State{
width: _width, width: _width,
height: _height, height: _height,
highlighted: highlighted, highlighted: highlighted,
flipped: flipped flipped: flipped,
game: %Chessh.Game{
id: game_id,
dark_player: %Player{username: dark_player},
light_player: %Player{username: light_player},
turn: turn
}
}) do }) do
board = rendered = [
draw_board( Enum.join(
fen, [
{@tile_width, @tile_height}, ANSI.clear_line(),
highlighted, "Game #{game_id}: ",
flipped ANSI.format_fragment([@light_piece_color, light_player]),
"#{ANSI.default_color()} --vs-- ",
ANSI.format_fragment([@dark_piece_color, dark_player]),
ANSI.default_color(),
", #{ANSI.format_fragment([if(turn == :light, do: @light_piece_color, else: @dark_piece_color), if(turn == :dark, do: dark_player, else: light_player)])} to move"
],
""
) )
| draw_board(
fen,
{@tile_width, @tile_height},
highlighted,
flipped
)
]
[ANSI.home()] ++ [ANSI.home()] ++
Enum.map( Enum.map(
Enum.zip(1..length(board), board), Enum.zip(1..length(rendered), rendered),
fn {i, line} -> fn {i, line} ->
[ANSI.cursor(i, 0), line] [ANSI.cursor(i, 0), line]
end end