def @range.to_s
return "%s -- %s" % self
end
+ if @rules[:list]
+ @check_method = "is_#{@rules[:addlang]}?"
+ # trick: if addlang was not in rules, this will be is_? which is
+ # not a method of the plugin
+ if @check_method and not @plugin.respond_to? @check_method
+ @check_method = nil
+ end
+ @check = Proc.new do |w|
+ wl = @rules[:list].include?(w)
+ if !wl and @check_method
+ if wl = @plugin.send(@check_method, w)
+ debug "adding #{w} to #{@rules[:addfile]}"
+ begin
+ File.open(@rules[:addfile], "a") do |f|
+ f.puts w
+ end
+ rescue Exception => e
+ error "failed to add #{w} to #{@rules[:addfile]}"
+ error e
+ end
+ end
+ end
+ wl
+ end
+ else
+ @check_method = "is_#{@lang}?"
+ @check = Proc.new { |w| @plugin.send(@check_method, w) }
+ end
end
def check(word)
return [:out, @range] if w < @range.first or w > @range.last
return [:ignore, @range] if w == @range.first or w == @range.last
# This is potentially slow (for languages that check online)
- return [:noexist, @range] unless @plugin.send("is_#{@lang}?", w)
+ return [:noexist, @range] unless @check.call(w)
debug "we like it"
# Check again if there was a winner in the mean time,
# and bail out if there was
:good => /(?:singular )?noun|verb|adj/,
:first => 'abacus',
:last => 'zuni',
- :url => "http://www.chambersharrap.co.uk/chambers/features/chref/chref.py/main?query=%s&title=21st",
+ :url => "http://www.chambers.co.uk/search.php?query=%s&title=21st",
:listener => /^[a-z]+$/
},
}
- japanese_wordlist = "#{@bot.botclass}/azgame/wordlist-japanese"
- if File.exist?(japanese_wordlist)
- words = File.readlines(japanese_wordlist) \
- .map {|line| line.strip} .uniq
+ @autoadd_base = datafile "autoadd-"
+ end
+
+ def initialize_wordlist(params)
+ lang = params[:lang]
+ addlang = params[:addlang]
+ autoadd = @autoadd_base + addlang.to_s
+ if Wordlist.exist?(@bot, lang)
+ # wordlists are assumed to be UTF-8, but we need to strip the BOM, if present
+ words = Wordlist.get(@bot, lang)
+ if addlang and File.exist?(autoadd)
+ word += File.readlines(autoadd).map {|line| line.sub("\xef\xbb\xbf",'').strip}
+ end
+ words.uniq!
+ words.sort!
if(words.length >= 4) # something to guess
- @rules[:japanese] = {
+ rules = {
:good => /^\S+$/,
:list => words,
:first => words[0],
:last => words[-1],
+ :addlang => addlang,
+ :addfile => autoadd,
:listener => /^\S+$/
}
- debug "Japanese wordlist loaded, #{@rules[:japanese][:list].length} lines; first word: #{@rules[:japanese][:first]}, last word: #{@rules[:japanese][:last]}"
+ debug "#{lang} wordlist loaded, #{rules[:list].length} lines; first word: #{rules[:first]}, last word: #{rules[:last]}"
+ return rules
end
end
+ return false
end
def save
@registry[:wordcache] = @wordcache
end
- def listen(m)
- return unless m.kind_of?(PrivMessage)
+ def message(m)
return if m.channel.nil? or m.address?
k = m.channel.downcase.to_s # to_sym?
return unless @games.key?(k)
m.reply _("couldn't think of anything ...")
return
end
+ m.reply _("got it!")
+ @games[k] = AzGame.new(self, lang, @rules[lang], word)
+ elsif !@rules.has_key?(lang) and rules = initialize_wordlist(params)
+ word = random_pick_wordlist(rules)
+ if word.empty?
+ m.reply _("couldn't think of anything ...")
+ return
+ end
+ m.reply _("got it!")
+ @games[k] = AzGame.new(self, lang, rules, word)
else
m.reply _("I can't play A-Z in %{lang}, sorry") % {:lang => lang}
return
end
- m.reply _("got it!")
- @games[k] = AzGame.new(self, lang, @rules[lang], word)
end
tr = @games[k].total_tries
# this message building code is rewritten to make translation easier
if wc[word].key?(:when)
tr = _("%{word} learned from %{user} on %{date}") % {:word => word, :user => wc[word][:who], :date => wc[word][:when]}
else
- tr = _("%{word} learned from %{user}") % {:word => word, :user => wc[word][:who]}
+ tr = _("%{word} learned from %{user}") % {:word => word, :user => wc[word][:who]}
end
m.reply tr
- when :delete
+ when :delete
if pars.empty?
m.reply _("provide a word")
return
end
end
- def is_japanese?(word)
- @rules[:japanese][:list].include?(word)
- end
-
# return integer between min and max, inclusive
def rand_between(min, max)
rand(max - min + 1) + min
end
- def random_pick_japanese(min=nil, max=nil)
- rules = @rules[:japanese]
+ def random_pick_wordlist(rules, min=nil, max=nil)
min = rules[:first] if min.nil_or_empty?
max = rules[:last] if max.nil_or_empty?
debug "Randomly picking word between #{min} and #{max}"
debug "getting random word from dictionary, matching #{random}"
p = @bot.httputil.get(rules[:url] % CGI.escape(random))
debug p
+ raise 'unable to get search results' if not p.match /id="fullsearchresults"/i
lemmi = Array.new
good = rules[:good]
# We look for a lemma composed by a single word and of length at least two
when 'play'
return _("az => start a game if none is running, show the current word range otherwise; you can say 'az <language>' if you want to play in a language different from the current bot default")
end
- return _("az topics: play, rules, cancel, manage, check")
+ langs = @rules.keys
+ wls = Wordlist.list(@bot)
+ return [
+ _("az topics: play, rules, cancel, manage, check"),
+ _("available languages: %{langs}") % { :langs => langs.join(", ") },
+ wls.empty? ? nil : _("available wordlists: %{wls}") % { :wls => wls.join(", ") },
+ ].compact.join(". ")
+
end
end
plugin.map 'az [:lang] word :cmd *params', :action=>'wordlist', :defaults => { :lang => nil, :cmd => 'count', :params => [] }, :auth_path => '!az::edit!'
plugin.map 'az cancel', :action=>'stop_game', :private => false
plugin.map 'az check :word', :action => 'manual_word_check', :private => false
-plugin.map 'az [play] [:lang]', :action=>'start_game', :private => false, :defaults => { :lang => nil }
+plugin.map 'az [play] [:lang] [autoadd :addlang]', :action=>'start_game', :private => false, :defaults => { :lang => nil, :addlang => nil }