dice_roller 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/dice_roller +5 -0
- data/lib/dice_roller/cli.rb +102 -0
- data/lib/dice_roller/dice.rb +18 -0
- data/lib/dice_roller/dice_pool.rb +107 -0
- data/lib/dice_roller/dice_result.rb +106 -0
- data/lib/dice_roller.rb +55 -0
- metadata +70 -0
data/bin/dice_roller
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
# this class handles parsing the command-line options
|
4
|
+
# and calling the appropriate actions
|
5
|
+
class DiceRoller::Cli
|
6
|
+
attr_reader :four, :six, :eight, :ten, :twelve, :twenty, :percentile, :type, :minimum, :reroll, :subtract
|
7
|
+
|
8
|
+
def initialize(args)
|
9
|
+
# default the number of each type of dice to zero
|
10
|
+
four = six = eight = ten = twelve = twenty = percentile = 0
|
11
|
+
|
12
|
+
# default result set to sum
|
13
|
+
type = :sum
|
14
|
+
|
15
|
+
# default minimum value for success to 8
|
16
|
+
minimum = 8
|
17
|
+
|
18
|
+
# default reroll value to 10
|
19
|
+
reroll = 10
|
20
|
+
|
21
|
+
# default to ones not subtracting successes
|
22
|
+
subtract = false
|
23
|
+
|
24
|
+
options = OptionParser.new do |opts|
|
25
|
+
opts.banner = "Usage: dice-roller"
|
26
|
+
|
27
|
+
opts.on("--four dice", Integer, "number of four-sided dice to roll") do |dice|
|
28
|
+
@four = dice
|
29
|
+
end
|
30
|
+
|
31
|
+
opts.on("--six dice", Integer, "number of six-sided dice to roll") do |dice|
|
32
|
+
@six = dice
|
33
|
+
end
|
34
|
+
|
35
|
+
opts.on("--eight dice", Integer, "number of eight-sided dice to roll") do |dice|
|
36
|
+
@eight = dice
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on("--ten dice", Integer, "number of ten-sided dice to roll") do |dice|
|
40
|
+
@ten = dice
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on("--twelve dice", Integer, "number of twelve-sided dice to roll") do |dice|
|
44
|
+
@twelve = dice
|
45
|
+
end
|
46
|
+
|
47
|
+
opts.on("--twenty dice", Integer, "number of twenty-sided dice to roll") do |dice|
|
48
|
+
@twenty = dice
|
49
|
+
end
|
50
|
+
|
51
|
+
opts.on("--percentile dice", Integer, "number of percentile dice to roll") do |dice|
|
52
|
+
@percentile = dice
|
53
|
+
end
|
54
|
+
|
55
|
+
opts.on("--type [sum|successes]", [:sum, :successes], "select type of result (sum, successes)") do |t|
|
56
|
+
@type = t
|
57
|
+
|
58
|
+
if @type.nil?
|
59
|
+
puts opts
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
opts.on("--reroll number", Integer, "rolling this or above rolls another ten-sided dice") do |val|
|
65
|
+
@reroll = val
|
66
|
+
end
|
67
|
+
|
68
|
+
opts.on("--rote", "make this roll a rote action") do |flag|
|
69
|
+
# DiceRoller::DicePool interprets a reroll value of 0 as a rote action
|
70
|
+
@reroll = 0 if flag
|
71
|
+
end
|
72
|
+
|
73
|
+
opts.on("--min number", Integer, "minimum value to be considered a success") do |min|
|
74
|
+
@minimum = min
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on("--[no-]sub", "cause ones to subtract from the success total") do |flag|
|
78
|
+
@subtract = flag
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
begin
|
83
|
+
options.parse!(args)
|
84
|
+
rescue OptionParser::MissingArgument => e
|
85
|
+
puts "Missing argument"
|
86
|
+
puts options
|
87
|
+
exit
|
88
|
+
rescue OptionParser::InvalidArgument => e
|
89
|
+
puts "Invalid argument"
|
90
|
+
puts options
|
91
|
+
exit
|
92
|
+
rescue OptionParser::InvalidOption => e
|
93
|
+
puts "Invalid option"
|
94
|
+
puts options
|
95
|
+
exit
|
96
|
+
end
|
97
|
+
|
98
|
+
return if $TEST
|
99
|
+
|
100
|
+
::DiceRoller.new(@four, @six, @eight, @ten, @twelve, @twenty, @percentile, @type, @reroll, @minimum, @subtract)
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# A class representing a single dice. Rolling this dice returns the result
|
2
|
+
class DiceRoller::Dice
|
3
|
+
attr_accessor :faces
|
4
|
+
attr_reader :value
|
5
|
+
|
6
|
+
# create a single dice
|
7
|
+
#
|
8
|
+
# faces: the number of sides on the dice
|
9
|
+
def initialize(faces = 6)
|
10
|
+
@faces = faces
|
11
|
+
@value = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
# roll the dice, storing and returning the resuilt
|
15
|
+
def roll()
|
16
|
+
@value = rand(@faces) + 1
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# A class representing a bunch of dice (many objects of class Dice).
|
2
|
+
# Rolling this die pool returns an object of the DiceResult class
|
3
|
+
class DiceRoller::DicePool
|
4
|
+
attr_accessor :num_four, :num_six, :num_eight, :num_ten, :num_twelve, :num_twenty, :num_percentile, :result
|
5
|
+
|
6
|
+
# create a pool of Dice with different numbers of sides
|
7
|
+
#
|
8
|
+
# num_four: the number of four-sided dice in the pool
|
9
|
+
# num_six: the number of six-sided dice in the pool
|
10
|
+
# num_eight: the number of eight-sided dice in the pool
|
11
|
+
# num_ten: the number of ten-sided dice in the pool
|
12
|
+
# num_twelve: the number of twelve-sided dice in the pool
|
13
|
+
# num_twenty: the number of twenty-sided dice in the pool
|
14
|
+
# num_percentile: the number of percentile (100-sided) dice in the pool
|
15
|
+
def initialize(four = 0, six = 0, eight = 0, ten = 0, twelve = 0, twenty = 0, percentile = 0)
|
16
|
+
@num_four = four
|
17
|
+
@num_six = six
|
18
|
+
@num_eight = eight
|
19
|
+
@num_ten = ten
|
20
|
+
@num_twelve = twelve
|
21
|
+
@num_twenty = twenty
|
22
|
+
@num_percentile = percentile
|
23
|
+
|
24
|
+
@result = ::DiceRoller::DiceResult.new
|
25
|
+
end
|
26
|
+
|
27
|
+
# roll the dice in the pool, with options. by default, roll_pool returns
|
28
|
+
# the numer of successes rolled
|
29
|
+
#
|
30
|
+
# success_value: on 10-sided dice, the minimum value to be considered a success
|
31
|
+
# sum_num: instead of displaying successes, display the total value rolled on all dice
|
32
|
+
# number_successes: instead of returning the sum total rolled, return the successes
|
33
|
+
# one_cancels: 1s rolled on a d10 subtract from the total successes
|
34
|
+
# roll_again: the number on a d10 above which another d10 should be rolled
|
35
|
+
def roll_pool(success_value = 8, sum_num = false, number_successes = true, one_cancels = false, roll_again = 10)
|
36
|
+
sum_value = 0
|
37
|
+
successes = 0
|
38
|
+
ones = 0
|
39
|
+
rerolls = 0
|
40
|
+
rote_rerolls = 0
|
41
|
+
roll_again = roll_again.to_i
|
42
|
+
rote = false
|
43
|
+
|
44
|
+
if roll_again == 0
|
45
|
+
roll_again = 10
|
46
|
+
rote = true
|
47
|
+
end
|
48
|
+
|
49
|
+
# set up a single dice of each type and an array to store their results
|
50
|
+
four_sided = ::DiceRoller::Dice.new(4)
|
51
|
+
four_results = []
|
52
|
+
|
53
|
+
six_sided = ::DiceRoller::Dice.new(6)
|
54
|
+
six_results = []
|
55
|
+
|
56
|
+
eight_sided = ::DiceRoller::Dice.new(8)
|
57
|
+
eight_results = []
|
58
|
+
|
59
|
+
ten_sided = ::DiceRoller::Dice.new(10)
|
60
|
+
ten_results = []
|
61
|
+
|
62
|
+
twelve_sided = ::DiceRoller::Dice.new(12)
|
63
|
+
twelve_results = []
|
64
|
+
|
65
|
+
twenty_sided = ::DiceRoller::Dice.new(20)
|
66
|
+
twenty_results = []
|
67
|
+
|
68
|
+
percentile = ::DiceRoller::Dice.new(100)
|
69
|
+
percentile_results = []
|
70
|
+
|
71
|
+
# roll dem bones!
|
72
|
+
@num_four.times do
|
73
|
+
four_results << four_sided.roll
|
74
|
+
end
|
75
|
+
@num_six.times do
|
76
|
+
six_results << six_sided.roll
|
77
|
+
end
|
78
|
+
@num_eight.times do
|
79
|
+
eight_results << eight_sided.roll
|
80
|
+
end
|
81
|
+
@num_ten.times do
|
82
|
+
ten_results << ten_sided.roll
|
83
|
+
end
|
84
|
+
@num_twelve.times do
|
85
|
+
twelve_results << twelve_sided.roll
|
86
|
+
end
|
87
|
+
@num_twenty.times do
|
88
|
+
twenty_results << twenty_sided.roll
|
89
|
+
end
|
90
|
+
@num_percentile.times do
|
91
|
+
percentile_results << percentile.roll
|
92
|
+
end
|
93
|
+
|
94
|
+
::DiceRoller::DiceResult.new(four_results, six_results, eight_results, ten_results, twelve_results, twenty_results, percentile_results)
|
95
|
+
end
|
96
|
+
|
97
|
+
# overrides the inspect method to provide some useful output
|
98
|
+
def inspect()
|
99
|
+
puts "four-sided dice: #{@num_four}"
|
100
|
+
puts "six-sided dice: #{@num_six}"
|
101
|
+
puts "eight-sided dice: #{@num_eight}"
|
102
|
+
puts "ten-sided dice: #{@num_ten}"
|
103
|
+
puts "twelve-sided dice: #{@num_twelve}"
|
104
|
+
puts "twenty-sided dice: #{@num_twenty}"
|
105
|
+
puts "percentile dice: #{@num_percentile}"
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# represents a result set from rolled dice
|
2
|
+
# it takes a series of arrays as input -- these arrays
|
3
|
+
# should contain the results of dice rolls
|
4
|
+
class DiceRoller::DiceResult
|
5
|
+
attr_reader :four_result, :six_result, :eight_result, :ten_result, :twelve_result, :twenty_result, :percentile_result
|
6
|
+
|
7
|
+
def initialize(four = [], six = [], eight = [], ten = [], twelve = [], twenty = [], percentile = [])
|
8
|
+
@four_result = four
|
9
|
+
@six_result = six
|
10
|
+
@eight_result = eight
|
11
|
+
@ten_result = ten
|
12
|
+
@twelve_result = twelve
|
13
|
+
@twenty_result = twenty
|
14
|
+
@percentile_result = percentile
|
15
|
+
@rerolled = false
|
16
|
+
end
|
17
|
+
|
18
|
+
# returns the sum total of all values in the results
|
19
|
+
def total
|
20
|
+
sum = 0
|
21
|
+
|
22
|
+
@four_result.each do |result|
|
23
|
+
sum += result
|
24
|
+
end
|
25
|
+
@six_result.each do |result|
|
26
|
+
sum += result
|
27
|
+
end
|
28
|
+
@eight_result.each do |result|
|
29
|
+
sum += result
|
30
|
+
end
|
31
|
+
@ten_result.each do |result|
|
32
|
+
sum += result
|
33
|
+
end
|
34
|
+
@twelve_result.each do |result|
|
35
|
+
sum += result
|
36
|
+
end
|
37
|
+
@twenty_result.each do |result|
|
38
|
+
sum += result
|
39
|
+
end
|
40
|
+
@percentile_result.each do |result|
|
41
|
+
sum += result
|
42
|
+
end
|
43
|
+
|
44
|
+
sum
|
45
|
+
end
|
46
|
+
|
47
|
+
# returns a hash with the number of successes (as determined by the paremeters)
|
48
|
+
# and the results of all the dice rolled
|
49
|
+
#
|
50
|
+
# min: minimum value for a success
|
51
|
+
# reroll: minimum value to roll an additional d10
|
52
|
+
# subtract: if true, causes values of 1 to subtract from the success total
|
53
|
+
def successes(min = 8, reroll = 10, subtract = false)
|
54
|
+
count = 0
|
55
|
+
rote = false
|
56
|
+
|
57
|
+
# if this result set has already been rerolled, simply count the successes
|
58
|
+
# in the result and return the total (rather than rerolling /again/)
|
59
|
+
if @rerolled
|
60
|
+
@ten_result.each do |value|
|
61
|
+
count += 1 if value >= min
|
62
|
+
end
|
63
|
+
|
64
|
+
return count
|
65
|
+
end
|
66
|
+
|
67
|
+
if reroll == 0
|
68
|
+
reroll = 10
|
69
|
+
rote = true
|
70
|
+
end
|
71
|
+
|
72
|
+
# this bonus dice is used for any rerolls that accrue
|
73
|
+
bonus_dice = ::DiceRoller::Dice.new(sides = 10)
|
74
|
+
|
75
|
+
# reroll failed dice once and add the results to the array
|
76
|
+
if rote
|
77
|
+
rote_rerolls = []
|
78
|
+
|
79
|
+
@ten_result.each do |result|
|
80
|
+
rote_rerolls << bonus_dice.roll if result < min
|
81
|
+
end
|
82
|
+
|
83
|
+
@ten_result += rote_rerolls
|
84
|
+
end
|
85
|
+
|
86
|
+
# loop through the rolled results and count successes. values greater than
|
87
|
+
# the reroll value are rolled again.
|
88
|
+
@ten_result.each do |result|
|
89
|
+
count += 1 if result >= min
|
90
|
+
count -= 1 if subtract and result == 1
|
91
|
+
|
92
|
+
# each pass through this loop is a rerolled dice
|
93
|
+
while result >= reroll
|
94
|
+
result = bonus_dice.roll
|
95
|
+
|
96
|
+
# add the result for historical accuracy
|
97
|
+
@ten_result << result
|
98
|
+
|
99
|
+
count += 1 if result >= min
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
@rerolled = true
|
104
|
+
count
|
105
|
+
end
|
106
|
+
end
|
data/lib/dice_roller.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# rolls dice and formats the results
|
2
|
+
class DiceRoller
|
3
|
+
def initialize(four = 0, six = 0, eight = 0, ten = 0, twelve = 0, twenty = 0, percentile = 0, type = :sum, reroll = 10, minimum = 8, subtract = false)
|
4
|
+
results = DicePool.new(four, six, eight, ten, twelve, twenty, percentile).roll_pool
|
5
|
+
|
6
|
+
case type
|
7
|
+
when :sum
|
8
|
+
# output each dice's value and the sum total
|
9
|
+
results.four_result.each do |value|
|
10
|
+
puts "four-sided dice: #{value}"
|
11
|
+
end
|
12
|
+
|
13
|
+
results.six_result.each do |value|
|
14
|
+
puts "six-sided dice: #{value}"
|
15
|
+
end
|
16
|
+
|
17
|
+
results.eight_result.each do |value|
|
18
|
+
puts "eight-sided dice: #{value}"
|
19
|
+
end
|
20
|
+
|
21
|
+
results.ten_result.each do |value|
|
22
|
+
puts "ten-sided dice: #{value}"
|
23
|
+
end
|
24
|
+
|
25
|
+
results.twelve_result.each do |value|
|
26
|
+
puts "twelve-sided dice: #{value}"
|
27
|
+
end
|
28
|
+
|
29
|
+
results.twenty_result.each do |value|
|
30
|
+
puts "twenty-sided dice: #{value}"
|
31
|
+
end
|
32
|
+
|
33
|
+
results.percentile_result.each do |value|
|
34
|
+
puts "percentile dice: #{value}"
|
35
|
+
end
|
36
|
+
|
37
|
+
puts "sum total: #{results.total}"
|
38
|
+
when :successes
|
39
|
+
# output the ten-sided dice's values and the
|
40
|
+
# number of successes
|
41
|
+
suxx = results.successes(minimum, reroll, subtract)
|
42
|
+
|
43
|
+
results.ten_result.each do |value|
|
44
|
+
puts "ten-sided dice: #{value}"
|
45
|
+
end
|
46
|
+
|
47
|
+
puts "successes: #{suxx}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
require 'dice_roller/dice'
|
53
|
+
require 'dice_roller/dice_pool'
|
54
|
+
require 'dice_roller/dice_result'
|
55
|
+
require 'dice_roller/cli'
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dice_roller
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alex Chvatal
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2012-04-27 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: " dice_roller is a pure ruby application that rolls dice for role playing games.\n it is primarily built to handle d20 or Storytelling style rolls.\n"
|
22
|
+
email:
|
23
|
+
- m.chvatal@gmail.com
|
24
|
+
executables:
|
25
|
+
- dice_roller
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/dice_roller/cli.rb
|
32
|
+
- lib/dice_roller/dice.rb
|
33
|
+
- lib/dice_roller/dice_pool.rb
|
34
|
+
- lib/dice_roller/dice_result.rb
|
35
|
+
- lib/dice_roller.rb
|
36
|
+
- bin/dice_roller
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: https://github.com/yithian/dice_roller
|
39
|
+
licenses:
|
40
|
+
- GPL
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options: []
|
43
|
+
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
segments:
|
52
|
+
- 0
|
53
|
+
version: "0"
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
version: "0"
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 1.3.7
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: a dice roller for games
|
69
|
+
test_files: []
|
70
|
+
|