Skip to content

Instantly share code, notes, and snippets.

@joonty
Created July 30, 2013 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joonty/6112895 to your computer and use it in GitHub Desktop.
Save joonty/6112895 to your computer and use it in GitHub Desktop.
Word game IRC bot, as a Cinch plugin
require 'cinch'
class Cinch::Plugins::WordGame
include Cinch::Plugin
match(/word start/, method: :start)
def start(m)
@word = DictionaryWord.new("/etc/dictionaries-common/words")
@guesses = 0
m.reply "Starting a new word game. Make a guess."
end
match(/word cheat/, method: :cheat)
def cheat(m)
if @word
m.reply "You want to cheat after #{@guesses} guesses? Fine. The word is #{@word.word}. #{m.user}: you suck."
end
end
match(/guess (\S+)/, method: :guess)
def guess(m, word)
if @word
@guesses += 1
if @word == word
m.reply("Yes, that's the word! Congratulations, #{m.user} wins! You had #{@guesses} guesses.")
else
m.reply("My word comes #{@word.before_or_after(word)} \"#{word}\". You've had #{@guesses} guesses.")
end
else
m.reply("I haven't started a word game yet. Use !word to start one.")
end
end
class DictionaryWord
attr_accessor :word
def initialize(filename)
begin
word = random_line(filename)
end until word[0] == word[0].downcase # remove proper nouns
@word = word.gsub(/'.*/, '') # Remove apostrophes
end
def before?(word)
@word < word.downcase
end
def before_or_after(word)
before?(word) ? "before" : "after"
end
def ==(word)
@word == word
end
private
def random_line(filename)
blocksize, line = 1024, ""
File.open(filename) do |file|
initial_position = rand(File.size(filename) - 1) + 1 # random pointer position. Not a line number!
pos = Array.new(2, initial_position) # array [prev_position, current_position]
# Find beginning of current line
begin
pos.push([pos[1] - blocksize, 0].max).shift # calc new position
file.pos = pos[1] # move pointer backward within file
offset = (n = file.read(pos[0] - pos[1]).rindex(/\n/) ) ? n+1 : nil
end until pos[1] == 0 || offset
file.pos = pos[1] + offset.to_i
# Collect line text till the end
begin
data = file.read(blocksize)
line.concat((p = data.index(/\n/)) ? data[0,p.to_i] : data)
end until file.eof? or p
end
line
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment