summaryrefslogtreecommitdiff
path: root/lib/lsg_irc/dice_handler.ex
blob: 7ff7b4d8a8a8c7b762388631ef50552204d6bd99 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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