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