Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@
background-color: #d18b47;
}

.square.selected {
border: 3px solid #0e0e0d;
}

.figure {
position: relative;
z-index: 0;
Expand Down Expand Up @@ -193,3 +197,21 @@
.figure.rook {
background-position-x: -182.5px;
}

.final_game {
font-size: 24px;
padding: 73px;
border-radius: 5px;
position: absolute;
top: 0px;
margin-top: 27%;
margin-left: 27%;
}
.final_game.white{
background-color: #f6cd9e;
border: 1px solid #d18b47;
}
.final_game.black{
background-color: #d18b47;
border: 1px solid #f6cd9e;
}
185 changes: 185 additions & 0 deletions lib/chess/movements.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
defmodule Chess.Movements do
@board_length 8

defguard is_inside_board(x, y) when x < @board_length and y < @board_length

defguard is_diagonal_movement(actual_x, actual_y, x, y)
when abs(actual_x - x) == abs(actual_y - y)

def movement(cells, piece, actual_position, {x, y} = new_position) when is_inside_board(x, y),
do: piece_movement(cells, piece, actual_position, new_position)

def movement(_, _, _, _), do: :error

# One position movement in any direction
defp piece_movement(cells, %{type: :king, color: color}, {actual_x, y}, {x, y})
when abs(actual_x - x) == 1 and actual_x < x,
do:
check_next_position(
cells,
color,
{actual_x + 1, y},
{1, 0},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :king, color: color}, {actual_x, y}, {x, y})
when abs(actual_x - x) == 1 and actual_x > x,
do:
check_next_position(
cells,
color,
{actual_x - 1, y},
{-1, 0},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :king, color: color}, {x, actual_y}, {x, y})
when abs(actual_y - y) == 1 and actual_y < y,
do:
check_next_position(
cells,
color,
{x, actual_y + 1},
{0, 1},
get_movements_number(actual_y, y)
)

defp piece_movement(cells, %{type: :king, color: color}, {x, actual_y}, {x, y})
when abs(actual_y - y) == 1 and actual_y > y,
do:
check_next_position(
cells,
color,
{x, actual_y - 1},
{0, -1},
get_movements_number(actual_y, y)
)

defp piece_movement(_, %{type: :king}, _, _), do: :error

# Lineal movement for queen
defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, y}, {x, y})
when actual_x < x,
do:
check_next_position(
cells,
color,
{actual_x + 1, y},
{1, 0},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, y}, {x, y})
when actual_x > x,
do:
check_next_position(
cells,
color,
{actual_x - 1, y},
{-1, 0},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :queen, color: color}, {x, actual_y}, {x, y})
when actual_y < y,
do:
check_next_position(
cells,
color,
{x, actual_y + 1},
{0, 1},
get_movements_number(actual_y, y)
)

defp piece_movement(cells, %{type: :queen, color: color}, {x, actual_y}, {x, y})
when actual_y > y,
do:
check_next_position(
cells,
color,
{x, actual_y - 1},
{0, -1},
get_movements_number(actual_y, y)
)

# Diagonal movement for queen
defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, actual_y}, {x, y})
when is_diagonal_movement(actual_x, actual_y, x, y) and actual_x < x and actual_y > y,
do:
check_next_position(
cells,
color,
{actual_x + 1, actual_y - 1},
{1, -1},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, actual_y}, {x, y})
when is_diagonal_movement(actual_x, actual_y, x, y) and actual_x > x and actual_y < y,
do:
check_next_position(
cells,
color,
{actual_x - 1, actual_y + 1},
{-1, 1},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, actual_y}, {x, y})
when is_diagonal_movement(actual_x, actual_y, x, y) and actual_x < x and actual_y < y,
do:
check_next_position(
cells,
color,
{actual_x - 1, actual_y - 1},
{-1, -1},
get_movements_number(actual_x, x)
)

