cinch-dicebag 1.0.9 → 1.0.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
- metadata.gz: ab59f8709ed5aee1d8354910616d518933583bda
4
- data.tar.gz: 353ef745e42b012d36c2e4efad611ef885eabcba
3
+ metadata.gz: 03ffcf66f79f8ac4138c0616c87bdec979c8a68b
4
+ data.tar.gz: 2ffd9ee34d9838564ce75c3823645f4d6b8d6016
5
5
  SHA512:
6
- metadata.gz: 20e7c611ae9235b4dab39e4d78717a39e169ecbbceecf2effacbb7870ea93b89cbbee0f744ff78e019300d9f285478290aaa167469e06b5d79670288b6dc2357
7
- data.tar.gz: f38172852b8b6d52c37895a60167318f9010c2b8fe9655d558a701ef1aec62b8b024fc24da9e2beb8df3cc0f5ae7fe98aff1bdba2fe88fd51da8b969c7d848c9
6
+ metadata.gz: 28deec95c393d146cf89c89aa49f476838f5e23aa045217addfdb3fccd7fb8a553be9c669b3a160e6956c29da0e611190370a4d60ffc726b30a781febf5ba1d0
7
+ data.tar.gz: 63c0c078021222b79ebed0dd726c191d5e57eb3ee87799f6f94c767d41f106c4c3d65dd87cd415742e9ba218226df1c865ca1e744f5dfc164692f90c92cc9af6
@@ -10,7 +10,6 @@ rvm:
10
10
  - 1.8.7
11
11
  - jruby-18mode
12
12
  - jruby-19mode
13
- - rbx
14
13
  - ruby-head
15
14
  - jruby-head
16
15
  - ree
@@ -1,3 +1,5 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require 'cinch/plugins/dicebag/version'
3
3
  require 'cinch/plugins/dicebag'
4
+ require 'cinch/plugins/dicebag/die'
5
+ require 'cinch/plugins/dicebag/bag'
@@ -18,13 +18,15 @@ module Cinch::Plugins
18
18
  'use .roll (dice count)d(sides) to roll specific dice ' +
19
19
  '(e.g. .roll 4d6 3d20)'
20
20
 
21
- match /dicebag/, method: :roll_dicebag
21
+ match /dicebag\z/, method: :dicebag
22
+ match /dicebag stats/, method: :stats
22
23
  match /roll(?:\s(.*))/, method: :roll
23
24
  match /roll\z/, method: :roll
24
25
 
25
26
  def initialize(*args)
26
27
  super
27
28
  @storage = Cinch::Storage.new(config[:filename] || 'yaml/dice.yml')
29
+ @bag = Bag.new({ 4 => 250, 6 => 500, 10 => 750, 20 => 1000 })
28
30
  end
29
31
 
30
32
  # Roll a random assortment of dice, total the rolls, and record the score.
@@ -32,19 +34,22 @@ module Cinch::Plugins
32
34
  # @param [Cinch::Channel] channel The Channel object where the roll took
33
35
  # place.
34
36
  # @return [String] A description of the roll that took place
35
- def roll_dicebag(m)
36
- if m.channel.nil?
37
- m.reply 'You must use that command in the main channel'
38
- return
39
- end
40
-
41
- dice = { d4: rand(250), d6: rand(500), d10: rand(750), d20: rand(1000) }
42
- total = roll_dice(dice.map { |die, count| "#{count}#{die}" })
43
- size = get_bag_size(dice.values.inject(:+))
44
-
45
- m.reply "#{m.user.nick} rolls a #{size} bag of dice totalling " +
46
- "#{total}. " +
47
- score_check(m.user.nick.downcase, m.channel.name, total)
37
+ def dicebag(m)
38
+ return if Cinch::Toolbox.sent_via_private_message?(m)
39
+
40
+ @bag.roll
41
+
42
+ m.reply "#{m.user.nick} rolls a #{@bag.size} bag of dice totalling " +
43
+ "#{@bag.score}. " +
44
+ score_check(m.user.nick.downcase, m.channel.name, @bag.score)
45
+ end
46
+
47
+ def stats(m)
48
+ return if Cinch::Toolbox.sent_via_private_message?(m)
49
+
50
+ m.user.send 'Top ten dicebag rolls:'
51
+ top10 = top_ten_rolls(m.channel.name)
52
+ top10.each_with_index { |r, i| m.user.send "#{i + 1} - #{r.first} [#{r.last}]"}
48
53
  end
