fifthed_sim 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -1
- data/HelpWanted.md +23 -0
- data/README.md +144 -5
- data/bin/console +2 -8
- data/bin/playground +42 -0
- data/exe/diceroll +9 -0
- data/fifthed_sim.gemspec +4 -0
- data/lib/fifthed_sim/actor.rb +80 -0
- data/lib/fifthed_sim/attack.rb +86 -0
- data/lib/fifthed_sim/calculated_fixnum.rb +57 -0
- data/lib/fifthed_sim/compiler/parser.rb +46 -0
- data/lib/fifthed_sim/compiler/transform.rb +28 -0
- data/lib/fifthed_sim/compiler.rb +51 -0
- data/lib/fifthed_sim/damage.rb +54 -0
- data/lib/fifthed_sim/damage_types.rb +39 -0
- data/lib/fifthed_sim/dice_expression.rb +134 -0
- data/lib/fifthed_sim/distribution.rb +219 -20
- data/lib/fifthed_sim/nodes/addition_node.rb +75 -0
- data/lib/fifthed_sim/nodes/block_node.rb +46 -0
- data/lib/fifthed_sim/nodes/division_node.rb +26 -0
- data/lib/fifthed_sim/nodes/greater_node.rb +41 -0
- data/lib/fifthed_sim/nodes/less_node.rb +46 -0
- data/lib/fifthed_sim/nodes/multi_node.rb +135 -0
- data/lib/fifthed_sim/nodes/multiplication_node.rb +25 -0
- data/lib/fifthed_sim/nodes/number_node.rb +38 -0
- data/lib/fifthed_sim/nodes/roll_node.rb +88 -0
- data/lib/fifthed_sim/nodes/subtraction_node.rb +24 -0
- data/lib/fifthed_sim/roll_repl.rb +117 -0
- data/lib/fifthed_sim/spell.rb +74 -0
- data/lib/fifthed_sim/stat.rb +49 -0
- data/lib/fifthed_sim/stat_block.rb +57 -0
- data/lib/fifthed_sim/version.rb +3 -1
- data/lib/fifthed_sim.rb +28 -4
- metadata +74 -8
- data/lib/fifthed_sim/dice_calculation.rb +0 -88
- data/lib/fifthed_sim/dice_result.rb +0 -108
- data/lib/fifthed_sim/die_roll.rb +0 -66
- data/lib/fifthed_sim/helpers/average_comparison.rb +0 -14
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fifthed_sim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Super
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: parslet
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.7.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.7.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rainbow
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.0
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: bundler
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,12 +80,27 @@ dependencies:
|
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
82
|
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 0.10.4
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 0.10.4
|
55
97
|
description: This is a simulator to run a D&D encounter. It provides DSL-like tools
|
56
98
|
to describe actions and abilities, and then it will (eventually) play with some
|
57
99
|
degree of AI skill.
|
58
100
|
email:
|
59
101
|
- anthony@noided.media
|
60
|
-
executables:
|
102
|
+
executables:
|
103
|
+
- diceroll
|
61
104
|
extensions: []
|
62
105
|
extra_rdoc_files: []
|
63
106
|
files:
|
@@ -65,18 +108,40 @@ files:
|
|
65
108
|
- ".rspec"
|
66
109
|
- ".travis.yml"
|
67
110
|
- Gemfile
|
111
|
+
- HelpWanted.md
|
68
112
|
- LICENSE.txt
|
69
113
|
- README.md
|
70
114
|
- Rakefile
|
71
115
|
- bin/console
|
116
|
+
- bin/playground
|
72
117
|
- bin/setup
|
118
|
+
- exe/diceroll
|
73
119
|
- fifthed_sim.gemspec
|
74
120
|
- lib/fifthed_sim.rb
|
75
|
-
- lib/fifthed_sim/
|
76
|
-
- lib/fifthed_sim/
|
77
|
-
- lib/fifthed_sim/
|
121
|
+
- lib/fifthed_sim/actor.rb
|
122
|
+
- lib/fifthed_sim/attack.rb
|
123
|
+
- lib/fifthed_sim/calculated_fixnum.rb
|
124
|
+
- lib/fifthed_sim/compiler.rb
|
125
|
+
- lib/fifthed_sim/compiler/parser.rb
|
126
|
+
- lib/fifthed_sim/compiler/transform.rb
|
127
|
+
- lib/fifthed_sim/damage.rb
|
128
|
+
- lib/fifthed_sim/damage_types.rb
|
129
|
+
- lib/fifthed_sim/dice_expression.rb
|
78
130
|
- lib/fifthed_sim/distribution.rb
|
79
|
-
- lib/fifthed_sim/
|
131
|
+
- lib/fifthed_sim/nodes/addition_node.rb
|
132
|
+
- lib/fifthed_sim/nodes/block_node.rb
|
133
|
+
- lib/fifthed_sim/nodes/division_node.rb
|
134
|
+
- lib/fifthed_sim/nodes/greater_node.rb
|
135
|
+
- lib/fifthed_sim/nodes/less_node.rb
|
136
|
+
- lib/fifthed_sim/nodes/multi_node.rb
|
137
|
+
- lib/fifthed_sim/nodes/multiplication_node.rb
|
138
|
+
- lib/fifthed_sim/nodes/number_node.rb
|
139
|
+
- lib/fifthed_sim/nodes/roll_node.rb
|
140
|
+
- lib/fifthed_sim/nodes/subtraction_node.rb
|
141
|
+
- lib/fifthed_sim/roll_repl.rb
|
142
|
+
- lib/fifthed_sim/spell.rb
|
143
|
+
- lib/fifthed_sim/stat.rb
|
144
|
+
- lib/fifthed_sim/stat_block.rb
|
80
145
|
- lib/fifthed_sim/version.rb
|
81
146
|
homepage: https://github.com/AnthonySuper/FifthedSim
|
82
147
|
licenses:
|
@@ -98,8 +163,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
98
163
|
version: '0'
|
99
164
|
requirements: []
|
100
165
|
rubyforge_project:
|
101
|
-
rubygems_version: 2.
|
166
|
+
rubygems_version: 2.4.8
|
102
167
|
signing_key:
|
103
168
|
specification_version: 4
|
104
169
|
summary: A 5th edition D&D encounter simulator
|
105
170
|
test_files: []
|
171
|
+
has_rdoc:
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require_relative './helpers/average_comparison'
|
2
|
-
|
3
|
-
module CalculatedFixnum
|
4
|
-
refine Fixnum do
|
5
|
-
include FifthedSim::AverageComparison
|
6
|
-
|
7
|
-
def value
|
8
|
-
self
|
9
|
-
end
|
10
|
-
|
11
|
-
def average
|
12
|
-
self
|
13
|
-
end
|
14
|
-
|
15
|
-
def has_critfail?
|
16
|
-
false
|
17
|
-
end
|
18
|
-
|
19
|
-
def has_crit?
|
20
|
-
false
|
21
|
-
end
|
22
|
-
|
23
|
-
def distance_from_average
|
24
|
-
0
|
25
|
-
end
|
26
|
-
|
27
|
-
def distribution
|
28
|
-
FifthedSim::Distribution.for_number(self)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
module FifthedSim
|
37
|
-
class DiceCalculation
|
38
|
-
include AverageComparison
|
39
|
-
using CalculatedFixnum
|
40
|
-
|
41
|
-
def initialize(*values)
|
42
|
-
values.each{|v| check_type(v) }
|
43
|
-
@components = values
|
44
|
-
end
|
45
|
-
|
46
|
-
def +(other)
|
47
|
-
check_type(other)
|
48
|
-
@components << other
|
49
|
-
self
|
50
|
-
end
|
51
|
-
|
52
|
-
def value
|
53
|
-
# Symbol::& uses send, so refinements would break
|
54
|
-
# How sad
|
55
|
-
@components.map{|x| x.value}.inject(:+)
|
56
|
-
end
|
57
|
-
|
58
|
-
def average
|
59
|
-
@components.map{|x| x.average}.inject(:+)
|
60
|
-
end
|
61
|
-
|
62
|
-
def has_critfail?
|
63
|
-
@components.any?{|x| x.has_critfail?}
|
64
|
-
end
|
65
|
-
|
66
|
-
def has_crit?
|
67
|
-
@components.any?{|x| x.has_crit?}
|
68
|
-
end
|
69
|
-
|
70
|
-
def distribution
|
71
|
-
# TODO: Maybe figure out how to minimize convolution expense?
|
72
|
-
@components.map{|x| x.distribution}.inject do |memo, p|
|
73
|
-
memo.convolve(p)
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
|
78
|
-
private
|
79
|
-
ALLOWED_TYPES = [DiceResult,
|
80
|
-
Fixnum]
|
81
|
-
|
82
|
-
def check_type(obj)
|
83
|
-
unless ALLOWED_TYPES.any?{|t| obj.is_a?(t) }
|
84
|
-
raise TypeError, "not a proper member type"
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
@@ -1,108 +0,0 @@
|
|
1
|
-
require_relative './helpers/average_comparison'
|
2
|
-
require_relative './distribution'
|
3
|
-
|
4
|
-
class Fixnum
|
5
|
-
def factorial
|
6
|
-
(1..self).inject(:*) || 1
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def combination(n, r)
|
11
|
-
n.factorial / (r.factorial * (n - r).factorial)
|
12
|
-
end
|
13
|
-
|
14
|
-
module FifthedSim
|
15
|
-
##
|
16
|
-
# This class models the result of a dice roll.
|
17
|
-
# It is filled with the actual result of randomly-rolled dice, but contains
|
18
|
-
# methods to enable the calculation of average values.
|
19
|
-
#
|
20
|
-
# When you add a modifier it becomes a DiceCalculation.
|
21
|
-
class DiceResult
|
22
|
-
def self.d(num, type)
|
23
|
-
self.new(num.times.map{DieRoll.roll(type)})
|
24
|
-
end
|
25
|
-
|
26
|
-
include AverageComparison
|
27
|
-
|
28
|
-
def initialize(array)
|
29
|
-
unless array.is_a?(Array) && ! array.empty?
|
30
|
-
raise ArgumentError, "Not a valid array"
|
31
|
-
end
|
32
|
-
unless array.all?{|elem| elem.is_a?(DieRoll) }
|
33
|
-
raise ArgumentError, "Not all die rolls"
|
34
|
-
end
|
35
|
-
@array = array
|
36
|
-
end
|
37
|
-
|
38
|
-
def has_crit?
|
39
|
-
@array.any?(&:crit?)
|
40
|
-
end
|
41
|
-
|
42
|
-
def average
|
43
|
-
@array.map(&:average).inject(:+)
|
44
|
-
end
|
45
|
-
|
46
|
-
def has_critfail?
|
47
|
-
@array.any?(&:critfail?)
|
48
|
-
end
|
49
|
-
|
50
|
-
def dice
|
51
|
-
@array.dup
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_i
|
55
|
-
@array.map(&:to_i).inject(:+)
|
56
|
-
end
|
57
|
-
|
58
|
-
def to_f
|
59
|
-
to_i.to_f
|
60
|
-
end
|
61
|
-
|
62
|
-
def value
|
63
|
-
to_i
|
64
|
-
end
|
65
|
-
|
66
|
-
def +(other)
|
67
|
-
a = DiceCalculation.new(self)
|
68
|
-
(a + other)
|
69
|
-
end
|
70
|
-
|
71
|
-
def roll_count
|
72
|
-
@array.count
|
73
|
-
end
|
74
|
-
|
75
|
-
def dice_type
|
76
|
-
@array.first.type
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
def min_value
|
81
|
-
roll_count
|
82
|
-
end
|
83
|
-
|
84
|
-
def max_value
|
85
|
-
dice_type * roll_count
|
86
|
-
end
|
87
|
-
|
88
|
-
def distribution
|
89
|
-
total_possible = (dice_type ** roll_count)
|
90
|
-
mapped = min_value.upto(max_value).map do |k|
|
91
|
-
[k, occurences(k)]
|
92
|
-
end
|
93
|
-
Distribution.new(Hash[mapped], total_possible)
|
94
|
-
end
|
95
|
-
|
96
|
-
private
|
97
|
-
|
98
|
-
def occurences(num)
|
99
|
-
dice_type = @array.first.type
|
100
|
-
num_dice = @array.size
|
101
|
-
0.upto((num - num_dice) / dice_type).map do |k|
|
102
|
-
((-1) ** k) *
|
103
|
-
combination(num_dice, k) *
|
104
|
-
combination(num - dice_type*k - 1, num_dice- 1)
|
105
|
-
end.inject(:+)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
data/lib/fifthed_sim/die_roll.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
require_relative './helpers/average_comparison'
|
2
|
-
|
3
|
-
module FifthedSim
|
4
|
-
class DieRoll
|
5
|
-
include AverageComparison
|
6
|
-
|
7
|
-
def self.roll(type)
|
8
|
-
raise ArgumentError, "Must be an Integer" unless type.is_a? Fixnum
|
9
|
-
self.new(SecureRandom.random_number(type - 1) + 1, type)
|
10
|
-
end
|
11
|
-
|
12
|
-
# Obtain a DieRoll filled with the average result of this die type
|
13
|
-
# This will round down.
|
14
|
-
def self.average(type)
|
15
|
-
self.new((type + 1) / 2, type)
|
16
|
-
end
|
17
|
-
|
18
|
-
# Obtain an average value for this die type, as a float
|
19
|
-
# We're extremely lazy here.
|
20
|
-
def self.average_value(type)
|
21
|
-
self.new(1, type).average
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize(val, type)
|
25
|
-
unless val.is_a?(Fixnum) && type.is_a?(Fixnum)
|
26
|
-
raise ArgumentError, "Type invald"
|
27
|
-
end
|
28
|
-
@value = val
|
29
|
-
@type = type
|
30
|
-
end
|
31
|
-
|
32
|
-
attr_reader :value, :type
|
33
|
-
|
34
|
-
def average
|
35
|
-
(@type + 1) / 2.0
|
36
|
-
end
|
37
|
-
|
38
|
-
def difference_from_average
|
39
|
-
@value - average
|
40
|
-
end
|
41
|
-
|
42
|
-
def critfail?
|
43
|
-
@value == 1
|
44
|
-
end
|
45
|
-
|
46
|
-
def crit?
|
47
|
-
@value == @type
|
48
|
-
end
|
49
|
-
|
50
|
-
def to_i
|
51
|
-
@value
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_f
|
55
|
-
@value.to_f
|
56
|
-
end
|
57
|
-
|
58
|
-
def method_missing(method, *args, **kwards, &block)
|
59
|
-
if @value.respond_to? method
|
60
|
-
@value.public_send(method,*args,**kwards,&block)
|
61
|
-
else
|
62
|
-
super
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
module FifthedSim
|
2
|
-
module AverageComparison
|
3
|
-
# metaprogramming lolz
|
4
|
-
{"above_" => :>, "below_" => :<, "" => :==}.each do |k,v|
|
5
|
-
define_method "#{k}average?" do
|
6
|
-
value.public_send(v, average)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def difference_from_average
|
11
|
-
value - average
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|