droll 1.0rc5.2.3

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.
data/COPYING ADDED
@@ -0,0 +1,15 @@
1
+ The droll project is copyright 2010, 2011, and 2012 Chad Perrin, and may be
2
+ distributed under the terms of the Open Works License. See the owl.txt file
3
+ for license text.
4
+
5
+ The Rubinius implementation of Ruby allows distribution under the terms of the
6
+ MIT/X11 license. See the [Rubinius project](http://rubini.us) for more details
7
+ about it.
8
+
9
+ The MRI/YARV implementation of Ruby is distributed under the terms of the Ruby
10
+ license, which also allows distribution under the terms of the Simplified
11
+ (2-Clause) BSD License.
12
+
13
+ Drollbot, in addition to the standard library, requires the Isaac library.
14
+ Isaac may be distributed under the terms of the MIT/X11 license. See the
15
+ [Isaac project](https://github.com/ichverstehe/isaac) for more details.
@@ -0,0 +1,178 @@
1
+ # droll
2
+
3
+ Droll, for "d roll" (as in "die roll"), is a dice rolling library and a command
4
+ line utility. Drollbot is an IRC bot that uses the droll and Isaac libraries
5
+ to provide dicebot functionality over IRC.
6
+
7
+ At present, droll provides both normal die rolling capability and simplistic
8
+ exploding die rolling capability (exploding automatically on die rolls that
9
+ return the highest value available on the die). Alternate thresholds for
10
+ exploding can be used. Use NdN as the pattern for normal die rolls (where N
11
+ stands in for a number), and NxN for exploding die rolls. Modifiers can be
12
+ included as well: NdN+N or NdN-N. Die codes, at this time, do not work if they
13
+ have spaces in them. Certain die codes are rejected (i.e. 0x0). Exploding is
14
+ limited to an unreasonably high number (1000), to prevent crashing. Changing
15
+ the exploding threshold uses a .N syntax (NxN.N). Die values are chosen
16
+ (pseudo)randomly from numbers between 1 and N (the number following the x or
17
+ d), or between 0 and N if the N is preceded by a 0 character. An example of
18
+ the full sophistication of die code parsing is:
19
+
20
+ 4x05.4+7
21
+
22
+ This would roll four virtual dice numbered 0-5, and each die would explode on
23
+ any 4 or 5 result. All die results are added together, and 7 added to the
24
+ total to yield a final number.
25
+
26
+ The first number following each 4 or 5 in this example is the result of a die
27
+ immediately rolled to handle exploding die values.
28
+
29
+
30
+ ## installation
31
+
32
+ If you already have Ruby installed, installing droll should be easy. Just
33
+ download the gem package from the [Bitbucket repository][bitbucket] and use the
34
+ gem command to install it:
35
+
36
+ $ gem install droll-<version>.gem
37
+
38
+ In this example, replace `<version>` with the version number in the name of the
39
+ gemfile you downloaded. For version 1.0.0, for instance, the command might
40
+ look like this:
41
+
42
+ $ gem install droll-1.0.0.gem
43
+
44
+ Note that the `$` character indicates your shell prompt, and is not part of the
45
+ command. Depending on your setup, you may need to use `sudo`, log in as root,
46
+ or engage in some other additional activities to ensure the gem is installed
47
+ correctly. If you know of different requirements for installation on other
48
+ systems, please feel free to submit patches to this README file via one of the
49
+ approaches detailed in the **contributions** section at the bottom of this
50
+ file.
51
+
52
+ Eventually, droll will be distributed through Ruby's standard centralized
53
+ package management system, and the entire installation process will be reduced
54
+ to the following for most cases:
55
+
56
+ $ gem install droll
57
+
58
+ That day has not yet arrived. Special circumstances apply to the use of the
59
+ `drollbot` command; see below.
60
+
61
+ ## usage
62
+
63
+ The following sections explain how to use the executable tools that come with
64
+ the droll library: a `droll` command line interface and a `drollbot` IRC
65
+ dicebot.
66
+
67
+
68
+ ### `droll` command line
69
+
70
+ Using the basic droll program from the command line is pretty simple:
71
+
72
+ > droll d20
73
+ d20: [15] + 0 = 15
74
+ > droll 2d4+3
75
+ 2d4+3: [1, 2] + 3 = 6
76
+ > droll 1d10 2d03
77
+ 1d10: [1] + 0 = 1
78
+ 2d03: [3, 2] + 0 = 5
79
+ > droll 4x05.4+7
80
+ 4x05.4+7: [5, 2, 0, 4, 0, 1] + 7 = 19
81
+
82
+ In each example, the numbers between `[brackets]`, separated by commas, are the
83
+ numberic results for each of the individual dice rolled. As shown by the third
84
+ example of using the command line droll program above, multiple die codes can
85
+ be listed on a single line, with the results of each roll being shown on a
86
+ separate line of output. In the last example, the first number following each
87
+ 4 or 5 in this example is the result of a die immediately rolled to handle
88
+ exploding die values.
89
+
90
+
91
+ ### `drollbot` IRC dicebot
92
+
93
+ The drollbot interface to the functionality of the droll library does some
94
+ things a little differently. For instance, any input to a channel monitored by
95
+ drollbot will be checked to see if it starts with a die code that drollbot
96
+ understands. If so, it will parse that line as a command to produce die roll
97
+ output. Starting a line with `droll` or `drollbot` will not have the same
98
+ effect. As such, this may occur:
99
+
100
+ 12:38 < apotheon> 1d20+3
101
+ 12:38 < drollbot> <apotheon> rolls 1d20+3: [10] + 3 = 13
102
+
103
+ The output from drollbot is a touch more verbose; this is an example of how it
104
+ works within a standard IRC channel. Private messages may be sent to drollbot,
105
+ with slightly differently formatted output:
106
+
107
+ 12:40 <apotheon> /msg drollbot 1d20+3
108
+ 12:40 <drollbot> result of 1d20+3: [13] + 3 = 16
109
+
110
+ Note that this example is not perfectly representative. The `/msg` command is
111
+ sent from an IRC channel where the drollbot instance is logged in, and the
112
+ `result` message appears in a PM that is not visible to anyone else in the IRC
113
+ channel where the dicebot was invoked.
114
+
115
+ In either case, a comment may be appended to the end of the line. Within an
116
+ IRC channel:
117
+
118
+ 12:42 < apotheon> 1d20+3 crappy save
119
+ 12:42 < drollbot> <apotheon> rolls 1d20+3: [17] + 3 = 20 (crappy save)
120
+
121
+ Drollbot will echo any text following your die code back to you as a
122
+ parenthetical note. This applies to die codes as well as other text so that,
123
+ unlike with the command line `droll` utility, multiple rolls cannot be
124
+ specified in a single command:
125
+
126
+ 12:43 < apotheon> 2x05 d20+3 2d4 many
127
+ 12:43 < drollbot> <apotheon> rolls 2x05: [4, 2] + 0 = 6 (d20+3 2d4 many)
128
+
129
+ To start drollbot, all you need to do is ensure that it is configured with an
130
+ IRC network to which it should connect, and some channel names it should join,
131
+ then run the program. An example configuration file is included with the
132
+ installed gem. After installing the droll gem, you can find the example
133
+ configuration file in the directory hierarchy where the gem was installed,
134
+ under the `etc` subdirectory. The example configuration file is called
135
+ `drollbot.conf.sample`. Use the `drollbot -c` or `drollbot --config` command
136
+ to see more information about configuring drollbot.
137
+
138
+
139
+ ## license
140
+
141
+ Droll project files may be redistributed under the terms of the Open Works
142
+ License. See owl.txt for license text.
143
+
144
+ Also see the [OWL site][owl] for more details.
145
+
146
+ The OWL was chosen with a conscious adherence to copyfree policies. See the
147
+ [Copyfree Initiative][copyfree] site for more details about the copyfree
148
+ philosophy of licensing.
149
+
150
+ See the COPYING file for more information about copyright and licensing for
151
+ droll and the code associated with it.
152
+
153
+
154
+ ## contributions
155
+
156
+ If you wish to contribute to the project, please feel free to do so.
157
+
158
+ Mercurial (in the form of the hg tool) offers a simple way to produce a patch,
159
+ using the `export` command. To produce a patch based on the most recent
160
+ commits in your local clone of the project, this command should suffice to
161
+ produce a usable patch for an update from the immediately previous commit:
162
+
163
+ > hg export tip
164
+
165
+ * Patches may be submitted via the issue tracker, as a comment with attachment
166
+ in response to whatever issue it fixes.
167
+ * Patches can also be submitted to Chad Perrin via email, using the code at
168
+ apotheon dot net address.
169
+ * Another way to submit contributions is to clone the project on
170
+ [Bitbucket][bitbucket] and send a "pull request" from the clone when changes
171
+ have been made. The process of submitting contributions via fork and pull
172
+ request is described in a TechRepublic article: [*Contribute to Bitbucket
173
+ Projects Using Forks and Pull Requests*][forkpull].
174
+
175
+ [owl]: http://owl.apotheon.org
176
+ [copyfree]: http://copyfree.org
177
+ [bitbucket]: https://bitbucket.org/apotheon/droll/overview
178
+ [forkpull]: http://blogs.techrepublic.com.com/programming-and-development/?p=4028
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'droll'
4
+
5
+ help_text = {
6
+ :quiet => 'Suppress verbose output.',
7
+ :help => 'Display this help text.',
8
+ :syntax => 'Display comprehensive syntax help.',
9
+ :version => 'Display version and license information.'
10
+ }
11
+
12
+ @usage = <<EOF
13
+
14
+ USAGE: #{File.basename $0} [options] [die_code]
15
+
16
+ EOF
17
+
18
+ syntax_help = <<EOF
19
+
20
+ SYNTAX
21
+
22
+ Die codes are constructed from up to five parts:
23
+
24
+ 1. Die Number (Optional; Default: 1)
25
+
26
+ An optional number that determines how many of a die should be
27
+ rolled. For instance, if you wish to get the results of rolling
28
+ two six-sided dice, the number would be 2.
29
+
30
+ 2. Roll Type (Mandatory; No Default)
31
+
32
+ A single-letter code used to specify how rolls should be treated.
33
+
34
+ d Roll normally.
35
+
36
+ x On a result equal to or higher than a threshold value, roll
37
+ another die of that type and add it to the total.
38
+
39
+ e On a result where all dice yield values equal to or higher
40
+ than a threshold value, roll another die of that type and
41
+ add it to the total.
42
+
43
+ 3. Die Value (Mandatory; No Default)
44
+
45
+ Indicates the set of values the die can produce. Two types of die
46
+ value are supported: a normal positive integer value (a whole
47
+ number higher than zero), and such a value preceded by a zero. If
48
+ preceded by a zero, it is treated as a die marked with a range of
49
+ numbers from zero to the value following the zero. Otherwise, it
50
+ is treated as being marked with a range of numbers from one to the
51
+ indicated value.
52
+
53
+ 4. Threshold (Optional; Default: Maximum Value)
54
+
55
+ A threshold may be specified for exploding roll types by attaching
56
+ a number, separated from the die value by a period. Any die result
57
+ equal to or greater than the threshold value causes another die to
58
+ be rolled and added to the total. The threshold is counted for
59
+ every die when using the x Roll Type, or for the sum of all dice
60
+ when using the e Roll Type. It is ignored when using the d Roll
61
+ Type, and a warning is issued.
62
+
63
+ 5. Modifier (Optional; No Default)
64
+
65
+ A plus or minus sign can be used to indicate that a value should be
66
+ added to, or subtracted from, the die roll total. Following the
67
+ plus or minus sign, a numerical value is specified to indicate what
68
+ should be added or subtracted. The modifier is applied to the roll
69
+ total, and not to each individual die roll.
70
+
71
+ EXAMPLES
72
+
73
+ d10 Roll a single ten-sided die for values between 1 and 10.
74
+
75
+ 2d3 Roll two three-sided dice for values between 1 and 3. Add the
76
+ results together, for a total between 2 and 6.
77
+
78
+ 3x02 Roll three three-sided dice for values between 0 and 2. For
79
+ each 2 result, roll another die of the same type. Repeat as
80
+ necessary, and add all values together.
81
+
82
+ 3x02.1 Same as 3x02, but explodes on 1 or higher instead of only on 2.
83
+
84
+ 3x02+3 Same as 3x02, but add 3 to the total.
85
+
86
+ 3e02 Roll three three-sided dice for values between 0 and 2 as
87
+ though rolling 3d02. If all three dice yield 2 results -- and
88
+ only if all three dice yield 2 results, providing a 6 total --
89
+ roll another three- sided die for values between 0 and 2.
90
+ Threat this die as 1x02, and add the exploding total to the
91
+ original 6 result.
92
+
93
+ 3e02.4 Same as 3e02, but roll an additional 1x02 if the total of the
94
+ original 3d02 roll is equal to 4 or greater.
95
+
96
+ EOF
97
+
98
+ version_help = <<EOF
99
+
100
+ Droll #{Droll.version}, Copyright 2010, 2011, 2012 Chad Perrin
101
+ This software may be distributed under the terms of the Open Works License.
102
+ See http://owl.apotheon.org for license details.
103
+
104
+ EOF
105
+
106
+ verbose = true
107
+
108
+ OptionParser.new do |opts|
109
+ opts.banner = @usage
110
+
111
+ opts.on('--quiet', '-q', help_text[:quiet]) do
112
+ verbose = false
113
+ end
114
+
115
+ opts.on('--help', '-h', help_text[:help]) do
116
+ puts opts
117
+ puts
118
+ exit!(0)
119
+ end
120
+
121
+ opts.on('--syntax', '-s', help_text[:syntax]) do
122
+ puts syntax_help
123
+ exit!(0)
124
+ end
125
+
126
+ opts.on_tail('--version', help_text[:version]) do
127
+ puts version_help
128
+ exit!(0)
129
+ end
130
+ end.parse!
131
+
132
+ if 0 < ARGV.size
133
+ ARGV.each do |a|
134
+ droll = Droll.new a
135
+ puts droll.roll(verbose)
136
+ end
137
+ else
138
+ puts @usage
139
+ puts %Q{ Try "#{File.basename $0} --help" for usage information.}
140
+ puts
141
+ end
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env ruby
2
+ require 'optparse'
3
+ require 'droll'
4
+
5
+ help_text = {
6
+ :file => 'Select non-default configuration file.',
7
+ :config => 'Display configuration help text.',
8
+ :help => 'Display this help text.',
9
+ :version => 'Display version and license information.'
10
+ }
11
+
12
+ @usage = <<EOF
13
+
14
+ USAGE: #{File.basename $0} [options] [command]
15
+
16
+ At present, there is only one command: start. Issuing the start command
17
+ starts the drollbot dicebot with settings according to the config file.
18
+
19
+ EOF
20
+
21
+ config_help = <<EOF
22
+
23
+ The drollbot IRC dicebot requires a configuration file to work, because it
24
+ needs to have certain information that cannot reasonably be defined by default.
25
+ The default configuration file is called "drollbot.conf", and is located in the
26
+ .config/droll directory within your user home directory. You can see this in
27
+ the source of the drollbot executable itself, in a line that reads:
28
+
29
+ filename = '~/.config/droll/drollbot.conf'
30
+
31
+ This can be overridden by use of the -f or --file option when entering a
32
+ drollbot command. For instance, to use a freenode-specific config file, you
33
+ might create a file in your home directory called "drollbot_freenode.conf" and
34
+ explicitly use that when starting the drollbot process:
35
+
36
+ drollbot -f '~/drollbot_freenode.conf' start
37
+
38
+ The configuration file, wherever you put it and whatever you call it has a
39
+ dirty little secret. It is actually just a Ruby file that is loaded by
40
+ drollbot to set certain values. Such values include:
41
+
42
+ $nickname IRC nick
43
+ $passwd IRC password
44
+ $ircnet IRC network
45
+ $portno port number
46
+ $ssl SSL switch
47
+ $verbose verbosity switch
48
+ $channels list of channels
49
+
50
+ For each of these, configure by using the label that starts with a dollar sign
51
+ an equal sign, and a value. The values must take the form of literal data
52
+ types in Ruby -- strings, integers, true/false boolean values, and (in the case
53
+ of the $channels lable) an array literal. For instance:
54
+
55
+ $nickname = 'dicebot'
56
+ $ircnet = 'irc.freenode.net'
57
+ $portno = 7000
58
+ $ssl = true
59
+ $channels = ['#botwar', '#drollbot_testing']
60
+
61
+ The port number value must be an integer, a simple number with no punctuation.
62
+ The switch values should be a bare, unpunctuated true or false word. The
63
+ channel list should be a comma separated list of channel names surrounded in
64
+ quotes, enclosed in brackets -- not (parentheses) or {braces}. Other values
65
+ shown here are individual terms surrounded in quotes. Whether you use single
66
+ quotes or double quotes is generally irrelevant, but do not use "curly" quotes
67
+ or backticks, use the same quote character on beginning and end of a value
68
+ (including list item values), and use exactly one quote character at each end
69
+ of a value. To learn more about this syntax, you can learn about Ruby
70
+ programming language data types.
71
+
72
+ Of these configuration values, only three are always important: the IRC nick,
73
+ the IRC network, and the channel list. The necessity of using the rest of them
74
+ depends on the specifics of what IRC network you are using, in what channels
75
+ you want to have a dicebot, and other matters particular to your circumstances.
76
+
77
+ You can find an example configuration file in the directory hierarchy where the
78
+ gem is installed, under the "etc" subdirectory. The example configuration file
79
+ is called "drollbot.conf.sample". It should not be used exactly as written, as
80
+ the nick and password values are not designed to avoid conflicting with
81
+ settings and other users on the default network configuration in that file.
82
+ The two default channels are used for IRC bot testing on the freenode IRC
83
+ network, so they should be safe for purposes of playing around with your
84
+ drollbot instance and learning its quirks.
85
+
86
+ EOF
87
+
88
+ version_help = <<EOF
89
+
90
+ Droll and drollbot #{Droll.version}, Copyright 2010, 2011, 2012 Chad Perrin
91
+ This software may be distributed under the terms of the Open Works License.
92
+ See http://owl.apotheon.org for license details.
93
+
94
+ EOF
95
+
96
+ filename = '~/.config/droll/drollbot.conf'
97
+
98
+ OptionParser.new do |opts|
99
+ opts.banner = @usage
100
+
101
+ opts.on('--file=FILE', '-f=FILE', help_text[:file]) do |val|
102
+ config_file = val.chomp
103
+ end
104
+
105
+ opts.on('--config', '-c', help_text[:config]) do
106
+ puts config_help
107
+ exit(0)
108
+ end
109
+
110
+ opts.on('--help', '-h', help_text[:help]) do
111
+ puts opts
112
+ puts
113
+ exit(0)
114
+ end
115
+
116
+ opts.on_tail('--version', '-v', help_text[:version]) do
117
+ puts version_help
118
+ exit(0)
119
+ end
120
+ end.parse!
121
+
122
+ if ARGV[0] == 'start'
123
+ require 'isaac'
124
+ load filename
125
+
126
+ configure do |c|
127
+ c.nick = $nickname
128
+ c.password = $passwd
129
+ c.server = $ircnet
130
+ c.port = $portno
131
+ c.ssl = $ssl
132
+ c.verbose = $verbose
133
+ end
134
+
135
+ on :connect do
136
+ $channels.each do |chan|
137
+ join chan
138
+ end
139
+ end
140
+
141
+ on :channel, /^([0-9]*[dex][0-9]+(\.\d+)?[+-]?[0-9]*)\s*(.*)/ do
142
+ droll = Droll.new match[0]
143
+ result = droll.roll
144
+ output = "<#{nick}> rolls " + result
145
+
146
+ if match.length > 1
147
+ if match[-1].length > 0
148
+ output += " (#{match[-1]})"
149
+ end
150
+ end
151
+ msg channel, output
152
+ end
153
+
154
+ on :private, /^([0-9]*[dex][0-9]+(\.\d+)?[+-]?[0-9]*)\s*(.*)/ do
155
+ droll = Droll.new match[0]
156
+ result = droll.roll
157
+ output = 'result of ' + result
158
+
159
+ if match.length > 1
160
+ if match[-1].length > 0
161
+ output += " (#{match[-1]})"
162
+ end
163
+ end
164
+ msg nick, output
165
+ end
166
+ end
@@ -0,0 +1,8 @@
1
+ $nickname = 'foo'
2
+ $passwd = 'bar'
3
+ $ircnet = 'irc.freenode.net'
4
+ $portno = 7000
5
+ $ssl = true
6
+ $verbose = true
7
+
8
+ $channels = ['#botwar', '##botwar']
@@ -0,0 +1,256 @@
1
+ =begin rdoc
2
+
3
+ Droll provides a Ruby class that parses die codes as normally presented in
4
+ roleplaying game texts, i.e.:
5
+
6
+ 3d4+7
7
+
8
+ This die code indicates that four-sided dice numbered 1-4 should be rolled --
9
+ three of them. Their totals should be added together, and the number 7 should
10
+ be added to the total. If only one die should be rolled, it can be represented
11
+ as either 1d4 or, in abbreviated form, as d4. Numbers may be either added or
12
+ subtracted (e.g. 3d4-7), or no modifiers may be applied at all (e.g. 3d4). A
13
+ "normal" six-sided die, a cube with numbers or "pips" to indicate the value of
14
+ each face, is represented by 1d6 or d6. Droll's handling of die codes is case
15
+ sensitive, such that 3D4 will not work as described above.
16
+
17
+ === Additional Syntax Options
18
+
19
+ The syntax accepted by Droll is more sophisticated than the above might
20
+ indicate, to accommodate special die roll semantics.
21
+
22
+ ==== Exploding
23
+
24
+ Dice in some game systems may "explode". This means that, under certain
25
+ conditions, the result on a die may indicate that another die should be rolled
26
+ and added to the total as well. The most common case is where any die that
27
+ produces the maximum possible value for that die indicates that another die
28
+ should be rolled and added to the total. Normal exploding die syntax uses x
29
+ instead of d in the die code:
30
+
31
+ 3x4+7
32
+
33
+ In this case, when each d4 is rolled, an additional die is rolled if that die's
34
+ value is 4 (the maximum value for the die). The modifier is applied to the
35
+ total after all dice (including exploding dice) are rolled and added together.
36
+
37
+ An alternate exploding method only explodes if *all* dice rolled produce a
38
+ result of the maximum value each die can produce. This uses e instead of d or
39
+ x in the die code:
40
+
41
+ 3e4+7
42
+
43
+ In this case, if the total of the 3d4 roll is 12, an additional d4 is rolled
44
+ and added to the running total, and if that (or any subsequent d4 rolls that
45
+ are part of the same 3e4+7 dice roll resolution) is another 4 result, it
46
+ explodes again. If two 4 results and a 3 result come from that roll of 3d4, no
47
+ exploding occurs, leaving an 11 result from the virtual dice. As normal, when
48
+ all die rolling is resolved and summed, the modifier (+7 in this case) is
49
+ applied to the total.
50
+
51
+ ==== Explosion Threshold
52
+
53
+ An exploding threshold may be specified by a period/fullstop character followed
54
+ by a number, with any modifiers coming after it:
55
+
56
+ 3x4.3+7
57
+
58
+ In this case, the die code is treated the same way as in the previous example,
59
+ except that it explodes on 3 or 4, and not just on 4.
60
+
61
+ ==== Alternate Minimum Value
62
+
63
+ Dice whose value ranges start at 0 instead of 1 are also possible. To indicate
64
+ a 0-N range, precede the die value with a 0 in the die code:
65
+
66
+ 3d03
67
+
68
+ This die code rolls three virtual dice whose values may be anywhere in the
69
+ range of 0-3 and returns the total for all three dice. For other minimum
70
+ values, apply a modifier. For instance, for a value ranging from -3 to 0, a
71
+ die code like the following may be used:
72
+
73
+ d03-3
74
+
75
+ === Usage:
76
+
77
+ ==== API:
78
+
79
+ require 'droll'
80
+
81
+ droll = Droll.new '3x4.3+7'
82
+ puts droll.roll
83
+
84
+ The above example produces output like the following:
85
+
86
+ 3x4.3+7: [4, 1, 4, 4, 2, 2] + 7 = 24
87
+
88
+ ==== Command Line:
89
+
90
+ droll 3x4.3+7
91
+
92
+ The above example produces output like the API usage example.
93
+
94
+ =end
95
+
96
+
97
+ class Droll
98
+
99
+ =begin rdoc
100
+
101
+ This method returns the version number for the Droll gem.
102
+
103
+ =end
104
+
105
+ def self.version; '1.0rc5.2.3'; end
106
+
107
+ =begin rdoc
108
+
109
+ The +dcode+ argument is any valid die code recognized by Droll.
110
+
111
+ Droll.new '4x7+3'
112
+
113
+ =end
114
+
115
+ def initialize(dcode)
116
+ @dcode = dcode
117
+ @pcode = process_die
118
+ end
119
+
120
+ private
121
+
122
+ def valid?
123
+ if @dcode.match(
124
+ /^[1-9]*[0-9]*[A-Za-z][0-9]?[1-9]+[0-9]?(\.\d+)?[+-]?[0-9]*\s*(.*)$/
125
+ )
126
+ validation = true
127
+ else
128
+ validation = false
129
+ end
130
+
131
+ if 1 > @pcode['val'].to_i
132
+ return false
133
+ end
134
+
135
+ if 1 > @pcode['thresh'].to_i
136
+ return false
137
+ end
138
+
139
+ if 1 > @pcode['num'].to_i
140
+ return false
141
+ end
142
+
143
+ if 0 == @pcode['val'][0].to_i
144
+ if 1 > @pcode['val'].to_i
145
+ return false
146
+ end
147
+ end
148
+
149
+ if 0 != @pcode['val'][0].to_i
150
+ if 2 > @pcode['val'].to_i
151
+ return false
152
+ elsif 2 > @pcode['thresh'].to_i
153
+ return false
154
+ end
155
+ end
156
+
157
+ return validation
158
+ end
159
+
160
+ def process_die
161
+ d = Hash.new
162
+ die_roll, d['sign'], d['mod'] = @dcode.split(/([+-])/)
163
+ d['num'], d['type'], die_vals = die_roll.split(/([A-Za-z])/)
164
+ d['val'], d['thresh'] = die_vals.split(/\./)
165
+ d['val'] = d['val'].to_s
166
+ d['thresh'] ||= d['val'].sub(/^0/, '')
167
+
168
+ d['num'] = 1 if d['num'] == ''
169
+ d['sign'] ||= '+'
170
+ d['mod'] ||= 0
171
+
172
+ return d
173
+ end
174
+
175
+ def get_discrete(dval)
176
+ dval.match(/^0/) ? rand(dval.to_i + 1) : 1 + (rand dval.to_i)
177
+ end
178
+
179
+ def roll_die(die_value, die_type, die_threshhold)
180
+ discrete_rolls = [get_discrete(die_value)]
181
+
182
+ case die_type
183
+ when 'x'
184
+ c = 0
185
+ while c < 1000
186
+ if discrete_rolls[-1] >= die_threshhold.to_i
187
+ discrete_rolls.push get_discrete(die_value)
188
+ c += 1
189
+ else
190
+ break
191
+ end
192
+ end
193
+ end
194
+
195
+ discrete_rolls.compact
196
+ end
197
+
198
+ public
199
+
200
+ =begin
201
+
202
+ By default, this method returns a string showing the die code rolled, the
203
+ individual die rolls that make up the complete roll of dice, the modifier
204
+ applied to the roll (showing "\+ 0" if no modifier was given), and the result,
205
+ in the following format:
206
+
207
+ 3d6+2: [3, 4, 1] + 2 = 10
208
+
209
+ If the +formatted+ argument is given a +false+ value, this method returns only
210
+ an integer equal to the total result.
211
+
212
+ =end
213
+
214
+ def roll(formatted=true)
215
+ running_totals = Array.new
216
+
217
+ return "bad die code: #{@dcode}" unless valid?
218
+
219
+ @pcode['num'].to_i.times do
220
+ running_totals.push(
221
+ roll_die @pcode['val'], @pcode['type'], @pcode['thresh']
222
+ )
223
+ running_totals.flatten!
224
+ end
225
+
226
+ if @pcode['type'] == 'e'
227
+ dice_total = running_totals.map {|s| s.to_i}.inject(:+)
228
+ if dice_total >= @pcode['thresh'].to_i
229
+ running_totals.push(
230
+ roll_die @pcode['val'], 'x', @pcode['thresh']
231
+ )
232
+ end
233
+ running_totals.flatten!
234
+ end
235
+
236
+ total_result = running_totals.map {|s| s.to_i }.inject do |sum,n|
237
+ sum ? sum+n : n
238
+ end
239
+
240
+ case @pcode['sign']
241
+ when '+'
242
+ total_result += @pcode['mod'].to_i
243
+ when '-'
244
+ total_result -= @pcode['mod'].to_i
245
+ end
246
+
247
+ if formatted
248
+ result = "#{@dcode}: #{running_totals.inspect} "
249
+ result += "#{@pcode['sign']} #{@pcode['mod']} = "
250
+
251
+ result + total_result.to_s
252
+ else
253
+ total_result
254
+ end
255
+ end
256
+ end
data/owl.txt ADDED
@@ -0,0 +1,23 @@
1
+ # Open Works License
2
+
3
+ This is version 0.9.2 of the Open Works License.
4
+
5
+ ## Terms
6
+
7
+ Permission is hereby granted by the copyright holder(s), author(s), and
8
+ contributor(s) of this work, to any person who obtains a copy of this work in
9
+ any form, to reproduce, modify, distribute, publish, sell, use, or otherwise
10
+ deal in the licensed material without restriction, provided the following
11
+ conditions are met:
12
+
13
+ Redistributions, modified or unmodified, in whole or in part, must retain
14
+ applicable copyright notices, the above license notice, these conditions, and
15
+ the following disclaimer.
16
+
17
+ NO WARRANTY OF ANY KIND IS IMPLIED BY, OR SHOULD BE INFERRED FROM, THIS LICENSE
18
+ OR THE ACT OF DISTRIBUTION UNDER THE TERMS OF THIS LICENSE, INCLUDING BUT NOT
19
+ LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
20
+ AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22
+ CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE
23
+ WORK, OR THE USE OF OR OTHER DEALINGS IN THE WORK.
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: droll
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0rc5.2.3
5
+ prerelease: 3
6
+ platform: ruby
7
+ authors:
8
+ - Chad Perrin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: isaac
16
+ requirement: &12637340 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '0.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *12637340
25
+ description: ! " Droll is a Ruby library providing dice roller functionality, with
26
+ a\n command line utility and an IRC bot as included user interfaces.\n"
27
+ email: code@apotheon.net
28
+ executables:
29
+ - droll
30
+ - drollbot
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - COPYING
35
+ - README.markdown
36
+ - owl.txt
37
+ - lib/droll.rb
38
+ - bin/droll
39
+ - bin/drollbot
40
+ - etc/drollbot.conf.sample
41
+ homepage: https://bitbucket.org/apotheon/droll
42
+ licenses:
43
+ - OWL
44
+ post_install_message:
45
+ rdoc_options: []
46
+ require_paths:
47
+ - lib
48
+ required_ruby_version: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ required_rubygems_version: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>'
58
+ - !ruby/object:Gem::Version
59
+ version: 1.3.1
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 1.8.15
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Droll - Dice Roller Library
66
+ test_files: []