49
54
 
50
55
  # Roll a specific set of dice and return the pretty result
@@ -53,82 +58,18 @@ module Cinch::Plugins
53
58
  # (i.e. '6d12 4d20 d10'
54
59
  # @return [String] String describing the dice that were rolled
55
60
  def roll(m, dice = '1d20')
56
- result = roll_dice(dice.split(' '))
57
-
61
+ result = Die.roll(dice.split(' '))
58
62
  result = "#{m.user.nick} rolls #{dice} totalling #{result}" if result.is_a?(Integer)
59
- m.reply result
60
- end
61
-
62
- # Takes an Array of dice rolls, sanitizes them, parses them, and dispatches
63
- # their calculation to `roll_die`.
64
- # @param [Array] dice Array of strings that correspond to valid die rolls.
65
- # (i.e. ['4d6', '6d10']
66
- # @return [Fixnum] The total from rolling all of the dice.
67
- def roll_dice(dice)
68
- # Clean out anything invalid
69
- dice.delete_if { |d| d.match(/\d*d\d+([\-\+]\d+)?/).nil? }
70
-
71
- return roll_check?(dice) if roll_check?(dice)
72
-
73
- # Roll each group and total up the returned value
74
- total = nil
75
- dice.each do |die|
76
- total ||= 0
77
- total += roll_die(die)
78
- end
79
-
80
- total
81
- end
82
63
 
83
- # Takes an array of rolls and does sanity on it.
84
- # @param [Array] dice Array of strings that correspond to valid die rolls.
85
- # (i.e. ['4d6', '6d10']
86
- # @return [Fixnum] The total from rolling all of the dice.
87
- def roll_check?(dice)
88
- # Check to make sure it's not a stupid large roll, they clog threads.
89
- count = dice.map { |die| die[/(\d+)d\d+/, 1].to_i || 1 }.inject(0, :+)
90
- return 'I don\'t have that many dice in my bag!' unless count <= 10_000
91
- false
92
- end
93
-
94
- # Rolls an n-sided die a given amount of times and returns the total
95
- # @param [Fixn] count Number of times to roll the die.
96
- # @return [Fixnum] The total from rolling the die.
97
- def roll_die(die)
98
- modifier = die[/[\-\+]\d+/]
99
-
100
- count = (die[/(\d+)d\d+/, 1] || 1).to_i
101
- sides = die[/\d?d(\d+)/, 1].to_i
102
-
103
- return 0 if count.nil? || sides.nil? || sides < 1 || count < 1
104
-
105
- total = 0
106
- count.times { total += rand(sides) + 1 }
107
-
108
- return total += parse_modifier(modifier) unless modifier.nil?
109
-
110
- total
64
+ m.reply result
111
65
  end
112
66
 
113
- def parse_modifier(modifier)
114
- operator = modifier[/\A[\+\-]/]
115
- int = modifier[/\d+\z/].to_i
116
- 0.send(operator, int)
117
- end
67
+ private
118
68
 
119
- # Simple method to return a flavor text 'size' description based on
120
- # how many dice you happened to get in your dicebag roll.
121
- # @param [Fixnum] size The number of dice in the dicebag.
122
- # @return [String] Description of the size of the bag.
123
- def get_bag_size(size)
124
- case size
125
- when 0..100 then 'tiny'
126
- when 101..500 then 'small'
127
- when 501..1000 then 'medium'
128
- when 1001..1500 then 'large'
129
- when 1501..2000 then 'hefty'
130
- else 'huge'
131
- end
69
+ def top_ten_rolls(channel)
70
+ scores = @storage.data[channel].dup
71
+ scores.sort { |a, b| b[1][:score] <=> a[1][:score] }
72
+ .map { |s| [s.first, s.last[:score]] }[0..9]
132
73
  end
