lib/lita/handlers/markov/engine.rb in lita-markov-1.1.2 vs lib/lita/handlers/markov/engine.rb in lita-markov-1.2.0
- old
+ new
@@ -103,36 +103,72 @@
states = @db[:dictionary]
.where(user: user, current_state: current_state)
.select(:next_state, :frequency)
.all
+ sample_states(states)
+ end
+
+ def get_random_next_state(user)
+ states = @db[:dictionary]
+ .where(user: user)
+ .select(:next_state, :frequency)
+ .all
+
+ sample_states states
+ end
+
+ def sample_states(states)
distribution = states.flat_map do |state|
Array.new(state[:frequency]) { state[:next_state] }
end
distribution.sample
end
- def generate_sentence_for(user, length = 30)
+ def start_new_sentence(user, sentence)
first_word = random_capitalized_word user
second_word = random_second_word user, first_word
- sentence = [first_word, second_word]
+ sentence << first_word
+ sentence << second_word
+ end
+
+ def generate_sentence_for(user, length = 30)
+ sentence = []
ended_with_punctuation = false
+ start_new_sentence user, sentence
+
while sentence.length < length
current_state = sentence.slice(sentence.length - @depth, @depth).join ' '
next_state = get_next_state user, current_state
- # Stop if we failed to find a next state
- break if next_state.nil?
+ if next_state.nil?
+ if sentence.length > (length / 2)
+ # Stop if we failed to find a next state and it's long enough
+ break
+ else
+ # Otherwise pick a completely random next-state from the user
+ # for the lols
+ next_state = get_random_next_state user
+ end
+ end
sentence << next_state
if next_state == '.'
- ended_with_punctuation = true
- break
+ if sentence.length > (length / 2)
+ # If it's long enough then we can end on a period
+ ended_with_punctuation = true
+ break
+ else
+ # Otherwise append a period and start a fresh sentence
+ last = sentence.pop
+ sentence.push(sentence.pop + last)
+ start_new_sentence user, sentence
+ end
end
end
chain = sentence.slice(0..-2).join(' ')
chain << ' ' unless ended_with_punctuation