diceguru 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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: []