133
74
 
134
75
  # Score checker for Dicebag rolls. Checks a given user/channel/score
@@ -0,0 +1,48 @@
1
+ module Cinch::Plugins
2
+ class Dicebag
3
+ class Bag
4
+ attr_accessor :count, :dice, :score
5
+ def initialize(dice_hash)
6
+ fail unless good_hash?(dice_hash)
7
+ @dice = dice_hash
8
+ @count = 0
9
+ @score = 0
10
+ end
11
+
12
+ def roll
13
+ dice = die_array
14
+ @score = Die.roll(dice)
15
+ @count = dice.map { |d| d[/(\d+)d\d+/, 1].to_i || 1 }.inject(0, :+)
16
+ end
17
+
18
+ def good_hash?(dice_hash)
19
+ dice_hash.keys { |k| return false unless k.is_a?(Integer) }
20
+ dice_hash.values { |k| return false unless k.is_a?(Integer) }
21
+ true
22
+ end
23
+
24
+ # Simple method to return a flavor text 'size' description based on
25
+ # how many dice you happened to get in your dicebag roll.
26
+ # @param [Fixnum] size The number of dice in the dicebag.
27
+ # @return [String] Description of the size of the bag.
28
+ def size
29
+ case count
30
+ when 0..100 then 'tiny'
31
+ when 101..500 then 'small'
32
+ when 501..1000 then 'medium'
33
+ when 1001..1500 then 'large'
34
+ when 1501..2000 then 'hefty'
35
+ else 'huge'
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def die_array
42
+ @dice.keys.map do |sides|
43
+ "#{sides}d#{@dice[sides]}"
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,78 @@
1
+ module Cinch::Plugins
2
+ class Dicebag
3
+ module Die
4
+ MOD_REGEX = /[\-\+]\d+/
5
+ ROLLS_REGEX = /(\d+)d\d+/
6
+ SIDES_REGEX = /\d?d(\d+)/
7
+
8
+ # Takes a dice roll string or Array of dice rolls, sanitizes them, parses
9
+ # them, and dispatches their calculation to `Die.cast`.
10
+ # @param [Array] dice Array of strings that correspond to valid die rolls.
11
+ # (i.e. ['4d6', '6d10']
12
+ # @return [Fixnum] The total from rolling all of the dice.
13
+ def self.roll(dice)
14
+ # Convert to an array if it's a single die roll
15
+ dice = [dice] if dice.is_a?(String)
16
+
17
+ # Clean out anything invalid
18
+ dice = clean_roll(dice)
19
+
20
+ total = nil
21
+
22
+ # Return if the sanity fails
23
+ return 'I don\'t have that many dice in my bag!' unless die_check?(dice)
24
+
25
+ # Roll each group and total up the returned value
26
+ dice.each do |die|
27
+ total ||= 0
28
+ total += cast(die)
29
+ end
30
+
31
+ total
32
+ end
33
+
34
+ private
35
+
36
+ # Rolls an n-sided die a given amount of times and returns the total
37
+ # @param [String] count Number of times to roll the die.
38
+ # @return [Fixnum] The total from rolling the die.
39
+ def self.cast(die)
40
+ modifier = die[MOD_REGEX]
41
+
42
+ count = (die[ROLLS_REGEX, 1] || 1).to_i
43
+ sides = die[SIDES_REGEX, 1].to_i
44
+
45
+ return 0 if count.nil? || sides.nil? || sides < 1 || count < 1
46
+
47
+ total = 0
48
+ count.times { total += rand(sides) + 1 }
49
+
50
+ return total += parse_modifier(modifier) unless modifier.nil?
51
+
52
+ total
53
+ end
54
+
55
+ def self.clean_roll(dice)
56
+ dice.delete_if { |d| d.match(/\d*d\d+([\-\+]\d+)?/).nil? }
57
+ dice
58
+ end
59
+
60
+ # Takes an array of rolls and does sanity on it.
61
+ # @param [Array] dice Array of strings that correspond to valid die rolls.
62
+ # (i.e. ['4d6', '6d10']
63
+ # @return [Boolean] Result of sanity check.
64
+ def self.die_check?(dice_list)
65
+ # Check to make sure it's not a stupid large roll, they clog threads.
66
+ count = dice_list.map { |d| d[/(\d+)d\d+/, 1].to_i || 1 }.inject(0, :+)
67
+ return false if count >= 10_000
68
+ true
69
+ end
70
+
71
+ def self.parse_modifier(modifier)
72
+ operator = modifier[/\A[\+\-]/]
73
+ int = modifier[/\d+\z/].to_i
74
+ 0.send(operator, int)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -2,6 +2,6 @@
2
2
  module Cinch
3
3
  # Versioning information for plugin
4
4
  module Dicebag
5
- VERSION = '1.0.9'
5
+ VERSION = '1.0.10'
6
6
  end
7
7
  end
@@ -77,101 +77,185 @@ describe Cinch::Plugins::Dicebag do
77
77
 
78
78
  it 'should return an error if the user is not in a channel' do
79
79
  get_replies(make_message(@bot, '!dicebag' , { nick: 'ted' })).first.text.
80
- should be_eql("You must use that command in the main channel")
80
+ should == 'You must use that command in the main channel.'
81
81
  end
82
82
 
83
83
  it 'should return a string describing the user\'s bag roll' do
84
84
  get_replies(make_message(@bot, '!dicebag' , { nick: 'ted', channel: '#bar' })).first.text.
85
85
  should match(/ted rolls a [a-z]+ bag of dice totalling \d+/)
86
86
  end
87
+ end
88
+
89
+ describe 'scores' do
90
+ before(:each) do
91
+ @bot.plugins.first.storage.data['#foo'] = { 'brian' => { score: 1, time: Time.now },
92
+ 'braad' => { score: 2, time: Time.now },
93
+ 'billy' => { score: 3, time: Time.now },
94
+ 'britt' => { score: 4, time: Time.now },
95
+ 'brett' => { score: 5, time: Time.now },
96
+ 'paulv' => { score: 6, time: Time.now },
97
+ 'stacy' => { score: 7, time: Time.now },
98
+ 'calrs' => { score: 8, time: Time.now },
99
+ 'susie' => { score: 9, time: Time.now },
100
+ 'enton' => { score: 10, time: Time.now },
101
+ 'grill' => { score: 11, time: Time.now },
102
+ 'evilg' => { score: 12, time: Time.now },
103
+ 'mobiu' => { score: 13, time: Time.now },
104
+ 'gamma' => { score: 14, time: Time.now },
105
+ 'omega' => { score: 15, time: Time.now } }
106
+ end
87
107
 
88
108
  it 'should announce a high score if the old score is higher' do
89
- get_replies(make_message(@bot, '!dicebag' , { nick: 'brian', channel: '#foo' }))
90
- @bot.plugins.first.storage.data['#foo']['brian'] = { score: 1, time: Time.now }
91
109
  text = get_replies(make_message(@bot, '!dicebag' , { nick: 'brian', channel: '#foo' })).first.text
92
110
  text.should match(/A new high score/)
93
111
  text.should match(/Their old high roll was \d+/)
94
112
  end
113
+
114
+ it 'should allow users to get a copy of the high scores' do
115
+ replies = get_replies(make_message(@bot, '!dicebag stats' , { nick: 'brian', channel: '#foo' }))
116
+ replies[1].text.should == '1 - omega [15]'
117
+ replies[5].text.should == '5 - grill [11]'
118
+ end
119
+
120
+ it 'should only show the first 10 scores' do
121
+ replies = get_replies(make_message(@bot, '!dicebag stats' , { nick: 'brian', channel: '#foo' }))
122
+ replies.length.should == 11
123
+ end
95
124
  end
96
125
 
97
126
  describe 'roll_dice' do
98
127
  it 'should return nil if the dice list is empty' do
