-2

私はrubyで書かれたircボットを実行し、cinchircフレームワークを実行しています。ボットは興味深い事実を返信し、これらの事実を循環するため、飽きることはありません。クールダウンを設定したので、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時間のクールダウンがtrueに設定されていないものが得られるまで、

m.reply "fact #{factnumber}: #{line[factnumber]}"
fact_not_next_6_hours[factnumber] = true

私の最初のアイデアは複数ifのことをすることでしたが、それはうまくいきませんでした。もっと良い方法があると確信しています。

4

3 に答える 3

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
于 2012-04-05T15:17:58.380 に答える
1

実際には行の配列であるため、実際には名前lineをに変更する必要があります。lines私は私の答えでそうしました。

これは本質的に「dowhile」ループです。

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))の最初のビットは、各行を数字(eg [[0, "fact"], [1, "afact"], ...])に関連付けるだけです。何が起こっているのかを完全に理解できるように、メソッドチェーンの各部分を個別に実行することをお勧めします。

于 2012-04-05T15:21:52.273 に答える
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

編集:

コードをリファクタリングして、クラスメソッドを使用しないようにしました。このコードを今すぐテストするのがどれほど簡単で、その一部を交換するのがどれほど簡単であるかに注意してください(たとえば、ファイルからファクトを読み取る部分を置き換える、またはファクトがクールダウンすることはどういう意味ですか)。

于 2012-04-05T15:31:52.853 に答える