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.ex87
-rw-r--r--lib/chessh/ssh/client/game/renderer.ex92
2 files changed, 74 insertions, 105 deletions
diff --git a/lib/chessh/ssh/client/game/game.ex b/lib/chessh/ssh/client/game/game.ex
index 4fb28f3..738832e 100644
--- a/lib/chessh/ssh/client/game/game.ex
+++ b/lib/chessh/ssh/client/game/game.ex
@@ -1,10 +1,8 @@
defmodule Chessh.SSH.Client.Game do
require Logger
- alias Chessh.{Game, Utils, Repo}
+ alias Chessh.{Game, Utils, Repo, Bot}
alias Chessh.SSH.Client.Game.Renderer
- @default_fen "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
-
defmodule State do
defstruct cursor: %{x: 7, y: 7},
highlighted: %{},
@@ -69,27 +67,14 @@ defmodule Chessh.SSH.Client.Game do
case Hammer.check_rate_inc(
:redis,
- "player-#{state.player_session.id}-create-game-rate",
+ "player-#{state.player_session.player_id}-create-game-rate",
create_game_ms,
create_game_rate,
1
) do
{:allow, _count} ->
- # Starting a new game
- {:ok, %Game{id: game_id} = game} =
- Game.changeset(
- %Game{},
- Map.merge(
- if(color == :light,
- do: %{light_player_id: player_session.player_id},
- else: %{dark_player_id: player_session.player_id}
- ),
- %{
- fen: @default_fen
- }
- )
- )
- |> Repo.insert()
+ game = Game.new_game(color, player_session.player_id) |> Repo.insert!()
+ %Game{id: game_id} = game
GenServer.cast(
:discord_notifier,
@@ -129,20 +114,23 @@ defmodule Chessh.SSH.Client.Game do
id: game_id,
fen: fen,
dark_player_id: dark_player_id,
- light_player_id: light_player_id
+ light_player_id: light_player_id,
+ bot_id: bot_id
} = game
} = state
| _
]) do
maybe_changeset =
- case color do
- :light ->
- if !light_player_id,
- do: Game.changeset(game, %{light_player_id: player_session.player_id})
-
- :dark ->
- if !dark_player_id,
- do: Game.changeset(game, %{dark_player_id: player_session.player_id})
+ if !bot_id do
+ case(color) do
+ :light ->
+ if !light_player_id,
+ do: Game.changeset(game, %{light_player_id: player_session.player_id})
+
+ :dark ->
+ if !dark_player_id,
+ do: Game.changeset(game, %{dark_player_id: player_session.player_id})
+ end
end
{status, maybe_joined_game} =
@@ -164,7 +152,7 @@ defmodule Chessh.SSH.Client.Game do
end
binbo_pid = initialize_game(game_id, fen)
- game = Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player])
+ game = Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player, :bot])
player_color = if(game.light_player_id == player_session.player_id, do: :light, else: :dark)
@@ -206,7 +194,7 @@ defmodule Chessh.SSH.Client.Game do
}
end).(%State{
state
- | game: Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player])
+ | game: Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player, :bot])
})
send(client_pid, {:send_to_ssh, Renderer.render_board_state(new_state)})
@@ -218,7 +206,7 @@ defmodule Chessh.SSH.Client.Game do
: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])
+ game = Repo.get(Game, game_id) |> Repo.preload([:light_player, :dark_player, :bot])
new_state = %State{state | game: game}
send(client_pid, {:send_to_ssh, Renderer.render_board_state(new_state)})
{:noreply, new_state}
@@ -365,7 +353,7 @@ defmodule Chessh.SSH.Client.Game do
from,
to,
%State{
- game: %Game{game_moves: game_moves, id: game_id, turn: turn},
+ game: %Game{id: game_id, turn: turn},
binbo_pid: binbo_pid,
flipped: flipped,
color: turn
@@ -391,22 +379,15 @@ defmodule Chessh.SSH.Client.Game do
{:ok, status} ->
{:ok, fen} = :binbo.get_fen(binbo_pid)
- {:ok, %Game{status: after_move_status}} =
+ {:ok, %Game{status: after_move_status} = game} =
game
- |> Game.changeset(
- Map.merge(
- %{
- fen: fen,
- moves: game.moves + 1,
- turn: if(game.turn == :dark, do: :light, else: :dark),
- last_move: attempted_move,
- game_moves: if(game_moves, do: game_moves <> " ", else: "") <> attempted_move
- },
- changeset_from_status(status)
- )
- )
+ |> Game.update_with_status(attempted_move, fen, status)
|> Repo.update()
+ if !is_nil(game.bot) do
+ spawn(fn -> Bot.send_update(Repo.get(Game, game.id) |> Repo.preload([:bot])) end)
+ end
+
:syn.publish(:games, {:game, game_id}, {:new_move, attempted_move})
if after_move_status == :continue do
@@ -433,22 +414,6 @@ defmodule Chessh.SSH.Client.Game do
nil
end
- defp changeset_from_status(game_status) do
- case game_status do
- :continue ->
- %{}
-
- {:draw, _} ->
- %{status: :draw}
-
- {:checkmate, :white_wins} ->
- %{status: :winner, winner: :light}
-
- {:checkmate, :black_wins} ->
- %{status: :winner, winner: :dark}
- end
- end
-
defp make_highlight_map(
%State{
game: %Game{last_move: last_move, turn: turn},
diff --git a/lib/chessh/ssh/client/game/renderer.ex b/lib/chessh/ssh/client/game/renderer.ex
index b9071a9..ecd1803 100644
--- a/lib/chessh/ssh/client/game/renderer.ex
+++ b/lib/chessh/ssh/client/game/renderer.ex
@@ -2,6 +2,7 @@ defmodule Chessh.SSH.Client.Game.Renderer do
alias IO.ANSI
alias Chessh.{Utils, Player}
alias Chessh.SSH.Client.Game
+ require Logger
@chess_board_height 8
@chess_board_width 8
@@ -9,10 +10,11 @@ defmodule Chessh.SSH.Client.Game.Renderer do
@tile_width 7
@tile_height 4
- @previous_move_background ANSI.light_magenta_background()
- @from_select_background ANSI.light_green_background()
- @to_select_background ANSI.light_yellow_background()
- @in_check_color ANSI.yellow_background()
+ @previous_move_background ANSI.color_background(208)
+ @from_select_background ANSI.color_background(105)
+
+ @to_select_background ANSI.color_background(177)
+ @in_check_color ANSI.color_background(197)
@dark_piece_color ANSI.red()
@light_piece_color ANSI.light_cyan()
@@ -42,29 +44,17 @@ defmodule Chessh.SSH.Client.Game.Renderer do
%Game.State{
game:
%Chessh.Game{
- light_player: light_player
- } = game
- } = state
- )
- when is_nil(light_player) do
- render_board_state(%Game.State{
- state
- | game: %Chessh.Game{game | light_player: %Player{username: "(no opponent)"}}
- })
- end
-
- def render_board_state(
- %Game.State{
- game:
- %Chessh.Game{
+ light_player: light_player,
dark_player: dark_player
} = game
} = state
)
- when is_nil(dark_player) do
+ when is_nil(light_player) or is_nil(dark_player) do
+ {light_player, dark_player} = get_players(game)
+
render_board_state(%Game.State{
state
- | game: %Chessh.Game{game | dark_player: %Player{username: "(no opponent)"}}
+ | game: %Chessh.Game{game | light_player: light_player, dark_player: dark_player}
})
end
@@ -73,9 +63,12 @@ defmodule Chessh.SSH.Client.Game.Renderer do
flipped: flipped,
game:
%Chessh.Game{
- fen: fen
+ fen: fen,
+ light_player: light_player,
+ dark_player: dark_player
} = game
- }) do
+ })
+ when not is_nil(light_player) and not is_nil(dark_player) do
rendered = [
ANSI.clear_line(),
make_status_line(game, true)
@@ -98,29 +91,19 @@ defmodule Chessh.SSH.Client.Game.Renderer do
def make_status_line(
%Chessh.Game{
- light_player: light_player
- } = game,
- fancy
- )
- when is_nil(light_player),
- do:
- make_status_line(
- %Chessh.Game{game | light_player: %Player{username: "(no opponent)"}},
- fancy
- )
-
- def make_status_line(
- %Chessh.Game{
+ light_player: light_player,
dark_player: dark_player
} = game,
fancy
)
- when is_nil(dark_player),
- do:
- make_status_line(
- %Chessh.Game{game | dark_player: %Player{username: "(no opponent)"}},
- fancy
- )
+ when is_nil(light_player) or is_nil(dark_player) do
+ {light_player, dark_player} = get_players(game)
+
+ make_status_line(
+ %Chessh.Game{game | light_player: light_player, dark_player: dark_player},
+ fancy
+ )
+ end
def make_status_line(
%Chessh.Game{
@@ -143,12 +126,12 @@ defmodule Chessh.SSH.Client.Game.Renderer do
"Game #{game_id} - ",
if(fancy,
do: ANSI.format_fragment([@light_piece_color, light_player]),
- else: "#{light_player} (L)"
+ else: "♔ #{light_player}"
),
"#{if fancy, do: ANSI.default_color(), else: ""} --vs-- ",
if(fancy,
do: ANSI.format_fragment([@dark_piece_color, dark_player]),
- else: "#{dark_player} (D)"
+ else: "♚ #{dark_player}"
),
if(fancy, do: ANSI.default_color(), else: ""),
case status do
@@ -373,4 +356,25 @@ defmodule Chessh.SSH.Client.Game.Renderer do
Map.merge(acc, pieces_map_for_this_row)
end)
end
+
+ defp get_players(
+ %Chessh.Game{light_player: light_player, dark_player: dark_player, bot: bot} = game
+ ) do
+ case {is_nil(light_player), is_nil(dark_player), is_nil(bot)} do
+ {false, true, false} ->
+ {game.light_player, %Player{username: bot.name}}
+
+ {true, false, false} ->
+ {%Player{username: bot.name}, game.dark_player}
+
+ {true, false, true} ->
+ {%Player{username: "(no opponent)"}, game.dark_player}
+
+ {false, true, true} ->
+ {game.light_player, %Player{username: "(no opponent)"}}
+
+ {false, false, true} ->
+ {game.light_player, game.dark_player}
+ end
+ end
end