ndac_todoroki
Thinking of implementing a Chess game in Elixir, I created a module which will represent a chess piece as a struct.
defmodule Piece do
alias __MODULE__, as: Piece
@piece_types ~w(King Queen Rook Bishop Knight Pawn)a
@type type :: :King | :Queen | :Rook | :Bishop | :Knight | :Pawn
defstruct [:type]
@type t :: %Piece{ type: type() }
defguard is_type(piece_type) when piece_type in @piece_types
def new(type) when is_type(type), do: %Piece{type: type}
end
then there is a struct that represents an active piece:
defmodule Fighter do
alias __MODULE__, as: Fighter
@type owner :: :player | :opponent
defstruct [ :owner, :piece, :position ]
@type t :: %Fighter{ owner: owner(), piece: Piece.t(), position: BoardCoordinate.t }
end
So I have a List of Fighters when the game starts. I came to a circumstance where I want to sort the Fighters.
The result should be sorted first by fighter.owner, then by fighter.piece.type, and then by fighter.position, so it will be
- my king
- my queen
… - my most left-top pawn
- my secondly left-top pawn
… - opponent’s king
- opponent’s queen
…
and so on. Can I perform this on a single custom sort? (Like performing fighters |> Fighter.sort())?
For that I thought setting a default sort algorism for each struct type could be a simple way, but I couldn’t have sorted(!) this out.
Any help and thoughts are welcomed!
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
Other Trending Topics
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #ai
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
kokolegorille
Not that it helps with your sorting question, but I have done two chess libs in Elixir…
The second is a translated from Erlang and generates all possible moves. Maybe it helps
japplegame
My AVLTree implementation with custom sorting function: GitHub - japplegame/avl_tree: Pure Elixir AVL tree implementation · GitHub
ndac_todoroki
Thanks, but this is just an example for a more generic question… Sorting your nested structs in ways you desire to.
But I’m gonna have fun with those repos!
ndac_todoroki
Giving a custom function to (e.g.
Enum.sort/3) was what I first considered, but it doesn’t help when you want to sort nested structs…But anyway, I like your AVLTree! It is very simple. Thanks!
ndac_todoroki
And I’ve kind of came up with some way: implementing a custom sort Protocol may do.
And then :
fighters |> Enum.sort(&ChessSorter.asc/2). So this recursively does sorting down to basicKernel.<=s.But I am afraid this may be veery slow.
Is it?
Qqwy
Elixir’s sorting function is stable. This means that you can first sort the whole list of fighters on the least-important condition, then on the second-least important condition , etc. and finally on the most important condtion, and they will end up in the order you’d expect.
So in your case
And, by taking advantage of the fact that tuples are ordered elementwise (we look at the next element only if the current element is equal), we could write it like this instead as well:
However, this will not give the answer you’d like yet, because many things are represented by symbols, which by default are sorted alphabetically (whereas you’d like the given order
King > Queen > Bishop > ...andplayer > opponent. The translation functions you wrote for your custom sorter would indeed be a solution to this.It is possible to automate that a little, by creating a map of the numerically ordered equivalents (like
piece_type_ordering = piece_types |> Enum.with_index |> Enum.into(%{})), which you’d want to generate at compile time, so you can just write a function then that will turn a given thing into their ordering.I think a protocol like the following might make sense:
whose implementation for e.g.
%Piecewould simply return the number that is stored for the given type’s symbol key.And for
%Fighter, it would return e.g.ndac_todoroki
Wow, this is amazing how minimum the code could be. It was a whole new study for me. Thanks for the information!!
japplegame
With
Orderableprotocol you also can use AVLTree like this:All inserted elements will be automatically sorted.
Qqwy
@japplegame Interesting! I wrote a library a while back to build and work with Priority Queues called prioqueue, which abstracts away the implementation details of how this queue is maintained, and lets you plug in your own. I think making an AVLTree implementation would be a great idea! When will you upload AVLTree to Hex.PM?
@ndac_todoroki Glad to be able to help. I guess the
Orderableprotocol could be wrapped in a library, since I think it is rather common to want to do this kind of stuff. We might even provide built-in implementations for common ordered enumerables that callOrderable.orderablefor all their contained elements… Let me conjure up something!Qqwy
Done! The orderable library has been built, tested, documented and published.