Skip to content

Instantly share code, notes, and snippets.

@kylef
Created March 14, 2010 15:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylef/332042 to your computer and use it in GitHub Desktop.
Save kylef/332042 to your computer and use it in GitHub Desktop.
MagicWord plugin for ZMB bot
class MagicWord
attr_accessor :words, :users
def initialize(sender, settings);
@words = settings['words'] if settings.has_key?('words')
@words = Hash.new if not @words
@users = settings['users'] if settings.has_key?('users')
@users = Array.new if not @users
end
def settings
{ 'words' => @words, 'users' => @users }
end
def random_user(users)
username = users[rand(users.size)].username
@users << username
username
end
def count(username)
@users.reject{ |user| username != user }.size
end
def delete_one(username)
@users.delete_at(@users.index(username))
end
def commands
{
'set-word' => [:set, {
:permission => 'authenticated',
:help => 'Set your magic word',
:usage => 'word' }],
'words?' => [:words_command, 0, { :help => 'See how many words have been set.' }],
'donate-word' => [:donate, {
:permission => 'authenticated',
:help => 'Donate your word too another user',
:usage => 'username' }],
'word-stats' => [:stats, 0],
'add-user' => [:add_user, { :permission => 'admin' }],
'rm-user' => [:del_user, { :permission => 'admin' }],
'remind' => [:remind, 0, {
:permission => 'authenticated',
:help => 'Remind you of the words you set.' }],
'flush' => [:flush, 0, { :permission => 'admin' }],
}
end
def set(e, word)
if @users.include?(e.user.username) then
if @words.include?(word) then
'Word already set'
else
delete_one(e.user.username)
@words[word] = { 'setter' => e.user.username, 'mentions' => 0 }
"word #{word} has been set"
end
else
'permission denied'
end
end
def donate(e, username=nil)
username = random_user(e.users.users) if not username
if @users.include?(e.user.username) then
if user = e.users.user!(username) then
if count(user.username) >= 2 then
"User already has >= 2 words"
else
delete_one(e.user.username)
@users << username
"You have donated your word too #{username}"
end
else
"no such user #{username}"
end
else
'permission denied'
end
end
def words_command(e)
if @users.size > 0 then
u = {}
@users.each do |user|
if u.has_key?(user) then
u[user] += 1
else
u[user] = 1
end
end
"There are #{@words.size} words set, and #{u.map{ |user, count| "#{user} (#{count})" }.join(', ')} can set a word. #{total_mentions} total mentions"
else
"There are #{@words.size} words set, and no one can set a word. #{total_mentions} total mentions"
end
end
def stats(e)
users = {}
@words.each do |k,v|
if users.has_key?(v['setter']) then
users[v['setter']] += 1
else
users[v['setter']] = 1
end
end
#users.invert.sort.map{ |count, user| "#{user} (#{count} words)"}.reverse.join(', ')
users.map{ |user, count| "#{user} (#{count} words)"}.reverse.join(', ')
end
def remind(e)
@words.reject{ |word, args| args['setter'] != e.user.username }.map{ |word, args| "#{word} (#{args['mentions']})" }.join(', ')
end
def flush(e)
@users = Array.new
end
def add_user(e, username)
@users << username
"#{username} has been added."
end
def del_user(e, username)
delete_one(username)
"#{username} has been deleted."
end
def total_mentions
@words.values.map{|v| v['mentions']}.sum
end
def score(e, word)
mentions = Float(@words[word]['mentions'])
mentions_ratio = mentions / total_mentions
words_ration = 1 - (1 / @words.count)
[Integer(mentions_ratio * 25), Integer((1 - mentions_ratio) * words_ration * 5)]
end
def event(sender, e)
if e.message? and not e.private? and e.respond_to?('user') and e.user.authenticated? then
@words.reject{ |word, v| not (e.message =~ /#{Regexp.escape(word)}/i) }.each do |word, args|
if e.user.username == args['setter'] then
args['mentions'] += 1
else
e.reply("#{e.user.username} got the word (#{word})!")
if count(e.user.username) >= 2 then
e.reply("Word donated too #{random_user(e.users.users.reject{|user| user == e.user.username})}")
else
@users << e.user.username
end
@words.delete(word)
if e.respond_to?('bank') then
setter_score, guess_score = score(e, word)
e.bank.transaction(guess_score, "Guessed #{word} on magicword")
e.points.account(args['setter']).transaction(setter_score, "Set #{word} magicword")
"Setter got #{setter_score}, and guesser got #{guess_score}"
end
end
end
end
end
end
Plugin.define do
name 'magicword'
object MagicWord
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment