rpg_tools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0316fd1f6aea96942849150e125d95ea05a96411
4
+ data.tar.gz: 47f8012ecda7a42111f22a6bac44d65b5bb9016c
5
+ SHA512:
6
+ metadata.gz: 556a6f049b6cbc5139c7ce4e56afd80efe981041534bfca5fb6a0fbfcdec5fb14efed10a477d3900c8b322f2121c2c2042cfa35e9817ff413fe12a48581ae0dc
7
+ data.tar.gz: 47dcde8a0c5227093b35e8c421e3a2958eff4beee3c94e21a94be3dd8ff1500a808e2c313dfcec4834d85cce1b8b6a8fe6367a6e56f2047eb70a46093ab67d14
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Yohan Piron
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,58 @@
1
+ rpg_tools [![Dependency Status](https://gemnasium.com/Yinfei/rpg_tools.svg)](https://gemnasium.com/Yinfei/rpg_tools) ![](https://circleci.com/gh/Yinfei/rpg_tools.svg?&style=shield&circle-token=f5153100f0a56438602b915cf95d80f1e6e0edca)
2
+ =======
3
+
4
+ A gem that gives you tools for your RPGs : dices, coins and playing cards !
5
+
6
+ ## Usage
7
+
8
+ ### Coins
9
+
10
+ `RpgTools::Coin.new`
11
+
12
+ * The `flip` method set its value to a `heads` or `tails` string.
13
+
14
+ ### Dices
15
+
16
+ `RpgTools.roll_dice(arg)` <i>(`arg` is case insensitive)</i>.
17
+
18
+ This returns a plain integer result based on the `arg` parameter.
19
+
20
+ * It can be a stardard dice like `"1dX"` for a X sided dice.
21
+
22
+ * It can be a fudge dice `"df"` : a three sided dice (-1, 0, +1).
23
+
24
+ * It can also be a percentile dice `"d%"` : a ten sided dice (from 10 to 100).
25
+
26
+ You can also add multiple chained modifiers like "+X", "-X", "*X" or "/X", to alter the roll result. `RpgTools.roll_dice("4d6+2")` will create 4 6-sided dices, roll them and add 2 to the sum of the roll result.
27
+
28
+ You can also manipulate all those dice types as objects :
29
+
30
+ * `RpgTools::Dice::Numerical`
31
+ * `RpgTools::Dice::Fudge`
32
+ * `RpgTools::Dice::Percentile`
33
+
34
+ All those classes take two args: a mandatory side number and an optional modifier.
35
+ They respond to the `.roll` or `.roll!` methods to update their `value` to the result of the roll.
36
+
37
+ `RpgTools::Dice::Numerical.new(6, '+4').roll` will roll a six sided dice and add 4 to the roll result.
38
+
39
+ ### Dice Bags
40
+
41
+ `RpgTools::Dice::Bag.new(arg)` <i>(`arg` is case insensitive)</i>.
42
+
43
+ * It works the same way `RpgTools.roll_dice` does but will give you a `RpgTools::Dice::Bag` object instead of a plain integer. `RpgTools::Dice::Bag.new("4d6-2")` will create a bag of four 6 sided dices with a -2 modifier to the sum of all rolls.
44
+
45
+ ### Playing card deck
46
+ `RpgTools::PlayingCardDeck.new(arg)` <i>(`arg` can only be 32 or 52)</i>.
47
+
48
+ * The `card` method returns a card of a 32 or 52 cards deck + 2 jokers, depending
49
+ of `arg` value.
50
+ * The `hand` method return an array of 5 `card` calls.
51
+
52
+ ## Contributing
53
+
54
+ 1. Fork it
55
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
56
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
57
+ 4. Push to the branch (`git push origin my-new-feature`)
58
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new('spec')
@@ -0,0 +1,32 @@
1
+ module RpgTools
2
+ class Coin
3
+ attr_accessor :value, :flips, :heads, :tails
4
+
5
+ def initialize
6
+ @value, @flips, @heads, @tails = nil, 0, 0, 0
7
+ end
8
+
9
+ def flip
10
+ @flips += 1
11
+ @value = rand(2) == 1 ? 'Heads' : 'Tails'
12
+ save_result
13
+ @value
14
+ end
15
+ alias_method :flip!, :flip
16
+
17
+ private
18
+
19
+ def save_result
20
+ @heads += 1 if heads?
21
+ @tails += 1 if tails?
22
+ end
23
+
24
+ def heads?
25
+ @value == 'Heads'
26
+ end
27
+
28
+ def tails?
29
+ @value == 'Tails'
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,65 @@
1
+ module RpgTools
2
+ module Dice
3
+ class Bag
4
+ NOTATIONS ||= {
5
+ 'D' => Numerical,
6
+ 'D%' => Percentile,
7
+ 'DF' => Fudge
8
+ }.freeze
9
+
10
+ attr_accessor :dice_hash, :content, :modifiers, :value
11
+
12
+ def initialize(base)
13
+ @dice_hash = Utils::Parser.new(base).handle
14
+ @content = []
15
+ @modifiers = dice_hash[:modifiers]
16
+ @value = 0
17
+ end
18
+
19
+ def roll
20
+ invalid_dice! if dice_klass.nil?
21
+
22
+ fill_bag!
23
+
24
+ roll_bag_content!
25
+
26
+ return @total if modifiers.empty?
27
+
28
+ @total = Utils::ModifierCalculator.new(@total, modifiers).recalculate
29
+ end
30
+ alias roll! roll
31
+
32
+ private
33
+
34
+ def fill_bag!
35
+ quantity.times { @content << dice_klass.new(sides) }
36
+ end
37
+
38
+ def roll_bag_content!
39
+ @content.map(&:roll)
40
+
41
+ @total = @content.map(&:value).inject(0, :+)
42
+ end
43
+
44
+ def dice_klass
45
+ NOTATIONS[type]
46
+ end
47
+
48
+ def type
49
+ dice_hash[:type]
50
+ end
51
+
52
+ def sides
53
+ dice_hash[:sides]
54
+ end
55
+
56
+ def quantity
57
+ dice_hash[:quantity]
58
+ end
59
+
60
+ def invalid_dice!
61
+ raise ArgumentError, 'Unsupported dice type.'
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,52 @@
1
+ module RpgTools
2
+ module Dice
3
+ class Base
4
+ attr_accessor :sides, :modifiers, :value, :rolls
5
+
6
+ def initialize(sides = 0, modifiers = '')
7
+ @sides = sides.zero? ? sides_count : sides
8
+ @modifiers = modifiers
9
+ @value = 0
10
+ @rolls = 0
11
+
12
+ check_sides
13
+ end
14
+
15
+ def roll
16
+ @rolls += 1
17
+
18
+ @value = perform_roll
19
+ end
20
+
21
+ private
22
+
23
+ def perform_roll
24
+ return roll_calculation if @modifiers.empty?
25
+
26
+ roll_with_modifiers
27
+ end
28
+
29
+ def roll_with_modifiers
30
+ Utils::ModifierCalculator.new(roll_calculation, @modifiers).recalculate
31
+ end
32
+
33
+ def roll_calculation
34
+ raise NotImplementedError
35
+ end
36
+
37
+ def sides_count
38
+ 0
39
+ end
40
+
41
+ def check_sides
42
+ if not_enough_sides
43
+ raise ArgumentError, 'Your dice must have at least three sides.'
44
+ end
45
+ end
46
+
47
+ def not_enough_sides
48
+ @sides < 3
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,15 @@
1
+ module RpgTools
2
+ module Dice
3
+ class Fudge < Base
4
+ def roll_calculation
5
+ rand(-1..1)
6
+ end
7
+
8
+ private
9
+
10
+ def sides_count
11
+ 3
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module RpgTools
2
+ module Dice
3
+ class Numerical < Base
4
+ def roll_calculation
5
+ rand(1..sides)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module RpgTools
2
+ module Dice
3
+ class Percentile < Base
4
+ def roll_calculation
5
+ (rand(1..10) * 10)
6
+ end
7
+
8
+ private
9
+
10
+ def sides_count
11
+ 10
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,53 @@
1
+ module RpgTools
2
+ module Dice
3
+ module Utils
4
+ class ModifierCalculator
5
+ attr_accessor :total, :modifiers
6
+
7
+ def initialize(total, modifiers)
8
+ @total = total
9
+ @modifiers = modifiers
10
+
11
+ unprocessable_modifiers if malformed_modifiers?
12
+ end
13
+
14
+ def recalculate
15
+ modifier_operations.each do |operator, value|
16
+ @total = @total.send(operator, value.to_i)
17
+ end
18
+
19
+ @total
20
+ end
21
+
22
+ private
23
+
24
+ def modifier_operations
25
+ @modifiers.scan(/(\D)(\d+)/)
26
+ end
27
+
28
+ def unprocessable_modifiers
29
+ raise ArgumentError,
30
+ 'Modifiers require both an operator and a numerical value.'
31
+ end
32
+
33
+ def malformed_modifiers?
34
+ no_operator_at_modifier_beginning? ||
35
+ no_number_at_modifier_end? ||
36
+ multiple_successive_operators?
37
+ end
38
+
39
+ def no_operator_at_modifier_beginning?
40
+ @modifiers.match(/^\D/).nil?
41
+ end
42
+
43
+ def no_number_at_modifier_end?
44
+ @modifiers.match(/\d+$/).nil?
45
+ end
46
+
47
+ def multiple_successive_operators?
48
+ !@modifiers.match(/\d?([^0-9]{2,})\d?$/).nil?
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,46 @@
1
+ module RpgTools
2
+ module Dice
3
+ module Utils
4
+ class Parser
5
+ attr_reader :dice
6
+
7
+ def initialize(dice)
8
+ @dice = dice.upcase.match(/^(\d+)([A-Z%]+)(\d*)(.*)$/)
9
+
10
+ quantity_error! if @dice.nil?
11
+ end
12
+
13
+ def handle
14
+ {
15
+ quantity: quantity,
16
+ type: type,
17
+ sides: sides,
18
+ modifiers: modifiers
19
+ }
20
+ end
21
+
22
+ private
23
+
24
+ def quantity
25
+ @dice[1].to_i
26
+ end
27
+
28
+ def type
29
+ @dice[2]
30
+ end
31
+
32
+ def sides
33
+ @dice[3].to_i
34
+ end
35
+
36
+ def modifiers
37
+ @dice[4]
38
+ end
39
+
40
+ def quantity_error!
41
+ raise ArgumentError, 'You must specify a dice quantity.'
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ require 'rpg_tools/dice/utils/modifier_calculator'
2
+ require 'rpg_tools/dice/utils/parser'
3
+
4
+ require 'rpg_tools/dice/base'
5
+ require 'rpg_tools/dice/fudge'
6
+ require 'rpg_tools/dice/numerical'
7
+ require 'rpg_tools/dice/percentile'
8
+ require 'rpg_tools/dice/bag'
@@ -0,0 +1,64 @@
1
+ module RpgTools
2
+ class PlayingCardDeck
3
+ attr_accessor :type, :card_picks, :value
4
+
5
+ def initialize(type)
6
+ @type = type
7
+ type_check
8
+ @card_picks = 0
9
+ @value = nil
10
+ end
11
+
12
+ def card
13
+ @card_picks += 1
14
+
15
+ @value =
16
+ if @type == 52
17
+ joker_picked? ? 'Joker' : standard_card
18
+ else
19
+ standard_card
20
+ end
21
+ end
22
+
23
+ def hand
24
+ [].tap do |hand|
25
+ until hand.count == 5
26
+ card = standard_card
27
+
28
+ unless hand.include?(card) || hand.count('Joker') == 2
29
+ hand << card
30
+ @card_picks += 1
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def type_check
39
+ unless [32, 52].include?(@type)
40
+ raise ArgumentError.new('A playing card deck contains 32 or 52 cards only.')
41
+ end
42
+ end
43
+
44
+ def joker_picked?
45
+ [0, 1].include?((0..54).to_a.sample(1).first)
46
+ end
47
+
48
+ def number
49
+ if @type == 32
50
+ [(7..10).to_a, 'Jack', 'Queen', 'King'].flatten.sample(1)
51
+ else
52
+ [(1..10).to_a, 'Jack', 'Queen', 'King'].flatten.sample(1)
53
+ end
54
+ end
55
+
56
+ def color
57
+ ['Clubs', 'Hearts', 'Diamonds', 'Spades'].sample(1)
58
+ end
59
+
60
+ def standard_card
61
+ @value = [number, color].join(' of ')
62
+ end
63
+ end
64
+ end
data/lib/rpg_tools.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rpg_tools/coin'
2
+ require 'rpg_tools/dice'
3
+ require 'rpg_tools/playing_card_deck'
4
+
5
+ module RpgTools
6
+ def roll_dice(dice)
7
+ Dice::Bag.new(dice).roll
8
+ end
9
+ module_function :roll_dice
10
+ end
data/rpg_tools.gemspec ADDED
@@ -0,0 +1,16 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{rpg_tools}
3
+ s.version = '1.0.0'
4
+ s.author = 'Yohan Piron'
5
+ s.email = 'yinfei84@gmail.com'
6
+ s.date = '2015-08-03'
7
+ s.summary = 'rpg_tools is a toolbox for tabletop games and RPGs'
8
+ s.description = 'rpg_tools gives you tools for your RPGs : dices, coins, cards...'
9
+ s.homepage = 'https://github.com/Yinfei/rpg_tools.git'
10
+ s.license = 'MIT'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.test_files = s.files.grep(%r{^(spec)/})
13
+ s.require_paths = ['lib']
14
+ s.add_development_dependency 'rake', '~> 10.4'
15
+ s.add_development_dependency 'rspec', '~> 3.0'
16
+ end
data/spec/coin_spec.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Coin do
5
+ it "can't return anything else than 'Heads' or 'Tails'" do
6
+ expect(['Heads', 'Tails'].include?(described_class.new.flip)).to eq(true)
7
+ end
8
+ end
@@ -0,0 +1,59 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Bag do
5
+ describe '#roll' do
6
+ it "doesn't roll a dice without quantity" do
7
+ expect { described_class.new('d10').roll }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ it "doesn't roll a 'd0' dice" do
11
+ expect { described_class.new('1d0').roll }.to raise_error(ArgumentError)
12
+ end
13
+
14
+ it "doesn't roll a 'd1' dice" do
15
+ expect { described_class.new('1d1').roll }.to raise_error(ArgumentError)
16
+ end
17
+
18
+ it "doesn't roll a 'd2' dice" do
19
+ expect { described_class.new('1d2').roll }.to raise_error(ArgumentError)
20
+ end
21
+
22
+ it 'rolls fudge dices' do
23
+ expect { described_class.new('1df').roll }.not_to raise_error
24
+ end
25
+
26
+ it "rolls a dice may the 'd' char be capitalized or not" do
27
+ expect { described_class.new('1d6').roll }.not_to raise_error
28
+ expect { described_class.new('1D6').roll }.not_to raise_error
29
+ end
30
+
31
+ it "rolls a dice may the 'f' char be capitalized or not" do
32
+ expect { described_class.new('1dF').roll }.not_to raise_error
33
+ expect { described_class.new('1Df').roll }.not_to raise_error
34
+ end
35
+
36
+ it 'rolls a dice with a bonus' do
37
+ expect { described_class.new('1d6+2').roll }.not_to raise_error
38
+ end
39
+
40
+ it 'rolls a dice with a malus' do
41
+ expect { described_class.new('1D6-2').roll }.not_to raise_error
42
+ end
43
+
44
+ it 'rolls a dice with a multiple modifiers' do
45
+ expect { described_class.new('1D6-2+4/8').roll }.not_to raise_error
46
+ end
47
+
48
+ it 'does not roll a dice with bad modifiers' do
49
+ expect { described_class.new('1D6-+2').roll }.to raise_error(ArgumentError)
50
+ expect { described_class.new('1D6-+2+').roll }.to raise_error(ArgumentError)
51
+ end
52
+
53
+ it "doesn't roll very odd dices" do
54
+ expect { described_class.new('1dDOGE').roll }.to raise_error(ArgumentError)
55
+ expect { described_class.new('1dfoo').roll }.to raise_error(ArgumentError)
56
+ expect { described_class.new('1foobarbaz').roll }.to raise_error(ArgumentError)
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,96 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Base do
5
+ let(:dice) { described_class.new(10) }
6
+ let(:dice_with_modifier) { described_class.new(10, '+2') }
7
+
8
+ describe '#initialize' do
9
+ it 'creates a basic dice' do
10
+ expect { described_class.new(10) }.not_to raise_error
11
+ end
12
+
13
+ it 'creates a basic dice with a modifier' do
14
+ expect { described_class.new(10, '+2') }.not_to raise_error
15
+ end
16
+
17
+ it 'falls back on sides_count method if no sides arg is provided' do
18
+ allow_any_instance_of(described_class).to receive(:sides_count).and_return(7)
19
+
20
+ new_dice = described_class.new
21
+
22
+ expect(new_dice.sides).to eq(7)
23
+ end
24
+ end
25
+
26
+ describe '#roll' do
27
+ before do
28
+ allow(dice).to receive(:roll_calculation).and_return(10)
29
+ allow(dice_with_modifier).to receive(:roll_calculation).and_return(10)
30
+ end
31
+
32
+ context 'no modifier' do
33
+ it 'returns an integer based on a basic roll calculation' do
34
+ expect(dice.roll).to eq(10)
35
+ end
36
+
37
+ it 'does not call the #roll_with_modifiers method' do
38
+ expect(dice).not_to receive(:roll_with_modifiers)
39
+
40
+ dice.roll
41
+ end
42
+ end
43
+
44
+ context 'modifier present' do
45
+ it 'returns an integer based on a roll calulation plus modifier applied' do
46
+ expect(dice_with_modifier.roll).to eq(12)
47
+ end
48
+
49
+ it 'calls the #roll_with_modifiers method' do
50
+ expect(dice_with_modifier).to receive(:roll_with_modifiers)
51
+
52
+ dice_with_modifier.roll
53
+ end
54
+ end
55
+
56
+ it 'updates a dice value attribute' do
57
+ dice.roll
58
+
59
+ expect(dice.value).to eq(10)
60
+ end
61
+
62
+ it 'increments to dice roll count' do
63
+ dice.roll
64
+
65
+ expect(dice.rolls).to eq(1)
66
+
67
+ dice.roll
68
+
69
+ expect(dice.rolls).to eq(2)
70
+ end
71
+ end
72
+
73
+ describe '#sides_count' do
74
+ it 'returns zero' do
75
+ expect(dice.send(:sides_count)).to eq(0)
76
+ end
77
+ end
78
+
79
+ describe '#roll_calculation' do
80
+ it 'raises a NotImplementedError' do
81
+ expect { dice.send(:roll_calculation) }.to raise_error(NotImplementedError)
82
+ end
83
+ end
84
+
85
+ describe 'not_enough_sides' do
86
+ it 'returns true if dice sides is less than three' do
87
+ dice.sides = 2
88
+
89
+ expect(dice.send(:not_enough_sides)).to be(true)
90
+ end
91
+
92
+ it 'returns false otherwise' do
93
+ expect(dice.send(:not_enough_sides)).to be(false)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,22 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Fudge do
5
+ let(:dice) { described_class.new }
6
+
7
+ describe '#roll_calculation' do
8
+ it 'rolls a value between -1 and 1' do
9
+ 10.times do
10
+ dice.roll
11
+
12
+ expect(dice.value.between?(-1, 1)).to be(true)
13
+ end
14
+ end
15
+ end
16
+
17
+ describe '#sides_count' do
18
+ it 'returns 3' do
19
+ expect(dice.send(:sides_count)).to eq(3)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Numerical do
5
+ let(:dice) { described_class.new(10) }
6
+
7
+ describe '#roll_calculation' do
8
+ it 'rolls a value between 1 and the sides value' do
9
+ 10.times do
10
+ dice.roll
11
+
12
+ expect(dice.value.between?(1, dice.sides)).to be(true)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Percentile do
5
+ let(:dice) { described_class.new }
6
+
7
+ describe '#roll_calculation' do
8
+ it 'rolls a value between 10 and 100' do
9
+ 10.times do
10
+ dice.roll
11
+
12
+ expect(dice.value.between?(10, 100)).to be(true)
13
+ end
14
+ end
15
+
16
+ it 'rolls only round values' do
17
+ 10.times do
18
+ dice.roll
19
+
20
+ expect(dice.value[-1]).to eq(0)
21
+ end
22
+ end
23
+ end
24
+
25
+ describe '#sides_count' do
26
+ it 'returns 10' do
27
+ expect(dice.send(:sides_count)).to eq(10)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,96 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Utils::ModifierCalculator do
5
+ let(:dice) { described_class.new(10, '+1') }
6
+
7
+ describe '#initialize' do
8
+ it 'raises an error for malformed modifiers' do
9
+ expect { described_class.new(10, '+3+') }.to raise_error(ArgumentError)
10
+ end
11
+
12
+ it 'does not otherwise' do
13
+ expect { described_class.new(10, '+5-3/10') }.not_to raise_error
14
+ end
15
+ end
16
+
17
+ describe '#recalculate' do
18
+ it 'applies a simple modifier to the total attribute' do
19
+ dice = described_class.new(10, '+5')
20
+
21
+ dice.recalculate
22
+
23
+ expect(dice.total).to eq(15)
24
+ end
25
+
26
+ it 'applies multiple modifiers to the total attribute' do
27
+ dice = described_class.new(10, '+5-1/2')
28
+
29
+ dice.recalculate
30
+
31
+ expect(dice.total).to eq(7)
32
+ end
33
+ end
34
+
35
+ describe '#malformed_modifiers?' do
36
+ it 'returns true if there is not operator at modifiers beginning' do
37
+ dice.modifiers = '4'
38
+
39
+ expect(dice.send(:malformed_modifiers?)).to be(true)
40
+ end
41
+
42
+ it 'returns true if there is no number at modifiers end' do
43
+ dice.modifiers = '+3-'
44
+
45
+ expect(dice.send(:malformed_modifiers?)).to be(true)
46
+ end
47
+
48
+ it 'returns true if multiple succesive operators are present in the modifiers' do
49
+ dice.modifiers = '+-3'
50
+
51
+ expect(dice.send(:malformed_modifiers?)).to be(true)
52
+ end
53
+
54
+ it 'returns false otherwise' do
55
+ dice.modifiers = '+4-5/8'
56
+
57
+ expect(dice.send(:malformed_modifiers?)).to be(false)
58
+ end
59
+ end
60
+
61
+ describe '#no_operator_at_modifier_beginning?' do
62
+ it 'returns true if there is not operator at modifiers beginning' do
63
+ dice.modifiers = '4'
64
+
65
+ expect(dice.send(:no_operator_at_modifier_beginning?)).to be(true)
66
+ end
67
+
68
+ it 'returs false otherwise' do
69
+ expect(dice.send(:no_operator_at_modifier_beginning?)).to be(false)
70
+ end
71
+ end
72
+
73
+ describe '#no_number_at_modifier_end?' do
74
+ it 'returns true if there is no number at modifiers end' do
75
+ dice.modifiers = '+3-'
76
+
77
+ expect(dice.send(:no_number_at_modifier_end?)).to be(true)
78
+ end
79
+
80
+ it 'returs false otherwise' do
81
+ expect(dice.send(:no_number_at_modifier_end?)).to be(false)
82
+ end
83
+ end
84
+
85
+ describe '#multiple_successive_operators?' do
86
+ it 'returns true if multiple succesive operators are present in the modifiers' do
87
+ dice.modifiers = '+-3'
88
+
89
+ expect(dice.send(:multiple_successive_operators?)).to be(true)
90
+ end
91
+
92
+ it 'returs false otherwise' do
93
+ expect(dice.send(:multiple_successive_operators?)).to be(false)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,28 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::Dice::Utils::Parser do
5
+ describe '#initialize' do
6
+ it 'raises an error when no matching pattern is found' do
7
+ expect { described_class.new('DOGE') }.to raise_error(ArgumentError)
8
+ end
9
+
10
+ it 'does not otherwise' do
11
+ expect { described_class.new('1DF') }.not_to raise_error
12
+ expect { described_class.new('1D10') }.not_to raise_error
13
+ expect { described_class.new('1D10+12') }.not_to raise_error
14
+ expect { described_class.new('1D%') }.not_to raise_error
15
+ end
16
+ end
17
+
18
+ describe '#handle' do
19
+ it 'builds a hash based on a matching pattern' do
20
+ hash = described_class.new('3DF+4').handle
21
+
22
+ expect(hash[:quantity]).to eq(3)
23
+ expect(hash[:type]).to eq('DF')
24
+ expect(hash[:sides]).to eq(0)
25
+ expect(hash[:modifiers]).to eq('+4')
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'rpg_tools'
2
+ require 'spec_helper'
3
+
4
+ describe RpgTools::PlayingCardDeck do
5
+ it 'must return a card name' do
6
+ expect(described_class.new(32).card).not_to eq(true)
7
+ expect(described_class.new(32).card).not_to eq(false)
8
+ expect(described_class.new(32).card).not_to eq(nil)
9
+ expect(described_class.new(52).card).not_to eq(true)
10
+ expect(described_class.new(52).card).not_to eq(false)
11
+ expect(described_class.new(52).card).not_to eq(nil)
12
+ end
13
+
14
+ it 'must return 5 cards for a full hand' do
15
+ expect(described_class.new(32).hand.count).to eq(5)
16
+ expect(described_class.new(52).hand.count).to eq(5)
17
+ end
18
+
19
+ it "can't pick the same card twice" do
20
+ expect(described_class.new(32).hand.uniq.count).to eq(5)
21
+ expect(described_class.new(52).hand.uniq.count).to eq(5)
22
+ end
23
+
24
+ it "can't use anything else than a 32 or 52 cards deck" do
25
+ expect { described_class.new(42) }.to raise_error(ArgumentError)
26
+ expect { described_class.new(666) }.to raise_error(ArgumentError)
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ RSpec.configure do |config|
2
+ config.color = true
3
+ config.tty = true
4
+ config.formatter = :documentation
5
+
6
+ config.mock_with :rspec do |c|
7
+ c.syntax = [:should, :expect]
8
+ end
9
+
10
+ config.expect_with :rspec do |c|
11
+ c.syntax = [:should, :expect]
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rpg_tools
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Yohan Piron
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ description: 'rpg_tools gives you tools for your RPGs : dices, coins, cards...'
42
+ email: yinfei84@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - LICENSE
48
+ - README.md
49
+ - Rakefile
50
+ - lib/rpg_tools.rb
51
+ - lib/rpg_tools/coin.rb
52
+ - lib/rpg_tools/dice.rb
53
+ - lib/rpg_tools/dice/bag.rb
54
+ - lib/rpg_tools/dice/base.rb
55
+ - lib/rpg_tools/dice/fudge.rb
56
+ - lib/rpg_tools/dice/numerical.rb
57
+ - lib/rpg_tools/dice/percentile.rb
58
+ - lib/rpg_tools/dice/utils/modifier_calculator.rb
59
+ - lib/rpg_tools/dice/utils/parser.rb
60
+ - lib/rpg_tools/playing_card_deck.rb
61
+ - rpg_tools.gemspec
62
+ - spec/coin_spec.rb
63
+ - spec/dice/bag_spec.rb
64
+ - spec/dice/base_spec.rb
65
+ - spec/dice/fudge_spec.rb
66
+ - spec/dice/numerical_spec.rb
67
+ - spec/dice/percentile_spec.rb
68
+ - spec/dice/utils/modifier_calculator_spec.rb
69
+ - spec/dice/utils/parser_spec.rb
70
+ - spec/playing_card_deck_spec.rb
71
+ - spec/spec_helper.rb
72
+ homepage: https://github.com/Yinfei/rpg_tools.git
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubyforge_project:
92
+ rubygems_version: 2.6.8
93
+ signing_key:
94
+ specification_version: 4
95
+ summary: rpg_tools is a toolbox for tabletop games and RPGs
96
+ test_files:
97
+ - spec/coin_spec.rb
98
+ - spec/dice/bag_spec.rb
99
+ - spec/dice/base_spec.rb
100
+ - spec/dice/fudge_spec.rb
101
+ - spec/dice/numerical_spec.rb
102
+ - spec/dice/percentile_spec.rb
103
+ - spec/dice/utils/modifier_calculator_spec.rb
104
+ - spec/dice/utils/parser_spec.rb
105
+ - spec/playing_card_deck_spec.rb
106
+ - spec/spec_helper.rb