Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Changelog

* Added automatch support for doubles matches - [@amikula](https://github.com/amikula).
* [#94](https://github.com/dblock/slack-gamebot/issues/94): De-registering and re-registering a team just reactivates the old team - [@dblock](https://github.com/dblock).
* [#92](https://github.com/dblock/slack-gamebot/issues/92): Leaderboard without ranked players now says that there're no ranked players - [@dblock](https://github.com/dblock).
* [#80](https://github.com/dblock/slack-gamebot/issues/80): Empty season produces `undefined method 'map' for nil:NilClass` error - [@dblock](https://github.com/dblock).
Expand Down
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ gem 'newrelic_rpm'
gem 'newrelic-slack-ruby-bot'
gem 'rack-rewrite'
gem 'wannabe_bool'
gem 'chronic'
gem 'chronic_duration'

group :development, :test do
gem 'rake', '~> 10.4'
gem 'rubocop', '0.34.2'
gem 'foreman'
gem 'timecop'
end

group :development do
Expand Down
8 changes: 8 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ GEM
thread_safe (~> 0.3, >= 0.3.1)
bson (4.0.1)
builder (3.2.2)
chronic (0.10.2)
chronic_duration (0.10.6)
numerizer (~> 0.1.1)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
crack (0.4.3)
Expand Down Expand Up @@ -183,6 +186,7 @@ GEM
newrelic_rpm (3.14.3.313)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
numerizer (0.1.1)
oj (2.14.4)
origin (2.2.0)
parser (2.3.0.5)
Expand Down Expand Up @@ -246,6 +250,7 @@ GEM
thor (0.19.1)
thread_safe (0.3.5)
time_ago_in_words (0.1.1)
timecop (0.8.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uber (0.0.15)
Expand Down Expand Up @@ -273,6 +278,8 @@ PLATFORMS
ruby

DEPENDENCIES
chronic
chronic_duration
database_cleaner
fabrication
faker
Expand All @@ -299,6 +306,7 @@ DEPENDENCIES
slack-ruby-bot!
slack-ruby-client!
time_ago_in_words
timecop
unicorn
vcr
wannabe_bool
Expand Down
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,58 @@ gamebot cancel
Victor Barna and Deng Yaping canceled a challenge against Wang Hoe and Zhang Jike.
```

#### gamebot automatch on|off

Turn doubles automatch on for 5 minutes, or turn it off. When 4 players have automatch on, gamebot will create a new challenge with the players with the highest and lowest ELO scores vs the players with the middle scores.

```
gamebot automatch on

Automatch is on for alf (1 users ready to play!)
```

```
gamebot automatch off

Automatch is off for alf (0 users ready to play!)
```

#### gamebot automatch for <duration>

Turn doubles automatch on for the specified duration. Accepts natural language duration like "5 minutes".

```
gamebot automatch for 5 minutes

Automatch is on for alf (1 users ready to play!)
```

#### gamebot automatch until <time>

Turn doubles automatch on until the specified time. Accepts natural language times.

```
gamebot automatch until 10 minutes from now

Automatch is on for alf (1 users ready to play!)
```

```
gamebot automatch until 8pm

Automatch is on for alf (1 users ready to play!)
```

#### gamebot automatch

List players with automatch on, and the durations they have remaining.

```
gamebot automatch

alf for 4 mins 57 secs
```

#### gamebot leaderboard [number|infinity]

Get the leaderboard.
Expand Down
1 change: 1 addition & 0 deletions slack-gamebot/commands.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'slack-gamebot/commands/accept'
require 'slack-gamebot/commands/automatch'
require 'slack-gamebot/commands/cancel'
require 'slack-gamebot/commands/challenge'
require 'slack-gamebot/commands/challenges'
Expand Down
82 changes: 82 additions & 0 deletions slack-gamebot/commands/automatch.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module SlackGamebot
module Commands
class Automatch < SlackRubyBot::Commands::Base
def self.call(client, data, match)
challenger = ::User.find_create_or_update_by_slack_id!(client, data.user)

case match['expression']
when 'on'
challenger.automatch_time = 5.minutes.from_now
challenger.save!
automatch_on(challenger, client, data)
when 'off'
challenger.automatch_time = nil
challenger.save!
automatch_off(challenger, client, data)
when /^until\b/i
parsed_time = Chronic.parse(match['expression'].sub(/^until\W*/, ''))
fail SlackGamebot::Error, "Can't understand time specified" unless parsed_time

challenger.automatch_time = parsed_time
challenger.save!
automatch_on(challenger, client, data)
when /^for\b/i
parsed_time = ChronicDuration.parse(match['expression'].sub(/^for\W*/, ''))
fail SlackGamebot::Error, "Can't understand time specified" unless parsed_time

challenger.automatch_time = Time.now + parsed_time
challenger.save!
automatch_on(challenger, client, data)
when nil
automatch_users = User.where(:automatch_time.gt => Time.now).order(automatch_time: :asc)
if (automatch_users.count == 0)
client.say(channel: data.channel, text: 'No users currently have automatch turned on')
else
times = automatch_users.map do |user|
duration = ChronicDuration.output((user.automatch_time - Time.new).to_i, keep_zero: true)
"#{user.user_name} for #{duration}"
end.join("\n")

client.say(channel: data.channel, text: times)
end
else
fail SlackGamebot::Error, "Invalid automatch argument '#{match['expression']}'"
end
end

def self.automatch_on(challenger, client, data)
logger.info "AUTOMATCH: #{client.owner} - #{challenger.user_name}: #{challenger.automatch_time}"

automatch_users = User.where(:automatch_time.gt => Time.now).order(elo: :asc).limit(4)
if automatch_users.count == 4
challenge = ::Challenge.create!(
team: client.owner,
channel: data.channel,
created_by: challenger,
updated_by: automatch_users[1],
challengers: [automatch_users[0], automatch_users[3]],
challenged: [automatch_users[1], automatch_users[2]],
state: ChallengeState::ACCEPTED
)

automatch_users.each do |user|
user.automatch_time = nil
user.save!
end

client.say(channel: data.channel, text: "Automatch: #{challenge.challengers.map(&:user_name).and} vs #{challenge.challenged.map(&:user_name).and}!", gif: 'challenge')
logger.info "CHALLENGE: #{client.owner} - #{challenge}"
else
client.say(channel: data.channel, text: "Automatch is on for #{challenger.user_name} (#{automatch_users.count} users ready to play!)", gif: 'ready')
end
end

def self.automatch_off(challenger, client, data)
automatch_count = User.where(:automatch_time.gt => Time.now).count
logger.info "AUTOMATCH: #{client.owner} - #{challenger.user_name}: OFF"

client.say(channel: data.channel, text: "Automatch is off for #{challenger.user_name} (#{automatch_count} users ready to play!)", gif: 'leave')
end
end
end
end
1 change: 1 addition & 0 deletions slack-gamebot/commands/help.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Help < SlackRubyBot::Commands::Base
-----
challenge <opponent>, ... [with <teammate>, ...]: challenge opponent(s) to a game
accept: accept a challenge
automatch: turn on automatch mode, eg. automatch for 10 minutes, or automatch until 8pm
decline: decline a previous challenge
cancel: cancel a previous challenge
lost [score, ...]: record your loss
Expand Down
1 change: 1 addition & 0 deletions slack-gamebot/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ class User
field :tau, type: Float, default: 0
field :rank, type: Integer
field :captain, type: Boolean, default: false
field :automatch_time, type: Time

belongs_to :team, index: true
validates_presence_of :team
Expand Down
11 changes: 11 additions & 0 deletions spec/fabricators/challenge_fabricator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,14 @@
instance.updated_by = instance.challenged.first
end
end

Fabricator(:automatch_challenge, from: :challenge) do
state ChallengeState::ACCEPTED
after_build do |instance|
instance.challengers = [Fabricate(:user, team: instance.team), Fabricate(:user, team: instance.team)] unless instance.challengers.any?
instance.challenged = [Fabricate(:user, team: instance.team), Fabricate(:user, team: instance.team)] unless instance.challenged.any?
end
before_create do |instance|
instance.updated_by = instance.challenged.first
end
end
Loading