1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
defmodule Chessh.Game do
alias Chessh.{Bot, Player, Game}
use Ecto.Schema
import Ecto.Changeset
@default_fen "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"
schema "games" do
field(:fen, :string)
field(:moves, :integer, default: 0)
field(:last_move, :string)
field(:turn, Ecto.Enum, values: [:light, :dark], default: :light)
field(:winner, Ecto.Enum, values: [:light, :dark, :none], default: :none)
field(:status, Ecto.Enum, values: [:continue, :draw, :winner], default: :continue)
field(:game_moves, :string)
belongs_to(:light_player, Player, foreign_key: :light_player_id)
belongs_to(:dark_player, Player, foreign_key: :dark_player_id)
belongs_to(:bot, Bot, foreign_key: :bot_id)
field(:discord_thread_id, :string)
timestamps()
end
def changeset(game, attrs) do
game
|> cast(attrs, [
:fen,
:moves,
:turn,
:winner,
:status,
:last_move,
:light_player_id,
:dark_player_id,
:discord_thread_id,
:bot_id,
:game_moves
])
end
def new_game(initial_player_color, player_id, fen \\ @default_fen) do
Game.changeset(
%Game{
fen: fen
},
if(initial_player_color == :light,
do: %{light_player_id: player_id},
else: %{dark_player_id: player_id}
)
)
end
def update_with_status(%Game{} = game, move, fen, status) do
Game.changeset(
game,
%{
fen: fen,
moves: game.moves + 1,
turn: if(game.turn == :dark, do: :light, else: :dark),
last_move: move,
game_moves:
if(!is_nil(game) && game.game_moves != "", do: "#{game.game_moves} ", else: "") <> move
}
|> Map.merge(changeset_from_status(status))
)
end
def 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
end
|