diff options
Diffstat (limited to 'lib/chessh/ssh/client/game')
-rw-r--r-- | lib/chessh/ssh/client/game/game.ex | 87 | ||||
-rw-r--r-- | lib/chessh/ssh/client/game/renderer.ex | 92 |
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 |