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

View File

@ -1,6 +1,6 @@
defmodule Chessh.SSH.Client.Game.Renderer do
alias IO.ANSI
alias Chessh.Utils
alias Chessh.{Utils, Player}
alias Chessh.SSH.Client.Game
require Logger
@ -25,23 +25,74 @@ defmodule Chessh.SSH.Client.Game.Renderer do
"#{List.to_string([?a + x])}#{@chess_board_height - y}"
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{
width: _width,
height: _height,
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
board =
draw_board(
fen,
{@tile_width, @tile_height},
highlighted,
flipped
rendered = [
Enum.join(
[
ANSI.clear_line(),
"Game #{game_id}: ",
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()] ++
Enum.map(
Enum.zip(1..length(board), board),
Enum.zip(1..length(rendered), rendered),
fn {i, line} ->
[ANSI.cursor(i, 0), line]
end