cinch-dicebag 1.0.9 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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