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.