And I’ve kind of came up with some way: implementing a custom sort Protocol may do.
defprotocol ChessSorter do
@spec asc(any, any) :: boolean
def asc(_, _)
end
defmodule Coordinate do
defstruct [:x, :y]
defimpl ChessSorter, for: __MODULE__ do
def asc(%{x: x1, y: y1}, %{x: x2, y: y2}) when x1 == x2, do: y1 <= y2
def asc(%{x: x1}, %{x: x2}), x1 <= x2
end
end
defmodule Piece do
defstruct [:type]
defimpl ChessSorter, for: __MODULE__ do
@types %{
Pawn => 1,
Knight => 2,
Bishop => 3,
Rook => 4,
Queen => 5,
King => 6,
}
def asc(%{type: t1}, %{tpe: t2}), do: @types[t1] <= @types[t2]
end
end
defmodule Fighter
defstruct [ :owner, :piece, :position ]
defimpl ChessSorter, for: __MODULE__ do
def asc(
%{owner: o1, piece: p2, position: pos1},
%{owner: o2, piece: p2, position: pos2}
)
when o1 == o2 and p1 == p2,
do: ChessSorter.asc(pos1, pos2)
def asc(%{owner: o1, piece: p2}, %{owner: o2, piece: p2}) when o1 == o2,
do: ChessSorter.asc(p1, p2)
def asc(%{owner: :opponent}, %{owner: :player}), do: false
def asc(%{owner: :player}, %{owner: :opponent}), do: true
end
end
And then : fighters |> Enum.sort(&ChessSorter.asc/2). So this recursively does sorting down to basic Kernel.<= s.
But I am afraid this may be veery slow.
Is it?


















