def check(word)\r
w = word.downcase\r
debug "checking #{w} for #{@word} in #{@range}"\r
+ # Since we're called threaded, bail out early if a winner\r
+ # was assigned already\r
+ return [:ignore, nil] if @winner\r
return [:bingo, nil] if w == @word\r
return [:out, @range] if w < @range.first or w > @range.last\r
return [:ignore, @range] if w == @range.first or w == @range.last\r
+ # This is potentially slow (for languages that check online)\r
return [:noexist, @range] unless @plugin.send("is_#{@lang}?", w)\r
debug "we like it"\r
- if w < @word\r
+ # Check again if there was a winner in the mean time,\r
+ # and bail out if there was\r
+ return [:ignore, nil] if @winner\r
+ if w < @word and w > @range.first\r
@range.first.replace(w)\r
- else\r
+ return [:in, @range]\r
+ elsif w > @word and w < @range.last\r
@range.last.replace(w)\r
+ return [:in, @range]\r
end\r
- return [:in, @range]\r
+ return [:out, @range]\r
end\r
\r
-# TODO scoring: base score is t = ceil(100*exp(-(n-1)^2/50))+p for n attempts\r
+# TODO scoring: base score is t = ceil(100*exp(-((n-1)^2)/(50^2)))+p for n attempts\r
# done by p players; players that didn't win but contributed\r
# with a attempts will get t*a/n points\r
\r
def score\r
n = @total_tries\r
p = @tries.keys.length\r
- t = (100*exp(-(n-1)**2/50**2)).ceil + p\r
+ t = (100*exp(-((n-1)**2)/(50.0**2))).ceil + p\r
debug "Total score: #{t}"\r
ret = Hash.new\r
@tries.each { |k, a|\r
- ret[k] = [t*a/n, "%d %s" % [a, a > 1 ? "tries" : "try"]]\r
+ ret[k] = [t*a/n, n_("%{count} try", "%{count} tries", a) % {:count => a}]\r
}\r
if @winner\r
debug "replacing winner score of %d with %d" % [ret[@winner].first, t]\r
tries = ret[@winner].last\r
- ret[@winner] = [t, "winner, #{tries}"]\r
+ ret[@winner] = [t, _("winner, %{tries}") % {:tries => tries}]\r
end\r
return ret.sort_by { |h| h.last.first }.reverse\r
end\r
else\r
@wordcache = Hash.new\r
end\r
- debug "\n\n\nA-Z wordcache: #{@wordcache.inspect}\n\n\n"\r
+ debug "A-Z wordcache: #{@wordcache.pretty_inspect}"\r
\r
@rules = {\r
:italian => {\r
end\r
\r
def word_check(m, k, word)\r
- isit = @games[k].check(word)\r
- case isit.first\r
- when :bingo\r
- m.reply "#{Bold}BINGO!#{Bold}: the word was #{Underline}#{word}#{Underline}. Congrats, #{Bold}#{m.sourcenick}#{Bold}!"\r
- @games[k].total_tries += 1\r
- @games[k].tries[m.source] += 1\r
- @games[k].winner = m.source\r
- ar = @games[k].score.inject([]) { |res, kv|\r
- res.push("%s: %d (%s)" % kv.flatten)\r
- }\r
- m.reply "The game was won after #{@games[k].total_tries} tries. Scores for this game: #{ar.join('; ')}"\r
- @games.delete(k)\r
- when :out\r
- m.reply "#{word} is not in the range #{Bold}#{isit.last}#{Bold}" if m.address?\r
- when :noexist\r
- m.reply "#{word} doesn't exist or is not acceptable for the game"\r
- @games[k].total_failed += 1\r
- @games[k].failed[m.source] += 1\r
- when :in\r
- m.reply "close, but no cigar. New range: #{Bold}#{isit.last}#{Bold}"\r
- @games[k].total_tries += 1\r
- @games[k].tries[m.source] += 1\r
- when :ignore\r
- m.reply "#{word} is already one of the range extrema: #{isit.last}" if m.address?\r
- else\r
- m.reply "hm, something went wrong while verifying #{word}"\r
- end\r
+ # Not really safe ... what happens\r
+ Thread.new {\r
+ isit = @games[k].check(word)\r
+ case isit.first\r
+ when :bingo\r
+ m.reply _("%{bold}BINGO!%{bold} the word was %{underline}%{word}%{underline}. Congrats, %{bold}%{player}%{bold}!") % {:bold => Bold, :underline => Underline, :word => word, :player => m.sourcenick}\r
+ @games[k].total_tries += 1\r
+ @games[k].tries[m.source] += 1\r
+ @games[k].winner = m.source\r
+ ar = @games[k].score.inject([]) { |res, kv|\r
+ res.push("%s: %d (%s)" % kv.flatten)\r
+ }\r
+ m.reply _("The game was won after %{tries} tries. Scores for this game: %{scores}") % {:tries => @games[k].total_tries, :scores => ar.join('; ')}\r
+ @games.delete(k)\r
+ when :out\r
+ m.reply _("%{word} is not in the range %{bold}%{range}%{bold}") % {:word => word, :bold => Bold, :range => isit.last} if m.address?\r
+ when :noexist\r
+ # bail out early if the game was won in the mean time\r
+ return if !@games[k] or @games[k].winner\r
+ m.reply _("%{word} doesn't exist or is not acceptable for the game") % {:word => word}\r
+ @games[k].total_failed += 1\r
+ @games[k].failed[m.source] += 1\r
+ when :in\r
+ # bail out early if the game was won in the mean time\r
+ return if !@games[k] or @games[k].winner\r
+ m.reply _("close, but no cigar. New range: %{bold}%{range}%{bold}") % {:bold => Bold, :range => isit.last}\r
+ @games[k].total_tries += 1\r
+ @games[k].tries[m.source] += 1\r
+ when :ignore\r
+ m.reply _("%{word} is already one of the range extrema: %{range}") % {:word => word, :range => isit.last} if m.address?\r
+ else\r
+ m.reply _("hm, something went wrong while verifying %{word}")\r
+ end\r
+ }\r
end\r
\r
def manual_word_check(m, params)\r
k = m.channel.downcase.to_s\r
word = params[:word].downcase\r
if not @games.key?(k)\r
- m.reply "no A-Z game running here, can't check if #{word} is valid, can I?"\r
+ m.reply _("no A-Z game running here, can't check if %{word} is valid, can I?")\r
return\r
end\r
if word !~ /^\S+$/\r
- m.reply "I only accept single words composed by letters only, sorry"\r
+ m.reply _("I only accept single words composed by letters only, sorry")\r
return\r
end\r
word_check(m, k, word)\r
return if m.channel.nil? # Shouldn't happen, but you never know\r
k = m.channel.downcase.to_s # to_sym?\r
if @games.key?(k)\r
- m.reply "the word in #{Bold}#{@games[k].range}#{Bold} was: #{Bold}#{@games[k].word}"\r
+ m.reply _("the word in %{bold}%{range}%{bold} was: %{bold}%{word}%{bold}") % {:bold => Bold, :range => @games[k].range, :word => @games[k].word}\r
ar = @games[k].score.inject([]) { |res, kv|\r
res.push("%s: %d (%s)" % kv.flatten)\r
}\r
- m.reply "The game was cancelled after #{@games[k].total_tries} tries. Scores for this game would have been: #{ar.join('; ')}"\r
+ m.reply _("The game was cancelled after %{tries} tries. Scores for this game would have been: %{scores}") % {:tries => @games[k].total_tries, :scores => ar.join('; ')}\r
@games.delete(k)\r
else\r
- m.reply "no A-Z game running in this channel ..."\r
+ m.reply _("no A-Z game running in this channel ...")\r
end\r
end\r
\r
unless @games.key?(k)\r
lang = (params[:lang] || @bot.config['core.language']).to_sym\r
method = 'random_pick_'+lang.to_s\r
- m.reply "let me think ..."\r
+ m.reply _("let me think ...")\r
if @rules.has_key?(lang) and self.respond_to?(method)\r
word = self.send(method)\r
if word.empty?\r
- m.reply "couldn't think of anything ..."\r
+ m.reply _("couldn't think of anything ...")\r
return\r
end\r
else\r
- m.reply "I can't play A-Z in #{lang}, sorry"\r
+ m.reply _("I can't play A-Z in %{lang}, sorry") % {:lang => lang}\r
return\r
end\r
- m.reply "got it!"\r
+ m.reply _("got it!")\r
@games[k] = AzGame.new(self, lang, @rules[lang], word)\r
end\r
tr = @games[k].total_tries\r
- case tr\r
- when 0\r
- tr_msg = ""\r
- when 1\r
- tr_msg = " (after 1 try"\r
+ # this message building code is rewritten to make translation easier\r
+ if tr == 0\r
+ tr_msg = ''\r
else\r
- tr_msg = " (after #{tr} tries"\r
- end\r
-\r
- unless tr_msg.empty?\r
f_tr = @games[k].total_failed\r
- case f_tr\r
- when 0\r
- tr_msg << ")"\r
- when 1\r
- tr_msg << " and 1 invalid try)"\r
+ if f_tr > 0\r
+ tr_msg = _(" (after %{total_tries} and %{invalid_tries})") %\r
+ { :total_tries => n_("%{count} try", "%{count} tries", tr) %\r
+ {:count => tr},\r
+ :invalid_tries => n_("%{count} invalid try", "%{count} invalid tries", tr) %\r
+ {:count => f_tr} }\r
else\r
- tr_msg << " and #{f_tr} invalid tries)"\r
+ tr_msg = _(" (after %{total_tries})") %\r
+ { :total_tries => n_("%{count} try", "%{count} tries", tr) %\r
+ {:count => tr}}\r
end\r
end\r
\r
- m.reply "A-Z: #{Bold}#{@games[k].range}#{Bold}" + tr_msg\r
+ m.reply _("A-Z: %{bold}%{range}%{bold}") % {:bold => Bold, :range => @games[k].range} + tr_msg\r
return\r
end\r
\r
cmd = params[:cmd].to_sym rescue :count\r
case cmd\r
when :count\r
- m.reply "I have #{wc.size > 0 ? wc.size : 'no'} #{lang} words in my cache"\r
+ m.reply n_("I have %{count} %{lang} word in my cache", "I have %{count} %{lang} words in my cache", wc.size) % {:count => wc.size, :lang => lang}\r
when :show, :list\r
if pars.empty?\r
- m.reply "provide a regexp to match"\r
+ m.reply _("provide a regexp to match")\r
return\r
end\r
begin\r
matches = []\r
end\r
if matches.size == 0\r
- m.reply "no #{lang} word I know match #{pars[0]}"\r
+ m.reply _("no %{lang} word I know match %{pattern}") % {:lang => lang, :pattern => pars[0]}\r
elsif matches.size > 25\r
- m.reply "more than 25 #{lang} words I know match #{pars[0]}, try a stricter matching"\r
+ m.reply _("more than 25 %{lang} words I know match %{pattern}, try a stricter matching") % {:lang => lang, :pattern => pars[0]}\r
else\r
m.reply "#{matches.join(', ')}"\r
end\r
when :info\r
if pars.empty?\r
- m.reply "provide a word"\r
+ m.reply _("provide a word")\r
return\r
end\r
word = pars[0].downcase.to_sym\r
if not wc.key?(word)\r
- m.reply "I don't know any #{lang} word #{word}"\r
+ m.reply _("I don't know any %{lang} word %{word}") % {:lang => lang, :word => word}\r
return\r
end\r
- tr = "#{word} learned from #{wc[word][:who]}"\r
- (tr << " on #{wc[word][:when]}") if wc[word].key?(:when)\r
+ if wc[word].key?(:when)\r
+ tr = _("%{word} learned from %{user} on %{date}") % {:word => word, :user => wc[word][:who], :date => wc[word][:when]}\r
+ else\r
+ tr = _("%{word} learned from %{user}") % {:word => word, :user => wc[word][:who]} \r
+ end\r
m.reply tr\r
- when :delete\r
+ when :delete \r
if pars.empty?\r
- m.reply "provide a word"\r
+ m.reply _("provide a word")\r
return\r
end\r
word = pars[0].downcase.to_sym\r
if not wc.key?(word)\r
- m.reply "I don't know any #{lang} word #{word}"\r
+ m.reply _("I don't know any %{lang} word %{word}") % {:lang => lang, :word => word}\r
return\r
end\r
wc.delete(word)\r
@bot.okay m.replyto\r
when :add\r
if pars.empty?\r
- m.reply "provide a word"\r
+ m.reply _("provide a word")\r
return\r
end\r
word = pars[0].downcase.to_sym\r
if wc.key?(word)\r
- m.reply "I already know the #{lang} word #{word}"\r
+ m.reply _("I already know the %{lang} word %{word}")\r
return\r
end\r
wc[word] = { :who => m.sourcenick, :when => Time.now }\r
wc = @wordcache[:italian]\r
return true if wc.key?(word.to_sym)\r
rules = @rules[:italian]\r
- p = @bot.httputil.get_cached(rules[:wapurl] % word)\r
+ p = @bot.httputil.get(rules[:wapurl] % word, :open_timeout => 60, :read_timeout => 60)\r
if not p\r
error "could not connect!"\r
return false\r
l = ('a'..'z').to_a[rand(26)]\r
debug "getting random word from dictionary, starting with letter #{l}"\r
first = rules[:url] % "lettera_#{l}_0_50"\r
- p = @bot.httputil.get_cached(first)\r
+ p = @bot.httputil.get(first)\r
max_page = p.match(/ \/ (\d+)<\/label>/)[1].to_i\r
pp = rand(max_page)+1\r
debug "getting random word from dictionary, starting with letter #{l}, page #{pp}"\r
- p = @bot.httputil.get_cached(first+"&pagina=#{pp}") if pp > 1\r
+ p = @bot.httputil.get(first+"&pagina=#{pp}") if pp > 1\r
lemmi = Array.new\r
good = rules[:good]\r
bad = rules[:bad]\r
wc = @wordcache[:english]\r
return true if wc.key?(word.to_sym)\r
rules = @rules[:english]\r
- p = @bot.httputil.get_cached(rules[:url] % URI.escape(word))\r
+ p = @bot.httputil.get(rules[:url] % CGI.escape(word))\r
if not p\r
error "could not connect!"\r
return false\r
ll = ('a'..'z').to_a[rand(26)]\r
random = [l,ll].join('*') + '*'\r
debug "getting random word from dictionary, matching #{random}"\r
- p = @bot.httputil.get_cached(rules[:url] % URI.escape(random))\r
+ p = @bot.httputil.get(rules[:url] % CGI.escape(random))\r
debug p\r
lemmi = Array.new\r
good = rules[:good]\r
def help(plugin, topic="")\r
case topic\r
when 'manage'\r
- return "az [lang] word [count|list|add|delete] => manage the az wordlist for language lang (defaults to current bot language)"\r
+ return _("az [lang] word [count|list|add|delete] => manage the az wordlist for language lang (defaults to current bot language)")\r
when 'cancel'\r
- return "az cancel => abort current game"\r
+ return _("az cancel => abort current game")\r
when 'check'\r
- return 'az check <word> => checks <word> against current game'\r
+ return _('az check <word> => checks <word> against current game')\r
when 'rules'\r
- return "try to guess the word the bot is thinking of; if you guess wrong, the bot will use the new word to restrict the range of allowed words: eventually, the range will be so small around the correct word that you can't miss it"\r
+ return _("try to guess the word the bot is thinking of; if you guess wrong, the bot will use the new word to restrict the range of allowed words: eventually, the range will be so small around the correct word that you can't miss it")\r
when 'play'\r
- 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"\r
+ 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")\r
end\r
- return "az topics: play, rules, cancel, manage, check"\r
+ return _("az topics: play, rules, cancel, manage, check")\r
end\r
\r
end\r