defmodule LSG.IRC.DiceHandler do
require Logger
@moduledoc """
# dice
* **!dice `[1 | lancés]` `[6 | faces]`**: lance une ou plusieurs fois un dé de 6 ou autre faces
"""
@default_faces 6
@default_rolls 1
@max_rolls 50
def short_irc_doc, do: "!dice (jeter un dé)"
defstruct client: nil, dets: nil
def irc_doc, do: @moduledoc
def start_link(client) do
GenServer.start_link(__MODULE__, [client])
end
def init([client]) do
ExIRC.Client.add_handler(client, self())
{:ok, _} = Registry.register(IRC.PubSub, "dice", [])
{:ok, %__MODULE__{client: client}}
end
def handle_info({:received, "!dice", sender, chan}, state) do
roll(state, sender, chan, @default_faces, @default_rolls)
{:noreply, state}
end
def handle_info({:received, "!dice "<>params, sender, chan}, state) do
{rolls, faces} = case String.split(params, " ", parts: 2) do
[faces, rolls] -> {rolls, faces}
[rolls] -> {rolls, @default_faces}
end
to_integer = fn(string, default) ->
case Integer.parse(string) do
{int, _} -> int
_ -> default
end
end
{faces, rolls} = {to_integer.(faces, @default_faces), to_integer.(rolls, @default_rolls)}
roll(state, sender, chan, faces, rolls)
{:noreply, state}
end
def handle_info(info, state) do
{:noreply, state}
end
defp roll(state, %{nick: nick}, chan, faces, 1) when faces > 0 do
random = :crypto.rand_uniform(1, faces+1)
ExIRC.Client.msg(state.client, :privmsg, chan, "#{nick} dice: #{random}")
end
defp roll(state, %{nick: nick}, chan, faces, rolls) when faces > 0 and rolls > 0 and rolls <= @max_rolls do
{results, acc} = Enum.map_reduce(Range.new(1, rolls), 0, fn(i, acc) ->
random = :crypto.rand_uniform(1, faces+1)
{random, acc + random}
end)
results = Enum.join(results, "; ")
ExIRC.Client.msg(state.client, :privmsg, chan, "#{nick} dice [#{acc}] #{results}")
end
defp roll(_, _, _, _, _), do: nil
end