dicechucker 0.6.0 → 0.8.0
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/README.md +96 -30
- data/VERSION +1 -1
- data/bin/roll +2 -3
- data/lib/dicechucker/dice.rb +77 -48
- data/lib/dicechucker/diesheet.rb +44 -0
- data/lib/dicechucker.rb +43 -2
- data/test/test_dice.rb +51 -11
- data/test/test_diesheet.rb +61 -0
- metadata +6 -6
- data/lib/dicechucker/game_logic.rb +0 -29
- data/test/test_game_logic.rb +0 -33
data/README.md
CHANGED
@@ -1,53 +1,119 @@
|
|
1
1
|
Dicechucker
|
2
2
|
===========
|
3
3
|
|
4
|
-
Dicechucker is a die-rolling library for Ruby that accepts standard
|
4
|
+
Dicechucker is a die-rolling library for Ruby that accepts standard
|
5
|
+
dice notation (XdYS+Z). S is a fairly new pattern for dice notation
|
6
|
+
that refers to special instructions; typically this is either L for
|
7
|
+
'drop low' or H for 'drop high'. Dicechucker also supports E for
|
8
|
+
'explode'.
|
9
|
+
|
10
|
+
Dicechucker also supports Diesheets, which are collections of diesets
|
11
|
+
that can be rolled together. For example, a standard d20 first-level
|
12
|
+
character requires seven rolls: one for each of six basic stats, and
|
13
|
+
one for hit points. A diesheet can define all seven rolls, so that
|
14
|
+
you can generate an entire character all at once.
|
15
|
+
|
16
|
+
|
17
|
+
Installation
|
18
|
+
------------
|
19
|
+
Dicechucker is installed via a gem package: `gem install dicechucker`.
|
5
20
|
|
6
21
|
Basic Usage
|
7
22
|
-----------
|
8
23
|
|
9
|
-
|
10
|
-
|
24
|
+
Please note that usage has changed significantly since the initial
|
25
|
+
0.6.0 release:
|
11
26
|
|
12
27
|
Parse a string to make a Dice object:
|
13
|
-
foo = Dicechucker
|
14
|
-
|
15
|
-
|
16
|
-
bar = foo.roll #total
|
17
|
-
bar = foo.
|
18
|
-
bar = foo.
|
19
|
-
|
20
|
-
|
28
|
+
foo = Dicechucker.parse(XdYS+Z)
|
29
|
+
|
30
|
+
Rolling and getting results:
|
31
|
+
bar = foo.roll #rolls the dice and gives you a total
|
32
|
+
bar = foo.results #gives you an array of individual rolls
|
33
|
+
bar = foo.total #gives you the total roll without re-rolling
|
34
|
+
bar = foo.report #gives you an english description without re-rolling
|
35
|
+
bar = foo.modifier #gives you only the modifier for the dieset
|
36
|
+
foo.roll # just rolls the dice
|
37
|
+
# total, results, and report now have different output
|
38
|
+
|
39
|
+
Please note that Dicechucker::Dice.new is deprecated. Dice is now a
|
40
|
+
parent class that can still be created, but will probably not give you
|
41
|
+
the results you're hoping for. Use Dicechucker.parse to create new diesets.
|
42
|
+
|
43
|
+
Other Dice Behaviors:
|
21
44
|
-------------------
|
22
45
|
|
23
|
-
|
24
|
-
|
25
|
-
drop_high(number_to_drop = 1, individual_results = false): Rolls the dice, and drops the highest number_to_drop results. Returns either a total or an array of individual results.
|
26
|
-
|
27
|
-
drop_low(number_to_drop = 1, individual_results = false): Rolls the dice, and drops the lowest number_to_drop results. Returns either a total or an array of individual results.
|
28
|
-
|
29
|
-
explode(individual_results = false). Rolls the dice. For each die which has a maximum result (e.g., 6 on a d6), that result is kept and another die is rolled. Returns either a total or an array of individual results.
|
46
|
+
Dicechucker imbeds special instructions into the dieset, so that you
|
47
|
+
don't need to do anything except .roll the dice.
|
30
48
|
|
31
49
|
Examples
|
32
50
|
------
|
33
|
-
|
34
|
-
|
51
|
+
Make a dieset comprised of three six-sided dice, with the total
|
52
|
+
modified by +1:
|
53
|
+
stat_dice = Dicechucker.parse('3d6+1')
|
35
54
|
|
36
|
-
To
|
37
|
-
|
55
|
+
To roll the dice and get a total (assume 4, 5, 6 rolled):
|
56
|
+
my_roll = stat_dice.roll # => 16
|
38
57
|
|
39
|
-
To
|
40
|
-
stat_dice.
|
41
|
-
|
42
|
-
To roll the dice and get individual dice and the modifier back:
|
43
|
-
stat_dice.roll(true) # => [4, 5, 6, 1]
|
58
|
+
To see the individual rolls that got you that total:
|
59
|
+
stat_dice.results # => [4, 5, 6]
|
44
60
|
|
45
61
|
To get a plain English result:
|
46
|
-
stat_dice.
|
62
|
+
stat_dice.report # => 'rolled 4, 5, 6 plus one for a total of 16.'
|
47
63
|
|
48
64
|
To roll 4d6+0 and drop the low die (results assume 3, 4, 5, 6 rolled):
|
49
|
-
easy_stat_dice = Dicechucker
|
50
|
-
stat = easy_stat_dice.
|
65
|
+
easy_stat_dice = Dicechucker.parse('4d6L')
|
66
|
+
stat = easy_stat_dice.roll # => 15
|
67
|
+
|
68
|
+
If you want to see what the dropped die was:
|
69
|
+
easy_stat_dice.dropped # => 3
|
70
|
+
|
71
|
+
Diesheets:
|
72
|
+
----------
|
73
|
+
|
74
|
+
Diesheets are hash-based for your dice-chucking convenience.
|
75
|
+
|
76
|
+
To set up a die sheet for a standard d20 warrior:
|
77
|
+
warrior = Dicechucker::Diesheet.new({
|
78
|
+
"STR" => "4d6L"
|
79
|
+
"DEX" => "4d6L"
|
80
|
+
"CON" => "4d6L"
|
81
|
+
"INT" => "4d6L"
|
82
|
+
"WIS" => "4d6L"
|
83
|
+
"CHA" => "4d6L"
|
84
|
+
"HP" => "1d10" })
|
85
|
+
puts warrior
|
86
|
+
# Gives you the results...
|
87
|
+
#STR = 14
|
88
|
+
#DEX = 12
|
89
|
+
#CON = 15
|
90
|
+
#etc...
|
91
|
+
|
92
|
+
Diesheets also support .add to add a dieset, so the above example can
|
93
|
+
be shortened greatly:
|
94
|
+
warrior = Dicechucker::Diesheet.new
|
95
|
+
['STR', 'DEX', 'CON', 'INT', 'WIS', 'CHA'].each do |stat|
|
96
|
+
warrior.add(stat, '4d6L')
|
97
|
+
end
|
98
|
+
warrior.add('HP', '1d10')
|
99
|
+
puts warrior
|
100
|
+
|
101
|
+
Finally, each dieset in a diesheet is individually addressable, so if
|
102
|
+
you want to see what your warrior rolled for strength - or allow your
|
103
|
+
warrior a strength re-roll, you kind GM, you - it's easy to do:
|
104
|
+
warrior['STR'].results # => [2, 3, 2]
|
105
|
+
warrior['STR'].roll # => Re-roll that garbage!
|
106
|
+
warrior.puts # => Gives you the new STR roll and all the other
|
107
|
+
# => unchanged results
|
108
|
+
|
109
|
+
|
110
|
+
Diesheets are rolled automatically when created. When a dieset is
|
111
|
+
added, just that dieset is rolled. When a dieset is removed, nothing
|
112
|
+
happens to the rest of the diesets in the diesheet. In other words,
|
113
|
+
every dieset is instantiated with a rolled result, but if you want a
|
114
|
+
fresh batch of results you'll need to call the .roll method on your
|
115
|
+
diesheet.
|
116
|
+
|
51
117
|
|
52
118
|
Copyright
|
53
119
|
---------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0
|
data/bin/roll
CHANGED
@@ -1,9 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require File.expand_path('../../lib/dicechucker.rb', __FILE__)
|
3
|
-
|
4
3
|
begin
|
5
|
-
dice = Dicechucker::
|
6
|
-
puts "You #{dice.
|
4
|
+
dice = Dicechucker::parse(ARGV[0])
|
5
|
+
puts "You #{dice.report}"
|
7
6
|
rescue => err
|
8
7
|
abort "#{err} -- aborting."
|
9
8
|
end
|
data/lib/dicechucker/dice.rb
CHANGED
@@ -1,71 +1,100 @@
|
|
1
|
-
require File.expand_path('../game_logic.rb', __FILE__)
|
2
|
-
|
3
1
|
module Dicechucker
|
4
2
|
|
5
3
|
class Dice
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
attr_accessor :number_of_dice, :sides, :modifier, :results, :total
|
5
|
+
|
6
|
+
def initialize(dice, sides, modifier)
|
7
|
+
@number_of_dice = dice
|
8
|
+
@sides = sides
|
9
|
+
@modifier = modifier
|
10
|
+
roll
|
9
11
|
end
|
10
|
-
|
11
|
-
PATTERN = /^(?:(?<dice>\d+)d)?(?<size>\d+)(?<mod>[+\-]\d+)?$/
|
12
12
|
|
13
|
-
|
13
|
+
def roll
|
14
|
+
roll_dice
|
15
|
+
@total = @results.inject(:+) + @modifier
|
16
|
+
end
|
14
17
|
|
15
|
-
def
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
raise NotationError, "Invalid die notation, #{raw}"
|
18
|
+
def report
|
19
|
+
rep = 'rolled '
|
20
|
+
rep << @results.join(', ')
|
21
|
+
if @modifier > 0
|
22
|
+
rep << " plus #{@modifier}"
|
23
|
+
elsif @modifier < 0
|
24
|
+
rep << " minus #{@modifier}"
|
23
25
|
end
|
26
|
+
rep << " for a total of #{@total}."
|
27
|
+
rep
|
24
28
|
end
|
25
|
-
|
26
|
-
def
|
27
|
-
@
|
28
|
-
|
29
|
-
|
29
|
+
|
30
|
+
def ==(other)
|
31
|
+
[@number_of_dice == other.number_of_dice,
|
32
|
+
@sides == other.sides,
|
33
|
+
@modifier == other.modifier,
|
34
|
+
self.class == other.class].all?
|
30
35
|
end
|
31
36
|
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
private
|
38
|
+
|
39
|
+
def roll_dice
|
40
|
+
@results = Array.new(@number_of_dice) { (rand * @sides + 1).to_i}
|
35
41
|
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
class DiceDropper < Dice
|
46
|
+
attr_accessor :dropped
|
36
47
|
|
37
|
-
def
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
if @mod > 0
|
42
|
-
mod_english = "plus #{@mod} "
|
43
|
-
elsif @mod < 0
|
44
|
-
mod_english = "minus #{@mod.abs} "
|
45
|
-
else
|
46
|
-
mod_english = ''
|
47
|
-
end
|
48
|
-
"rolled #{dice} #{mod_english}for a total of #{total}."
|
48
|
+
def roll
|
49
|
+
roll_dice
|
50
|
+
@dropped = @results.delete_at(@results.index(drop_target))
|
51
|
+
@total = @results.inject(:+) + @modifier
|
49
52
|
end
|
50
53
|
|
51
|
-
def
|
52
|
-
|
54
|
+
def report
|
55
|
+
rep = super
|
56
|
+
rep << " Dropped #{@dropped}."
|
57
|
+
rep
|
53
58
|
end
|
54
59
|
|
55
|
-
|
60
|
+
def drop_target
|
61
|
+
raise NotImplementedError, "drop_target must be overwritten by child classes"
|
62
|
+
#defined only for use by subclasses
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class DiceDropLow < DiceDropper
|
68
|
+
def drop_target
|
69
|
+
@results.min
|
70
|
+
end
|
71
|
+
end
|
56
72
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
73
|
+
class DiceDropHigh < DiceDropper
|
74
|
+
def drop_target
|
75
|
+
@results.max
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class DiceExplode < Dice
|
80
|
+
def roll
|
81
|
+
roll_dice
|
82
|
+
@results.each.with_index do |roll, index|
|
83
|
+
if roll == @sides
|
84
|
+
@results.insert(index + 1, (rand(@sides)+1))
|
85
|
+
end
|
62
86
|
end
|
63
|
-
|
87
|
+
@total = @results.inject(:+) + @modifier
|
64
88
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
class DieSingle < Dice
|
93
|
+
def report
|
94
|
+
"rolled #{@total}."
|
68
95
|
end
|
69
96
|
end
|
97
|
+
|
70
98
|
end
|
71
99
|
|
100
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Dicechucker
|
2
|
+
|
3
|
+
class Diesheet
|
4
|
+
attr_accessor :diesets
|
5
|
+
|
6
|
+
def initialize(diesets = {})
|
7
|
+
@diesets = {}
|
8
|
+
diesets.each do |key, value|
|
9
|
+
@diesets[key] = Dicechucker.parse(value)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](key)
|
14
|
+
@diesets[key]
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(key, dieset)
|
18
|
+
@diesets[key] = Dicechucker.parse(dieset)
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove(key)
|
22
|
+
@diesets.delete(key)
|
23
|
+
end
|
24
|
+
|
25
|
+
def roll
|
26
|
+
@diesets.each_value do |value|
|
27
|
+
value.roll
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def results
|
32
|
+
to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
output = ""
|
37
|
+
@diesets.each do |key, value|
|
38
|
+
output << "#{key.to_s} = #{value.total.to_s}\n"
|
39
|
+
end
|
40
|
+
output
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/lib/dicechucker.rb
CHANGED
@@ -1,4 +1,45 @@
|
|
1
1
|
module Dicechucker
|
2
|
-
autoload :
|
3
|
-
autoload :
|
2
|
+
autoload :Diesheet, File.expand_path('../dicechucker/diesheet.rb', __FILE__)
|
3
|
+
autoload :Dice, File.expand_path('../dicechucker/dice.rb', __FILE__)
|
4
|
+
autoload :DieSingle, File.expand_path('../dicechucker/dice.rb', __FILE__)
|
5
|
+
autoload :DiceDropHigh, File.expand_path('../dicechucker/dice.rb', __FILE__)
|
6
|
+
autoload :DiceDropLow, File.expand_path('../dicechucker/dice.rb', __FILE__)
|
7
|
+
autoload :DiceExplode, File.expand_path('../dicechucker/dice.rb', __FILE__)
|
8
|
+
|
9
|
+
|
10
|
+
class NotationError < ArgumentError
|
11
|
+
end
|
12
|
+
|
13
|
+
PATTERN = /^(?:(?<dice>\d+)d)?(?<size>\d+)(?<logic>[eEhHlL])?(?<mod>[+\-]\d+)?$/
|
14
|
+
|
15
|
+
def self.parse(raw, reportstyle = :total_only)
|
16
|
+
if (match = raw.match(PATTERN))
|
17
|
+
dice = Integer(match[:dice]) rescue 1
|
18
|
+
size = Integer(match[:size])
|
19
|
+
mod = Integer(match[:mod]) rescue 0
|
20
|
+
logic = String(match[:logic]) rescue nil
|
21
|
+
dieset = make_dice(dice, size, logic, mod)
|
22
|
+
dieset.roll
|
23
|
+
dieset
|
24
|
+
else
|
25
|
+
raise NotationError, "Invalid die notation, #{raw}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.make_dice(dice, size, logic, mod)
|
30
|
+
case logic.upcase
|
31
|
+
when 'L'
|
32
|
+
return DiceDropLow.new(dice, size, mod)
|
33
|
+
when 'H'
|
34
|
+
return DiceDropHigh.new(dice, size, mod)
|
35
|
+
when 'E'
|
36
|
+
return DiceExplode.new(dice, size, mod)
|
37
|
+
end
|
38
|
+
if dice == 1 and mod == 0
|
39
|
+
return DieSingle.new(dice, size, mod)
|
40
|
+
end
|
41
|
+
return Dice.new(dice, size, mod)
|
42
|
+
end
|
43
|
+
|
44
|
+
|
4
45
|
end
|
data/test/test_dice.rb
CHANGED
@@ -4,49 +4,89 @@ class TestDice < MiniTest::Unit::TestCase
|
|
4
4
|
include Dicechucker
|
5
5
|
|
6
6
|
def setup
|
7
|
-
|
7
|
+
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
|
8
12
|
end
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
14
|
+
|
15
|
+
def test_dice_parse_single_explicit
|
16
|
+
first = DieSingle.new(1, 20, 0)
|
17
|
+
second = Dicechucker.parse('1d20')
|
13
18
|
assert_equal first, second
|
14
19
|
end
|
15
20
|
|
16
|
-
def
|
21
|
+
def test_dice_parse_single_implied
|
22
|
+
first = DieSingle.new(1, 20, 0)
|
23
|
+
second = Dicechucker.parse('20')
|
24
|
+
assert first == second
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_dice_parse_instructions
|
28
|
+
exploder = Dicechucker.parse('6d10E')
|
29
|
+
drop_low = Dicechucker.parse('4d6L')
|
30
|
+
drop_high = Dicechucker.parse('4d3H+2')
|
31
|
+
assert_equal exploder.class, Dicechucker::DiceExplode
|
32
|
+
assert_equal drop_low.class, Dicechucker::DiceDropLow
|
33
|
+
assert_equal drop_high.class, Dicechucker::DiceDropHigh
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_dice_parse_plural_negative_mod
|
17
37
|
first = Dice.new(2, 20, -4)
|
18
|
-
second =
|
38
|
+
second = Dicechucker.parse('2d20-4')
|
19
39
|
assert_equal first, second
|
20
40
|
end
|
21
41
|
|
22
42
|
def test_dice_parse_large_numbers
|
23
43
|
first = Dice.new(300, 5000, 2000)
|
24
|
-
second =
|
44
|
+
second = Dicechucker.parse('300d5000+2000')
|
25
45
|
assert_equal first, second
|
26
46
|
end
|
27
47
|
|
28
|
-
def
|
48
|
+
def test_die_roll_single
|
29
49
|
testroll = Dice.new(1, 6, 0)
|
50
|
+
testroll.stubs(:rand => 0.5)
|
30
51
|
assert_equal testroll.roll, 4
|
31
|
-
|
32
52
|
end
|
33
53
|
|
34
54
|
def test_dice_roll_plural
|
35
55
|
testroll = Dice.new(2, 6, 0)
|
56
|
+
testroll.stubs(:rand => 0.5)
|
36
57
|
assert_equal testroll.roll, 8
|
37
58
|
end
|
38
59
|
|
39
60
|
def test_dice_average_plural_mod
|
40
61
|
testroll = Dice.new(2, 6, 2)
|
62
|
+
testroll.stubs(:rand => 0.5)
|
41
63
|
assert_equal testroll.roll, 10
|
42
64
|
end
|
43
65
|
|
44
|
-
def
|
66
|
+
def test_dice_roll_report
|
45
67
|
testroll = Dice.new(2, 20, 4)
|
46
|
-
|
68
|
+
testroll.stubs(:rand => 0.5)
|
69
|
+
testroll.roll
|
70
|
+
result = testroll.report
|
47
71
|
sample = 'rolled 11, 11 plus 4 for a total of 26.'
|
48
72
|
assert_equal result, sample
|
49
73
|
end
|
50
74
|
|
75
|
+
def test_dice_drop_low
|
76
|
+
testroll = Dicechucker.parse('4d6L')
|
77
|
+
testroll.stubs(:rand => 0.5)
|
78
|
+
testroll.roll
|
79
|
+
assert_equal testroll.total, 12
|
80
|
+
assert_equal testroll.dropped, 4
|
81
|
+
assert_equal testroll.report, 'rolled 4, 4, 4 for a total of 12. Dropped 4.'
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_single_die_report
|
85
|
+
testroll = Dicechucker.parse('20')
|
86
|
+
testroll.stubs(:rand => 0.5)
|
87
|
+
testroll.roll
|
88
|
+
assert_equal testroll.report, 'rolled 11.'
|
89
|
+
end
|
90
|
+
|
51
91
|
end
|
52
92
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestDice < MiniTest::Unit::TestCase
|
4
|
+
include Dicechucker
|
5
|
+
|
6
|
+
def test_diesheet_initialize
|
7
|
+
warrior_dice = Diesheet.new({'STR' => '4d6L',
|
8
|
+
'DEX' => '4d6L',
|
9
|
+
'CON' => '4d6L',
|
10
|
+
'INT' => '4d6L',
|
11
|
+
'WIS' => '4d6L',
|
12
|
+
'CHA' => '4d6L',
|
13
|
+
'HP' => '1d10+3'})
|
14
|
+
assert_equal warrior_dice.diesets['STR'].class, DiceDropLow
|
15
|
+
assert_equal warrior_dice.diesets['HP'].class, Dice
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_diesheet_add
|
19
|
+
warrior_dice = Diesheet.new
|
20
|
+
['STR', 'DEX', 'CON', 'INT', 'WIS', 'CHA'].each do |stat|
|
21
|
+
warrior_dice.add(stat, '4d6L')
|
22
|
+
end
|
23
|
+
warrior_dice.add('HP', '1d10+3')
|
24
|
+
assert_equal warrior_dice.diesets['STR'].class, DiceDropLow
|
25
|
+
assert_equal warrior_dice.diesets['HP'].class, Dice
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_diesheet_remove
|
29
|
+
dummy_dice = Diesheet.new('First' => '2d6', 'Second' => '2d6')
|
30
|
+
dummy_dice.remove('Second')
|
31
|
+
assert_equal dummy_dice['Second'], nil
|
32
|
+
assert_equal dummy_dice['First'].class, Dice
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def test_diesheet_accessibility
|
37
|
+
warrior_dice = Diesheet.new
|
38
|
+
['STR', 'DEX', 'CON', 'INT', 'WIS', 'CHA'].each do |stat|
|
39
|
+
warrior_dice.add(stat, '4d6L')
|
40
|
+
end
|
41
|
+
warrior_dice.add('HP', '1d10+3')
|
42
|
+
assert_equal warrior_dice['STR'].class, DiceDropLow
|
43
|
+
assert_equal warrior_dice['HP'].class, Dice
|
44
|
+
assert_equal warrior_dice['STR'].total.class, Fixnum
|
45
|
+
assert_equal warrior_dice['STR'].results.class, Array
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_diesheet_roll
|
49
|
+
dummydice = Diesheet.new('First' => '1d6', 'Second' => '1d6')
|
50
|
+
dummydice.roll
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_diesheet_to_s
|
54
|
+
dummydice = Diesheet.new('First' => '1d6', 'Second' => '2d6')
|
55
|
+
output = dummydice.to_s
|
56
|
+
assert_equal output.class, String
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 8
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.8.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mark Tabler
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-20 00:00:00 -07:00
|
18
18
|
default_executable: roll
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -48,10 +48,10 @@ files:
|
|
48
48
|
- bin/roll
|
49
49
|
- lib/dicechucker.rb
|
50
50
|
- lib/dicechucker/dice.rb
|
51
|
-
- lib/dicechucker/
|
51
|
+
- lib/dicechucker/diesheet.rb
|
52
52
|
- test/helper.rb
|
53
53
|
- test/test_dice.rb
|
54
|
-
- test/
|
54
|
+
- test/test_diesheet.rb
|
55
55
|
has_rdoc: true
|
56
56
|
homepage: http://github.com/marktabler/dicechucker
|
57
57
|
licenses: []
|
@@ -86,5 +86,5 @@ specification_version: 3
|
|
86
86
|
summary: dice notation (XdY+Z) library
|
87
87
|
test_files:
|
88
88
|
- test/helper.rb
|
89
|
-
- test/
|
89
|
+
- test/test_diesheet.rb
|
90
90
|
- test/test_dice.rb
|
@@ -1,29 +0,0 @@
|
|
1
|
-
module Dicechucker
|
2
|
-
module GameLogic
|
3
|
-
|
4
|
-
def check_dc(dc)
|
5
|
-
self.roll >= dc
|
6
|
-
end
|
7
|
-
|
8
|
-
def explode(individual_rolls = false)
|
9
|
-
dice = roll_dice
|
10
|
-
dice.each do |roll|
|
11
|
-
if roll == @size
|
12
|
-
dice << (rand(@size)+1)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
report(dice, individual_rolls)
|
16
|
-
end
|
17
|
-
|
18
|
-
def drop_high(number_to_drop = 1, individual_rolls = false)
|
19
|
-
dice = roll_dice.sort.reverse.drop(number_to_drop)
|
20
|
-
report(dice, individual_rolls)
|
21
|
-
end
|
22
|
-
|
23
|
-
def drop_low(number_to_drop = 1, individual_rolls = false)
|
24
|
-
dice = roll_dice.sort.drop(number_to_drop)
|
25
|
-
report(dice, individual_rolls)
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
data/test/test_game_logic.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestLogic < MiniTest::Unit::TestCase
|
4
|
-
include Dicechucker
|
5
|
-
|
6
|
-
def setup
|
7
|
-
Dice.any_instance.stubs(:rand => 0.5)
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_dice_drop_low
|
11
|
-
testroll = Dice.new(100, 6, 0)
|
12
|
-
result = testroll.drop_low(10, true)
|
13
|
-
assert_equal result.size, 91 #90 dice plus 1 modifier of 0
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_dice_drop_high
|
17
|
-
testroll = Dice.new(100, 6, 0)
|
18
|
-
result = testroll.drop_high(10, true)
|
19
|
-
assert_equal result.size, 91 #90 dice plus 1 modifier of 0
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_explode
|
23
|
-
testroll = Dice.new(100, 6, 0)
|
24
|
-
result = testroll.explode(true)
|
25
|
-
assert_equal result.size, 101 #all random rolls are 4, nothing explodes
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_check_dc
|
29
|
-
testroll = Dice.new(1, 20, 2)
|
30
|
-
assert testroll.check_dc(14) == false
|
31
|
-
assert testroll.check_dc(13) == true
|
32
|
-
end
|
33
|
-
end
|