99
- @bot.plugins.first.roll_dice([]).should be_nil
128
+ Cinch::Plugins::Dicebag::Die.roll([]).should be_nil
100
129
  end
101
130
 
102
131
  it 'should return a non zero total on a normal dice list' do
103
- @bot.plugins.first.roll_dice(['3d3', '4d5']).should_not be_zero
132
+ Cinch::Plugins::Dicebag::Die.roll(['3d3', '4d5']).should_not be_zero
104
133
  end
105
134
 
106
135
  it 'should clear out any invalid dice rolls' do
107
- @bot.plugins.first.roll_dice(['33']).should be_nil
136
+ Cinch::Plugins::Dicebag::Die.roll(['33']).should be_nil
108
137
  end
109
138
 
110
139
  it 'should allow modifiers' do
111
- @bot.plugins.first.roll_dice(['1d1+1', '1d1-4']).should == -1
140
+ Cinch::Plugins::Dicebag::Die.roll(['1d1+1', '1d1-4']).should == -1
112
141
  end
113
142
  end
114
143
 
115
- describe 'roll_die' do
144
+ describe 'Die.roll' do
116
145
  it 'should return an acceptable value for a given roll' do
117
- @bot.plugins.first.roll_die('1d1').should == 1
118
- (3..15).should include(@bot.plugins.first.roll_die('3d5'))
146
+ Cinch::Plugins::Dicebag::Die.roll('1d1').should == 1
147
+ (3..15).should include(Cinch::Plugins::Dicebag::Die.roll('3d5'))
119
148
  end
120
149
 
121
- it 'should return 0 for any negetive values' do
122
- @bot.plugins.first.roll_die('1d-1').should == 0
123
- @bot.plugins.first.roll_die('-1d-1').should == 0
150
+ it 'should return nil for any negetive values' do
151
+ Cinch::Plugins::Dicebag::Die.roll('1d-1').should == nil
152
+ Cinch::Plugins::Dicebag::Die.roll('-1d-1').should == nil
124
153
  end
125
154
 
126
155
  it 'should add modifiers to the total' do
127
- @bot.plugins.first.roll_die('1d1+2').should == 3
128
- @bot.plugins.first.roll_die('3d1-2').should == 1
156
+ Cinch::Plugins::Dicebag::Die.roll('1d1+2').should == 3
157
+ Cinch::Plugins::Dicebag::Die.roll('3d1-2').should == 1
129
158
  end
130
159
 
131
160
  it 'should allow modifiers to take the total below zero' do
132
- @bot.plugins.first.roll_die('1d1-1').should == 0
133
- @bot.plugins.first.roll_die('1d1-2').should == -1
161
+ Cinch::Plugins::Dicebag::Die.roll('1d1-1').should == 0
162
+ Cinch::Plugins::Dicebag::Die.roll('1d1-2').should == -1
134
163
  end
135
164
  end
136
165
 
137
166
  describe 'get_bag_size' do
167
+ before(:each) do
168
+ @bag = Cinch::Plugins::Dicebag::Bag.new({})
169
+ end
170
+
138
171
  it 'should return \'huge\' for out of bounds queries' do
139
- @bot.plugins.first.get_bag_size(50000).should == 'huge'
172
+ @bag.count = 50000
173
+ @bag.size.should == 'huge'
140
174
  end
141
175
 
142
176
  it 'should return the proper size for tiny range' do
143
- @bot.plugins.first.get_bag_size(0).should == 'tiny'
144
- @bot.plugins.first.get_bag_size(rand(100)).should == 'tiny'
145
- @bot.plugins.first.get_bag_size(100).should == 'tiny'
177
+ @bag.count = 0
178
+ @bag.size.should == 'tiny'
179
+ end
180
+
181
+ it 'should return the proper size for small range' do
182
+ @bag.count = rand(100)
183
+ @bag.size.should == 'tiny'
184
+ end
185
+
186
+ it 'should return the proper size for small range' do
187
+ @bag.count = 100
188
+ @bag.size.should == 'tiny'
189
+ end
190
+
191
+ it 'should return the proper size for small range' do
192
+ @bag.count = 101
193
+ @bag.size.should == 'small'
194
+ end
195
+
196
+ it 'should return the proper size for small range' do
197
+ @bag.count = rand(399) + 101
198
+ @bag.size.should == 'small'
146
199
  end
