2012-04-05 6 views
-2

私はrubyで書かれたirc botを実行し、cinch ircフレームワークを実行します。ボットは、興味深い事実とサイクルでこれらの事実を返信するので、あなたはそれらに飽きることはありません。私はクールダウンを設定しているので、6時間表示することはできません。最初に示された事実を示すのではなく、無作為に選択されたものを表示するようになりました。変数が正しいまで変更します(if、else)

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) 

を、それがダウンしてtrueに設定クール6時間を持っているdosen't 1を取得するまで、次に

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

私の最初のアイデアは、複数のifの操作を行うことだったん:私は何をする必要がありますしかしそれはうまくいかず、より良い方法があると確信しています。

答えて

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 
+0

これはうまくいくようです!ありがとう。私は2番目の解決策、そのきれいで素敵な – qwerty1911

+0

すべての事実が使用されている場合、これは無限ループに終わるでしょう – psyho

+0

私は無限ループを認識していますが、チャンネルは約680ファクトですので、私も "インスタントun-cooldown"を追加することを計画しています – qwerty1911

1

を、それが実際に行の配列であるとして、あなたは本当に、lineslineの名前を変更する必要があります。私は私の答えでそうした。

これは基本的にループ「ながらやる」です。

begin 
    factnumber = rand(lines.length) 
end while fact_not_next_6_hours[factnumber] 

しかし、あなたが持っているどのように多くの事実に依存し、どのように多くのあなたは、あなたが最初に使用することはできませんものをフィルタリング、「使用」であることを期待その((0...lines.length).zip(lines))の

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, "fact"], [1, "afact"], ...])と行の各々を関連付けるされる:より多くの意味を行うことができます。メソッドチェインの各部分を個別に実行して、何が起こっているのかを完全に理解できるようにすることをお勧めします。

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 

EDIT:それはもう、クラスメソッドを使用しないように

私は、コードをリファクタリング。このコードを今すぐテストするのがどれくらい簡単で、その部分を交換するのが簡単か(たとえば、ファイルからファクトを読み取る部分を置き換えたり、ファクトがクールダウンされていることを意味するものなど)

+0

facts.txtを#{m.channel}に簡単に変更できますか?グローバル変数のために考えてみましょう。簡単に説明するときはfacts.txtを置きます – qwerty1911

関連する問題