BrotherCrow

BrotherCrow

Creating a dice-roller in Elixir. D-10 and D-100 giving me fits.

I’m very new to programming, and elixir is my first language. If my verbage or vocabulary are slightly off, I appreciate your understanding.

The Scope:

I’m working on an RNG modeled on tabletop dice. A d2, d4, d6, d8, d10, d12, d20 and d100. These will be called by functions needing to draw from charts, and will hopefully be rolled direclty by users as needed. As such, I need the results to be consistant and usable.

The Problem:

Anything over d8 is giving me fits in its result. It produces random seeming letters or punctuation instead of a numerical result.

I understand this is an artifact of how elixir and erlang sort of… co-mingle numbers and letters. The details and specifics of that are still a bit beyond me, I confess. I solved this issue in one specific instance, by piping the result of a single d100 into an Enum.sum. This doesn’t work for multiple dice, and won’t work globally.

The Code
Dice Module:

defmodule Plotgenerator.Dice do

@moduledoc """

Dice Functions

The basic dice functions are very simple, but effective.


A function call for 'Dice.dX(Y)', where X is the sides on the die and Y is the number being rolled, will return a list of results. This works by feeding the sides and count argument to Dice.roll, which in turn, calls on the Dice.d(sides) function.

The Dice.dX functions can be bypassed by using roll directly and providing it with the sides and count arguments.

Additionally, a functioncall of Dice.dX() with no arguments, will cause a single result of the die-type to be generated and returned.
"""

# NOTE this format replicates the process for d2(count) and provides a count of 1 for a d2 function with no argument.
  def d2(), do: d2(1)


  # NOTE this d2 command is the standard, providing a
  def d2(count) do
    roll(2, count)
  end


 # NOTE this format replicates the process for d2(), but provides a default value for the count. This is more complicated than the previous two iterations. We are not using it, but I am providing it for completeness.
  #
  #  def d2(count \\ 1) do
  #   roll(2, count)
  # end

# NOTE FOR ELIXIR FORUM - I have cut the other dice rollers from this, because they are exact formulaeic copies of the above examples, save for different numerals. 
  
# NOTE the defp deffinition means its private and can only be called by this module. This keeps other modules from accidentally calling it. Only use it if there is no other case in which another module may -need- to call it.
  defp d(sides) do
   Enum.random(1..sides)
  end

  @spec roll(pos_integer, pos_integer) :: list
  def roll(sides, count) when is_integer(count) and count > 0 and is_integer(sides) and sides > 1 do
    (1..count |> Enum.map(fn _-> d(sides) end))
  end

Thats the die rolling module.

Here is where I am trying to use it, and initially ran into the problem.

    def create(attributes \\ %{}) do
      defaults = %{
        shape: Plotgenerator.pick("traps/effect_shape"),
        size: area_select(),
        damage: Plotgenerator.pick("traps/damage_type"),
        difficulty: Enum.random(1..10),
        effect: Plotgenerator.pick("traps/trap_effect"),
        trigger_point: Plotgenerator.pick("traps/trap_locations"),
        control_point: Plotgenerator.pick("traps/trap_locations"),
        focal_point: Plotgenerator.pick("traps/trap_locations"),
        mechanism_point: Plotgenerator.pick("traps/trap_locations"),
        object: Plotgenerator.pick("traps/trigger_objects"),
        reset: Plotgenerator.pick("traps/reset_type"),
        time: Plotgenerator.pick("traps/reset_time"),
        triggered_by: Plotgenerator.pick("traps/trigger_action")
      }
      struct(__MODULE__, Map.merge(defaults, attributes))
    end

    # NOTE: when returning this value initially, it was printing as random characters. Thats because a list of numbers have corrolation to charlist, and it was offering that. By adding enum.sum to the end of it, we ensure it returns a number.

    def area_select() do
      Plotgenerator.Dice.d100(1) |> Enum.sum
    end

I solved the issue with the enum.sum on area_select(), but this is not a workable solution on the whole. Below is an example of the return, when I do not engage the enum.sum function on the result.

Note: I know the text doesn’t make a lot of sense. This is still getting the information to populate properly. I’ll clean up the template later.

If triggered, this trap has the effect of Illusion. If triggered, this trap effects a Geometric shaped area, with a size of E. This area is centered on Floor. The lethality of the trap is 8 out of 10. 

If triggered, this trap has the effect of Damage. If triggered, this trap effects a Cone shaped area, with a size of ;. This area is centered on Window, drain or vent. The lethality of the trap is 3 out of 10. 

If triggered, this trap has the effect of Alarm. If triggered, this trap effects a Wall shaped area, with a size of %. This area is centered on Stairs. The lethality of the trap is 6 out of 10. 

If triggered, this trap has the effect of Spell. If triggered, this trap effects a Wall shaped area, with a size of +. This area is centered on Stairs. The lethality of the trap is 6 out of 10. 

If triggered, this trap has the effect of Illusion. If triggered, this trap effects a Wall shaped area, with a size of M. This area is centered on Stairs. The lethality of the trap is 6 out of 10. 

Thank you for any suggestions, solutions or feedback you can offer.

Most Liked

ruslandoga

ruslandoga

Sorry, I haven’t read the whole discussion but still thought I’d chime in …

Inspecting lists of integers might still result in unexpected output:

iex(1)> "some string with #{inspect([50, 51])}"
"some string with '23'"

# can be "fixed" with `[charlists: :as:lists]` option, for more see https://hexdocs.pm/elixir/1.12/Inspect.Opts.html
iex(2)> "some string with #{inspect([50, 51], charlists: :as_lists)}"
"some string with [50, 51]"

Where Next?

Popular in Questions Top

New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> somethi...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
yawaramin
In the Dialyzer docs ( dialyzer — OTP 29.0.2 (dialyzer 6.0.1) ), there is a way to turn off a specific warning for a function: -dialyzer...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29703 241
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43806 214
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New

We're in Beta

About us Mission Statement