147
200
 
148
201
  it 'should return the proper size for small range' do
149
- @bot.plugins.first.get_bag_size(101).should == 'small'
150
- @bot.plugins.first.get_bag_size(rand(399) + 101).should == 'small'
151
- @bot.plugins.first.get_bag_size(500).should == 'small'
202
+ @bag.count = 500
203
+ @bag.size.should == 'small'
152
204
  end
153
205
 
154
206
  it 'should return the proper size for medium range' do
155
- @bot.plugins.first.get_bag_size(501).should == 'medium'
156
- @bot.plugins.first.get_bag_size(rand(499) + 501).should == 'medium'
157
- @bot.plugins.first.get_bag_size(1000).should == 'medium'
207
+ @bag.count = 501
208
+ @bag.size.should == 'medium'
209
+ end
210
+
211
+ it 'should return the proper size for medium range' do
212
+ @bag.count = rand(499) + 501
213
+ @bag.size.should == 'medium'
214
+ end
215
+
216
+ it 'should return the proper size for medium range' do
217
+ @bag.count = 1000
218
+ @bag.size.should == 'medium'
158
219
  end
159
220
 
160
221
  it 'should return the proper size for large range' do
161
- @bot.plugins.first.get_bag_size(1001).should == 'large'
162
- @bot.plugins.first.get_bag_size(rand(499) + 1001).should == 'large'
163
- @bot.plugins.first.get_bag_size(1500).should == 'large'
222
+ @bag.count = 1001
223
+ @bag.size.should == 'large'
224
+ end
225
+
226
+ it 'should return the proper size for large range' do
227
+ @bag.count = rand(499) + 1001
228
+ @bag.size.should == 'large'
229
+ end
230
+
231
+ it 'should return the proper size for large range' do
232
+ @bag.count = 1500
233
+ @bag.size.should == 'large'
234
+ end
235
+
236
+ it 'should return the proper size for hefty range' do
237
+ @bag.count = 1501
238
+ @bag.size.should == 'hefty'
239
+ end
240
+
241
+ it 'should return the proper size for hefty range' do
242
+ @bag.count = rand(499) + 1501
243
+ @bag.size.should == 'hefty'
164
244
  end
165
245
 
166
246
  it 'should return the proper size for hefty range' do
167
- @bot.plugins.first.get_bag_size(1501).should == 'hefty'
168
- @bot.plugins.first.get_bag_size(rand(499) + 1501).should == 'hefty'
169
- @bot.plugins.first.get_bag_size(2000).should == 'hefty'
247
+ @bag.count = 2000
248
+ @bag.size.should == 'hefty'
249
+ end
250
+
251
+ it 'should return the proper size for huge range' do
252
+ @bag.count = 2001
253
+ @bag.size.should == 'huge'
170
254
  end
171
255
 
172
256
  it 'should return the proper size for huge range' do
173
- @bot.plugins.first.get_bag_size(2001).should == 'huge'
174
- @bot.plugins.first.get_bag_size(20001).should == 'huge'
257
+ @bag.count = 20001
258
+ @bag.size.should == 'huge'
175
259
  end
176
260
  end
177
261
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cinch-dicebag
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.9
4
+ version: 1.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Haberer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-01 00:00:00.000000000 Z
11
+ date: 2014-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -153,6 +153,8 @@ files:
153
153
  - cinch-dicebag.gemspec
154
154
  - lib/cinch-dicebag.rb
155
155
  - lib/cinch/plugins/dicebag.rb
156
+ - lib/cinch/plugins/dicebag/bag.rb
157
+ - lib/cinch/plugins/dicebag/die.rb
156
158
  - lib/cinch/plugins/dicebag/version.rb
157
159
  - spec/cinch-dicebag_spec.rb
158
160
  - spec/spec_helper.rb