diceguru 0.1.2

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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/dicebag.rb +194 -0
  3. metadata +44 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0bfa1a9bc2621613e65150ba835eb73fd688f347
4
+ data.tar.gz: 13f43f46fc9fa9d6242e2dd342cce5caaaa3e620
5
+ SHA512:
6
+ metadata.gz: a2760cdf0ec8860af51bde4caf8b28cb81080c24bac874162abbe3462cadb5bf472332309e79ffb48ac6a0d9a5ff0656a63f7cd58fa721c2881643650559f5a9
7
+ data.tar.gz: 36cf0336b2753f5b19c1da6abf9ce1178ba5c877ab48d9258196b5d2988fc76d083c0f338fb58718cdbfcc7f3aba9b482313a9a5388e78663a008baf707b5e6b
@@ -0,0 +1,194 @@
1
+ require 'singleton'
2
+ require 'json'
3
+
4
+ module Kernel
5
+ def d
6
+ DiceBag.instance
7
+ end
8
+ end
9
+
10
+ class DiceDSL
11
+
12
+ class << self
13
+
14
+ def parse(dices)
15
+ %r{^(?<top_or_bottom>t|b)?(?<tb_number>\d)?\[(?<dice>.*)\](?<explode>\*)?(?<plus>\+\d+)?\=?(?<target>.*)?$} =~ dices
16
+ die_set = eval "[" + string_to_dice_array(dice) + "]"
17
+ dice_pool({set: die_set, top: tb_number.to_i, plus: plus.to_i})
18
+ end
19
+
20
+ def dice_pool(*args)
21
+ DicePool.new(*args)
22
+ end
23
+
24
+ def string_to_dice_array(dice)
25
+ dice.gsub(/\s+/, '').
26
+ split("+").
27
+ map{|ds| ds.split('d') }.
28
+ collect {|how_many, dice_face| (["d^#{dice_face}"]*how_many.to_i ).join(",") }.
29
+ join(",")
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ class DiceBag
37
+
38
+ include Singleton
39
+
40
+ def ^(max)
41
+ @max = max
42
+ Die.new(sides: max)
43
+ end
44
+
45
+ def roll(what: self, plus: 0, keep: nil, how_many: nil)
46
+ raise "Must include :how_many if you pass an individual Die" unless how_many
47
+ keep = how_many if keep.nil?
48
+ DicePool.new set: how_many.times.collect{ what.clone.reroll }, top: keep, plus: plus
49
+ end
50
+
51
+ end
52
+
53
+ class Die
54
+
55
+ def initialize(sides: 6, plus: 0)
56
+ @plus = plus
57
+ @sides = sides
58
+ roll
59
+ end
60
+
61
+ def +(x)
62
+ @plus = x
63
+ reroll
64
+ end
65
+
66
+ def inspect; "d#{@sides}#{"+#{@plus}" unless @plus.zero?}=>#{value}"; end
67
+
68
+ def to_h
69
+ {sides: @sides, plus: @plus, value: value}
70
+ end
71
+
72
+ def value; @value; end
73
+
74
+ def roll; @value = rand(1..@sides)+@plus; self end
75
+
76
+ def reroll; roll; end
77
+
78
+ def to_s; value; end
79
+
80
+ def to_i; value; end
81
+
82
+ end
83
+
84
+ class DicePool
85
+
86
+ attr_reader :how_many, :top_number_of_dice, :results, :plus, :set
87
+ attr_writer :how_many, :top_number_of_dice, :results, :plus
88
+
89
+ def initialize(set: nil, plus: 0, top: 2)
90
+ @set = set.is_a?(Die) ? [set] : set
91
+ raise 'Dice passed to DicePool must be instances of Die.' unless @set.any?{|s| s.is_a?(Die) }
92
+ @plus = plus
93
+ @how_many = 100_000
94
+ @top_number_of_dice = top
95
+ end
96
+
97
+ def highest(top: top_number_of_dice, re_roll: false)
98
+ reroll if re_roll
99
+ highest_results = set.sort_by{|d| d.value }.reverse[0..top-1]
100
+ return highest_results.map(&:to_i).inject(0){|sum,i| sum += i } + plus
101
+ end
102
+ alias :result :highest
103
+
104
+ def reroll
105
+ set.map(&:reroll)
106
+ self
107
+ end
108
+
109
+ def roll; reroll; end
110
+
111
+ def generate_results
112
+ @results = Hash.new(0)
113
+ how_many.times { @results[highest(top: top_number_of_dice, re_roll: true)] += 1 }
114
+ self
115
+ end
116
+
117
+ def graph(r=@results)
118
+ DiceGraph.new(r, how_many, top_number_of_dice).graph
119
+ end
120
+
121
+ def roll_results
122
+ set.inspect
123
+ end
124
+
125
+ def results
126
+ "results: #{(@results.sort_by {|k,v| k }).to_h.inspect}"
127
+ end
128
+
129
+ def total
130
+ highest(top: top_number_of_dice)
131
+ end
132
+
133
+ def inspect
134
+ puts "<DicePool:\n @set: #{@set.inspect}, @plus: #{plus}, @total: #{total}, @top: #{top_number_of_dice}>"
135
+ end
136
+
137
+ def self.inspect
138
+ puts "<DicePool:\n @set: #{@set.inspect}, @plus: #{plus}, @total: #{total}, @top: #{top_number_of_dice}>"
139
+ end
140
+
141
+ def to_h
142
+ {
143
+ top: top_number_of_dice,
144
+ total: total,
145
+ plus: plus,
146
+ set: @set.map(&:to_h)
147
+ }
148
+ end
149
+
150
+ def to_json
151
+ to_h.to_json
152
+ end
153
+
154
+ end
155
+
156
+ class DiceGraph
157
+
158
+ def initialize(r, how_many, top_number_of_dice)
159
+ @data = generate_text_graph(r, how_many, top_number_of_dice)
160
+ end
161
+
162
+ def graph
163
+ @data
164
+ end
165
+
166
+ def generate_text_graph(r, how_many, top_number_of_dice)
167
+ raise "There are no statistical results to graph. Run :generate_results" unless r
168
+ data = "Running #{how_many} times, taking the top #{top_number_of_dice}, the breakdown of results by value rolled are:"
169
+ data << "\n" + ("◘" * 30) + "\n"
170
+ r.sort.each do |total, count|
171
+ percentage = (count.to_f/how_many.to_f)
172
+ data << sprintf("%3d ", total)
173
+ data << '('
174
+ data << sprintf("%5.2f", percentage * 100)
175
+ data << "%) "
176
+ dots = (percentage*500).to_i
177
+ if dots > 100
178
+ data << '▃' * 80
179
+ data << "*(#{dots})"
180
+ else
181
+ data << '▃' * (percentage*500).to_i
182
+ end
183
+ data << "\n"
184
+ end
185
+ data
186
+ end
187
+
188
+ end
189
+
190
+ Dice = DiceBag.instance
191
+
192
+
193
+ # ds=DiceDSL.parse("3[4d6]"); [ds.reroll.total, ds.reroll.total, ds.reroll.total, ds.reroll.total, ds.reroll.total, ds.reroll.total]
194
+ # h=[]; (2..7).each {|e| (2..7).each {|i| (0..12).each {|plus| 1_000.times {|x| if e > i; e = i; end; h << DiceDSL.parse("#{e}[#{i}d6]+#{plus}").to_h } } } }
metadata ADDED
@@ -0,0 +1,44 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: diceguru
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.2
5
+ platform: ruby
6
+ authors:
7
+ - Matt Petty
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-28 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Roll sets of dice and generate statistical information
14
+ email: matt@kizmeta.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/dicebag.rb
20
+ homepage: http://rubygems.org/gems/diceguru
21
+ licenses:
22
+ - MIT
23
+ metadata: {}
24
+ post_install_message:
25
+ rdoc_options: []
26
+ require_paths:
27
+ - lib
28
+ required_ruby_version: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ requirements:
35
+ - - ">="
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ requirements: []
39
+ rubyforge_project:
40
+ rubygems_version: 2.2.2
41
+ signing_key:
42
+ specification_version: 4
43
+ summary: Dice roller and statistic generation
44
+ test_files: []