Add reply_chance to markov chains and markov commands
Every time a user sends a message, there is now a chance that markov will reply with a random message based on what they said. !markov chance allows lookups and setting of the chance that a user may receive a message. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -3,7 +3,7 @@ defmodule Omnibot.Contrib.Markov.Chain do
|
||||
require Logger
|
||||
|
||||
@enforce_keys [:order]
|
||||
defstruct order: 2, chain: %{}
|
||||
defstruct order: 2, chain: %{}, reply_chance: 0.01
|
||||
|
||||
def train(chain, line) when is_binary(line) do
|
||||
train(chain, line |> String.split(~r/\s+/))
|
||||
|
||||
@@ -51,6 +51,14 @@ defmodule Omnibot.Contrib.Markov.ChainServer do
|
||||
GenServer.call(server, :chain_sum)
|
||||
end
|
||||
|
||||
def reply_chance(server) do
|
||||
GenServer.call(server, :reply_chance)
|
||||
end
|
||||
|
||||
def set_reply_chance(server, chance) do
|
||||
GenServer.cast(server, {:set_reply_chance, chance})
|
||||
end
|
||||
|
||||
## Server callbacks
|
||||
|
||||
@impl true
|
||||
@@ -122,4 +130,14 @@ defmodule Omnibot.Contrib.Markov.ChainServer do
|
||||
def handle_call(:chain_sum, _from, state = {chain, _channel, _user}) do
|
||||
{:reply, Markov.Chain.chain_sum(chain), state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call(:reply_chance, _from, state = {chain, _channel, _user}) do
|
||||
{:reply, chain.reply_chance, state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_cast({:set_reply_chance, chance}, {chain, channel, user}) when is_float(chance) or chance == 0 do
|
||||
{:noreply, {%Markov.Chain{chain | reply_chance: chance}, channel, user}}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule Omnibot.Contrib.Markov do
|
||||
alias Omnibot.{Contrib.Markov.ChainServer, Util}
|
||||
require Logger
|
||||
|
||||
@default_config save_dir: "markov", order: 2, save_every: 5 * 60, ignore: []
|
||||
@default_config save_dir: "markov", order: 2, save_every: 5 * 60, ignore: [], max_reply_chance: 0.01
|
||||
|
||||
@registry __MODULE__.Registry
|
||||
@supervisor __MODULE__.ChainSupervisor
|
||||
@@ -22,18 +22,20 @@ defmodule Omnibot.Contrib.Markov do
|
||||
end
|
||||
|
||||
command "!markov", ["force"] do
|
||||
reply = chain_server(channel, nick) |> ChainServer.generate()
|
||||
Irc.send_to(irc, channel, "#{nick}: #{reply}")
|
||||
do_markov_message(irc, channel, nick, nick)
|
||||
end
|
||||
|
||||
# !markov emulate <name>, except it's !markov force <name>
|
||||
command "!markov", ["force", emulate] do
|
||||
do_markov_message(irc, channel, nick, emulate)
|
||||
end
|
||||
|
||||
command "!markov", ["emulate", emulate] do
|
||||
reply = chain_server(channel, emulate) |> ChainServer.generate()
|
||||
Irc.send_to(irc, channel, "#{nick}: #{reply}")
|
||||
do_markov_message(irc, channel, nick, emulate)
|
||||
end
|
||||
|
||||
command "!markov", ["all"] do
|
||||
reply = chain_server(channel, :all) |> ChainServer.generate()
|
||||
Irc.send_to(irc, channel, "#{nick}: #{reply}")
|
||||
do_markov_message(irc, channel, nick, :all)
|
||||
end
|
||||
|
||||
command "!markov", ["status"] do
|
||||
@@ -43,6 +45,23 @@ defmodule Omnibot.Contrib.Markov do
|
||||
Irc.send_to(irc, channel, "#{nick}: You are worth #{ratio |> Float.round(4)}% of the channel")
|
||||
end
|
||||
|
||||
command "!markov", ["chance"] do
|
||||
chance = reply_chance(channel, nick)
|
||||
Irc.send_to(irc, channel, "#{nick}: Your reply chance is #{chance}")
|
||||
end
|
||||
|
||||
command "!markov", ["chance", chance] do
|
||||
{chance, ""} = Float.parse(chance)
|
||||
chance = min(chance, cfg()[:max_reply_chance]) |> max(0)
|
||||
chain_server(channel, nick) |> ChainServer.set_reply_chance(chance)
|
||||
Irc.send_to(irc, channel, "#{nick}: Your reply chance is now #{chance}")
|
||||
end
|
||||
|
||||
defp do_markov_message(irc, channel, sender, user) do
|
||||
reply = chain_server(channel, user) |> ChainServer.generate()
|
||||
Irc.send_to(irc, channel, "#{sender}: #{reply}")
|
||||
end
|
||||
|
||||
def save_dir() do
|
||||
cfg()[:save_dir]
|
||||
end
|
||||
@@ -88,13 +107,22 @@ defmodule Omnibot.Contrib.Markov do
|
||||
Logger.info("Saved markov chains in #{stop - start} seconds")
|
||||
end
|
||||
|
||||
defp reply_chance(channel, user) do
|
||||
chain_server(channel, user) |> ChainServer.reply_chance()
|
||||
end
|
||||
|
||||
@impl true
|
||||
def on_channel_msg(_irc, channel, nick, msg) do
|
||||
def on_channel_msg(irc, channel, nick, msg) do
|
||||
# self-messages are already ignored, so just check the configured ignore-list
|
||||
filter = nick in cfg()[:ignore]
|
||||
|| (String.trim(msg) |> String.starts_with?("!"))
|
||||
if !filter do
|
||||
train(channel, nick, msg)
|
||||
|
||||
# Maybe send user a message
|
||||
if IO.inspect(:rand.uniform()) < IO.inspect(reply_chance(channel, nick)) do
|
||||
do_markov_message(irc, channel, nick, nick)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user