defp piece_movement(cells, %{type: :queen, color: color}, {actual_x, actual_y}, {x, y})
when is_diagonal_movement(actual_x, actual_y, x, y) and actual_x > x and actual_y > y,
do:
check_next_position(
cells,
color,
{actual_x + 1, actual_y + 1},
{1, 1},
get_movements_number(actual_x, x)
)

defp piece_movement(_, %{type: :queen}, _, _), do: :error

defp piece_movement(_, _, _, _), do: {:ok, nil}

defp check_next_position(cells, color, {x, y} = position, {increment_x, increment_y}, n)
when n > 0 do
case position_availability(color, Map.get(cells, position)) do
{:ok, nil} ->
check_next_position(
cells,
color,
{x + increment_x, y + increment_y},
{increment_x, increment_y},
n - 1
)

_ ->
:error
end
end

defp check_next_position(cells, color, position, _, 0),
do: position_availability(color, Map.get(cells, position))

defp position_availability(_, nil), do: {:ok, nil}

defp position_availability(color, %{color: occupied_color}) when occupied_color == color,
do: :error

defp position_availability(color, %{color: occupied_color} = piece)
when occupied_color != color,
do: {:ok, piece}

defp get_movements_number(initial, final), do: abs(initial - final) - 1
end
54 changes: 54 additions & 0 deletions lib/chess/structs.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
defmodule Chess.Cell do
defstruct [:x, :y]
end

defmodule Chess.Piece do
defstruct [:type, :color]
end

defmodule Chess.Board do
defstruct cells: %{
{0, 0} => %Chess.Piece{type: :rook, color: :black},
{0, 1} => %Chess.Piece{type: :knight, color: :black},
{0, 2} => %Chess.Piece{type: :bishop, color: :black},
{0, 3} => %Chess.Piece{type: :queen, color: :black},
{0, 4} => %Chess.Piece{type: :king, color: :black},
{0, 5} => %Chess.Piece{type: :bishop, color: :black},
{0, 6} => %Chess.Piece{type: :knight, color: :black},
{0, 7} => %Chess.Piece{type: :rook, color: :black},
{1, 0} => %Chess.Piece{type: :pawn, color: :black},
{1, 1} => %Chess.Piece{type: :pawn, color: :black},
{1, 2} => %Chess.Piece{type: :pawn, color: :black},
{1, 3} => %Chess.Piece{type: :pawn, color: :black},
{1, 4} => %Chess.Piece{type: :pawn, color: :black},
{1, 5} => %Chess.Piece{type: :pawn, color: :black},
{1, 6} => %Chess.Piece{type: :pawn, color: :black},
{1, 7} => %Chess.Piece{type: :pawn, color: :black},
{6, 0} => %Chess.Piece{type: :pawn, color: :white},
{6, 1} => %Chess.Piece{type: :pawn, color: :white},
{6, 2} => %Chess.Piece{type: :pawn, color: :white},
{6, 3} => %Chess.Piece{type: :pawn, color: :white},
{6, 4} => %Chess.Piece{type: :pawn, color: :white},
{6, 5} => %Chess.Piece{type: :pawn, color: :white},
{6, 6} => %Chess.Piece{type: :pawn, color: :white},
{6, 7} => %Chess.Piece{type: :pawn, color: :white},
{7, 0} => %Chess.Piece{type: :rook, color: :white},
{7, 1} => %Chess.Piece{type: :knight, color: :white},
{7, 2} => %Chess.Piece{type: :bishop, color: :white},
{7, 3} => %Chess.Piece{type: :queen, color: :white},
{7, 4} => %Chess.Piece{type: :king, color: :white},
{7, 5} => %Chess.Piece{type: :bishop, color: :white},
{7, 6} => %Chess.Piece{type: :knight, color: :white},
{7, 7} => %Chess.Piece{type: :rook, color: :white}
}
end

defmodule Chess.Game do
defstruct name: nil,
initial_position: nil,
final_position: nil,
next_player: :white,
board: %Chess.Board{},
white: %{removed_pieces: []},
black: %{removed_pieces: []}
end
Loading