dicechucker 0.6.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|