As you may know, I am slowly/painfully writing an Elixir book.
There is a code example that I’ve written in Ruby – a simple
robot-type “capture the flag” game. (Not a real game, just a
coding exercise.)
I’m about to port the Ruby code to Elixir. If anyone wants to
look/comment/help, please feel free. (Those who contribute
will be mentioned in the acknowledgements fwiw.)
I think you can refactor the show_cell function to remove the conditional and assignments.
defmodule Grid do
def show_cell(grid, xx, yy) do
grid
|> Grid.get({:red, xx, yy})
|> Bot.to_string
|> IO.write
end
end
defmodule Bot do
def to_string(nil), do: "-"
end
Merged. Appreciated. Just remember we may be in different time zones.
By the way The Ruby version is not “ideal” either. The non-threaded version is
easier to watch/understand, but the threaded one is a massive free-for-all, and I
am not sure how I want to fix it.
Tip: here you have a tutorial about creating a command line application in Elixir.
I will create a next PR in current week (first version of this app that works from command line).
Hey, I added new PR.
I rewrite Elixir code to much some guidelines.
Now we have Agent that stores our game data, each bot have AI Erlang process (TODO: turn).
Your project is now really configurable. For example you can setup 2 to 4 teams with their colours and names dynamically.
I added some two dependencies bunt to easy format grid and credo to keep code readability.
Review my code and say if you don’t understand something. The code is not 10 lines, so bigger explanation may be really long. Let me know what you think about my version. If you accept it I will implement simple AI.
I wrote that I add this PR in current week, so it’s not complete yet (AI and credo checks).
Run code several times to see different results.
Tip: I created new modules inside Vexil module, because it’s not a “Hello World” tutorial and you are going to show good code example. In your old code you have for example: Grid module which may conflict in other projects if they organise code like you.
These modules are for defining structs by defstruct. Here you have details about structs.
I think it’s best way to store data like that. Of course I can forgot about other things. Feel free to add propositions to my version of code.
The main module (to manage grid) is Vexil.Battleground. It stores grid in Vexil.Agent and have functions to manipulate this grid. For example to store Bot or Flag structure. I wrote some function and split this module to some imports, so: Vexil.Battlegroundimports: Vexil.Battleground.TeamUtils. TeamUtils (like a normal team) importsVexil.Battleground.BotUtils and Vexil.Battleground.FlagUtils and both of them importsVexil.Battleground.GridUtils. Note: in your Ruby code Flag extends Bot, so it can move(!). I think it’s not a good to read your Ruby code, because Flag will not move at all.
In my code FlagUtilsimports only functions for calculate position based on corner and spawn item. Ok, but why it’s all for Battleground? It’s simple. Bot and Flag do not need to calculate position from corner. I think my version is easiest to understand (if you know how import works).
More, flag do not think and bot do not see full grid, so they should not calculate coords. I know it’s not a bug, but it’s not easy to read - am I wrong?