我运行一个用ruby编写的irc bot,运行cinch irc框架。机器人回答有趣的事实,并通过这些事实循环,这样你就不会对它们感到厌倦。我已经冷静下来,所以他们无法显示6个小时。它不是显示它首先显示的事实,而是显示随机选择的事实,这可能是之前已经显示过的事实。
line = IO.readlines("facts.txt")
factnumber = rand(line.length)
if fact_not_next_6_hours[factnumber] == true
factnumber = rand(line.length)
m.reply "fact #{factnumber}: #{line[factnumber]}"
fact_not_next_6_hours[factnumber] = true
fact_not_next_6_hours[factnumber]
是6小时冷却的变量;如果设置为true,则冷却处于活动状态。我需要这样做:
factnumber = rand(line.length)
直到它得到一个没有将6小时冷却设置为真,然后执行
m.reply "fact #{factnumber}: #{line[factnumber]}"
fact_not_next_6_hours[factnumber] = true
我的第一个想法是做多个if
,但它不起作用,我确信有更好的方法。
答案 0 :(得分:1)
你可以这样做:
factnumber = rand(line.length)
while fact_not_next_6_hours[factnumber] == true
factnumber = rand(line.length)
end
m.reply "fact #{factnumber}: #{line[factnumber]}"
fact_not_next_6_hours[factnumber] = true
或者:
nil while fact_not_next_6_hours[factnumber = rand(line.length)] == true
m.reply "fact #{factnumber}: #{line[factnumber]}"
fact_not_next_6_hours[factnumber] = true
答案 1 :(得分:1)
您应该将line
重命名为lines
,因为它实际上是一系列行。我在答案中这样做了。
这实际上是一个“do while”循环:
begin
factnumber = rand(lines.length)
end while fact_not_next_6_hours[factnumber]
但是根据您拥有的事实数量以及您希望“使用”的数量,过滤掉您先无法使用的事实可能会更有意义:
fact = (0...lines.length).zip(lines).reject do |k, v|
fact_not_next_6_hours[k]
end.sample
m.reply "fact #{fact[0]}: #{fact[1]}"
第一位((0...lines.length).zip(lines)
)只是将每一行与一个数字相关联(例如[[0, "fact"], [1, "afact"], ...]
)。我建议单独运行方法链的每个部分,以便您可以完全了解正在发生的事情。
答案 2 :(得分:1)
首先,如果你只是设置一个布尔标志,你怎么知道何时“解冻”呢?我将保留对象中最后访问时间的“时间戳”。此外,我不再使用原始类型,而是采用更加面向对象的方式。
这是我的解决方案:
class Fact
attr_reader :text
def initialize(text)
@text = text
@last_accessed = Time.new(0) # a long time ago, not in cooldown
end
def in_cooldown?
Time.now - @last_accessed < 60*60*6
end
def cooldown!
@last_accessed = Time.now
end
end
class Facts
attr_reader :all
def initialize(file_name)
@all = IO.readlines("facts.txt").map{|line| Fact.new(line)}
end
end
class FactRandomizer
def initialize(facts)
@facts = facts
end
def get
fact = not_in_cooldown.sample || all.sample # all can be in cooldown
fact.cooldown!
fact.text
end
private
def not_in_cooldown
@facts.select{|fact| !fact.in_cooldown?}
end
end
用法:
facts = Facts.new("whatever").all
randomizer = FactRandomizer.new(facts)
randomizer.get
编辑:
我重构了代码,因此它不再使用类方法了。注意,现在测试这段代码要容易多少,以及交换它的部分是多么容易(比如替换从文件中读取事实的部分或者对于冷却事实的意义)。