diceguru 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/dicebag.rb +194 -0
- metadata +44 -0
checksums.yaml
ADDED
@@ -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
|
data/lib/dicebag.rb
ADDED
@@ -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: []
|