[QUIZ] IRC Teams (#221)

Discussion in 'Ruby' started by Daniel Moore, Oct 16, 2009.

  1. Daniel Moore

    Daniel Moore Guest

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    The three rules of Ruby Quiz:

    1. Please do not post any solutions or spoiler discussion for this
    quiz until 48 hours have elapsed from the time this message was
    sent.

    2. Support Ruby Quiz by submitting ideas and responses
    as often as you can.

    3. Enjoy!

    Suggestion: A [QUIZ] in the subject of emails about the problem
    helps everyone on Ruby Talk follow the discussion. Please reply to
    the original quiz message, if you can.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    RSS Feed: http://rubyquiz.strd6.com/quizzes.rss

    Suggestions?: http://rubyquiz.strd6.com/suggestions

    -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    ## IRC Teams (#221)

    Tashi dele Rubyists,

    This week's quiz was suggested by [Martin DeMello][1]

    A common feature in IRC-based games is the ability to create and join
    teams. The game bot sits in the channel and watches for messages in a
    certain format, which it interprets as commands. Write a small gamebot
    that accepts the following commands:

    create team <teamname>
    join <teamname>
    leave team
    show teams
    show team <teamname>
    show my team
    delete team <teamname>
    reset

    Here's a typical transcript

    <foo> create team ruby
    <bot> - created team ruby -
    <bar> create team python
    <bot> - created team python -
    <foo> show teams
    <bot> teams: ruby, python
    <foo> show team ruby
    <bot> team ruby: foo
    <bar> show my team
    <bot> bar is in team python
    <baz> join ruby
    <bot> baz is now in team ruby
    <bar> show team ruby
    <bot> team ruby: foo, baz

    Think up some useful extensions, such as the ability to join a user
    rather than a team, and restricting some commands like reset to ops.
    There are plenty of IRC bot libraries out there, go explore! If one
    already does team formation, that's cheating, though :)

    Have fun!

    [1]: http://zem.novylen.net

    --
    -Daniel
    http://rubyquiz.strd6.com
    Daniel Moore, Oct 16, 2009
    #1
    1. Advertising

  2. The main idea behind this quiz was to show how easy it is to get an
    irc bot up and running in ruby, especially given the number of bot
    frameworks out there. I chose to base my bot on rif
    [http://gitorious.org/ruby-irc], a nice lightweight library with
    everything I needed to get started immediately.

    The code consists of a Teams class, which does all the actual work of
    maintaining teams, and a TeamBot, which inherits from RIF::Bot and
    handles the IRC part of it. For the sake of simplicity, the bot
    frontend does no real validation; it just unpacks an incoming message
    into a command and arguments, and blindly sends those arguments to the
    Teams object. All public methods on the Teams object accept a player
    name as a first argument, whether they need it or not, and return
    either a string or an array of strings, or raise an exception. The bot
    sends the return value to the channel; an array is sent one message at
    a time.

    -------------------------------------------------------------------------------------

    gem 'rif'
    require 'rif/bot'

    class TeambotError < Exception
    end

    def TeambotError(foo)
    TeambotError.new(foo)
    end

    class Teams
    attr_accessor :teams, :members

    def initialize
    @teams = {}
    @members = {}
    end

    def create(player, team)
    raise TeambotError("team #{team} already created") if teams[team]
    teams[team] = true
    "created team #{team}"
    end

    def delete(player, team)
    teams.delete(team)
    members.delete_if {|k,v| v == team}
    "deleted team #{team}"
    end

    def join(player, team)
    raise TeambotError("no such team: #{team}") if not teams[team]
    members[player] = team
    "#{player} has joined team #{team}"
    end

    def leave(player, *args)
    team = members.delete(player)
    "#{player} has left team #{team}"
    end

    def reset(*args)
    @members = {}
    @teams = {}
    "deleted all teams"
    end

    def show(player, *args)
    if args[0] == 'my'
    members[player]
    elsif args[0] == 'teams'
    teams.map {|team, _| "#{team}: #{show_players(team)}"}
    elsif args[0] == 'team'
    show_players(team)
    end
    end

    private
    def players(team)
    members.select {|k,v| v == team}.keys
    end

    def show_players(team)
    players(team).join(" ")
    end
    end

    class TeamBot < RIF::Bot
    attr_reader :teams, :channel
    def initialize(channel, nick, server, port, username)
    @teams = Teams.new
    @channel = channel
    super(nick, server, port, username)
    end

    def on_endofmotd(event)
    join(channel)
    end

    def on_message(event)
    return unless event.channel == channel
    msg, *args = event.message.split(" ")
    player = event.nick
    begin
    *ret = teams.send(msg, player, *args)
    rescue NameError
    ret = nil
    rescue TeambotError => e
    ret = [e.message]
    end
    ret.each {|m| send_message(channel, m)} if ret
    end
    end

    if __FILE__ == $0
    channel = "##{ARGV[0]}"
    bot = TeamBot.new(channel, "teambot", "irc.freenode.net", 6667, "RIF Bot")
    bot.connect
    end

    martin
    Martin DeMello, Oct 19, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tarren
    Replies:
    7
    Views:
    4,993
    Tarren
    Jan 20, 2005
  2. zcraven
    Replies:
    3
    Views:
    2,555
    Bruno Grieder
    Oct 29, 2004
  3. Replies:
    0
    Views:
    310
  4. Diwa
    Replies:
    24
    Views:
    742
  5. Jeff

    creating random teams?

    Jeff, Dec 29, 2006, in forum: ASP General
    Replies:
    9
    Views:
    165
Loading...

Share This Page