mgmg 1.4.1 → 1.5.1
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/CHANGELOG.md +23 -0
- data/README.md +51 -10
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +19 -24
- data/lib/mgmg/ir.rb +401 -373
- data/lib/mgmg/optimize.rb +21 -9
- data/lib/mgmg/option.rb +84 -0
- data/lib/mgmg/poly.rb +2 -2
- data/lib/mgmg/recipe.rb +172 -0
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +204 -222
- data/lib/mgmg/system_equip.rb +6 -0
- data/lib/mgmg/utils.rb +70 -2
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +186 -70
- data/mgmg.gemspec +4 -4
- data/reference.md +271 -49
- metadata +14 -10
data/lib/mgmg/utils.rb
CHANGED
@@ -14,6 +14,48 @@ module Mgmg
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
+
refine Float do
|
18
|
+
alias :cdiv :quo # Floatの場合は普通の割り算
|
19
|
+
def comma3
|
20
|
+
s = (self*100).round.to_s
|
21
|
+
if s[0] == '-'
|
22
|
+
g, s = '-', s[1..(-1)]
|
23
|
+
else
|
24
|
+
g = ''
|
25
|
+
end
|
26
|
+
raise unless %r|\A\d+\Z|.match(s)
|
27
|
+
case s.length
|
28
|
+
when 1
|
29
|
+
if s == '0'
|
30
|
+
'0.0'
|
31
|
+
else
|
32
|
+
g+'0.0'+s
|
33
|
+
end
|
34
|
+
when 2
|
35
|
+
if s[1] == '0'
|
36
|
+
g+'0.'+s[0]
|
37
|
+
else
|
38
|
+
g+'0.'+s
|
39
|
+
end
|
40
|
+
else
|
41
|
+
i, d = s[0..(-3)], s[(-2)..(-1)]
|
42
|
+
d = d[0] if d[1] == '0'
|
43
|
+
g+i.gsub(/(\d)(?=(\d{3})+(?!\d))/, '\1,') + '.' + d
|
44
|
+
end
|
45
|
+
rescue
|
46
|
+
self.to_s
|
47
|
+
end
|
48
|
+
end
|
49
|
+
refine Rational do
|
50
|
+
alias :cdiv :quo # Rationalの場合は普通の割り算
|
51
|
+
def comma3
|
52
|
+
if self.denominator == 1
|
53
|
+
self.numerator.comma3
|
54
|
+
else
|
55
|
+
self.to_f.comma3
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
17
59
|
end
|
18
60
|
using Refiner
|
19
61
|
|
@@ -46,6 +88,27 @@ module Mgmg
|
|
46
88
|
end
|
47
89
|
attr_accessor :equip
|
48
90
|
end
|
91
|
+
class InvalidReinforcementNameError < StandardError
|
92
|
+
def initialize(str)
|
93
|
+
@name = str
|
94
|
+
super("Unknown skill or preset cuisine name `#{@name}' is given.")
|
95
|
+
end
|
96
|
+
attr_accessor :name
|
97
|
+
end
|
98
|
+
class InvalidRecipeError < StandardError
|
99
|
+
def initialize(msg=nil)
|
100
|
+
if msg.nil?
|
101
|
+
super("Neither String nor Enumerable recipe was set.")
|
102
|
+
else
|
103
|
+
super(msg)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
class Over20Error < StandardError
|
108
|
+
def initialize(star)
|
109
|
+
super("The star of given recipe is #{star}. It can't be built since the star is over 20.")
|
110
|
+
end
|
111
|
+
end
|
49
112
|
class SearchCutException < StandardError; end
|
50
113
|
class UnexpectedError < StandardError
|
51
114
|
def initialize()
|
@@ -90,8 +153,13 @@ module Mgmg
|
|
90
153
|
module_function def invexp3(exp, sa, comp)
|
91
154
|
Math.sqrt(exp - ((sa-1)**2) - (2*((comp-1)**2)) - 4).round + 1
|
92
155
|
end
|
156
|
+
module_function def option(recipe=nil, **kw)
|
157
|
+
ret = Option.new(**kw)
|
158
|
+
ret.set_default(recipe) unless recipe.nil?
|
159
|
+
ret
|
160
|
+
end
|
93
161
|
|
94
|
-
CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]
|
162
|
+
CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]/.freeze
|
95
163
|
module_function def check_string(str)
|
96
164
|
str = str.gsub(/[\s \\]/, '')
|
97
165
|
if m = CharacterList.match(str)
|
@@ -134,7 +202,7 @@ module Mgmg
|
|
134
202
|
end
|
135
203
|
str
|
136
204
|
end
|
137
|
-
|
205
|
+
|
138
206
|
module_function def parse_material(str)
|
139
207
|
m = /\A.+?(\d+)\Z/.match(str)
|
140
208
|
mat = MaterialIndex[str.to_sym]
|
data/lib/mgmg/version.rb
CHANGED
data/lib/mgmg.rb
CHANGED
@@ -5,120 +5,237 @@ require_relative './mgmg/equip'
|
|
5
5
|
require_relative './mgmg/poly'
|
6
6
|
require_relative './mgmg/ir'
|
7
7
|
require_relative './mgmg/system_equip'
|
8
|
+
require_relative './mgmg/cuisine'
|
9
|
+
require_relative './mgmg/reinforce'
|
10
|
+
require_relative './mgmg/option'
|
11
|
+
require_relative './mgmg/recipe'
|
8
12
|
require_relative './mgmg/search'
|
9
13
|
require_relative './mgmg/optimize'
|
10
14
|
|
11
15
|
class String
|
12
|
-
|
13
|
-
|
16
|
+
using Mgmg::Refiner
|
17
|
+
def to_recipe(para=:power, allow_over20: false, **kw)
|
18
|
+
ret = Mgmg::Recipe.new(self, para, **kw)
|
19
|
+
raise Mgmg::Over20Error, ret.ir.star if (!allow_over20 and 20<ret.ir.star)
|
20
|
+
ret
|
21
|
+
end
|
22
|
+
def min_weight(opt: Mgmg::Option.new)
|
23
|
+
build(build(opt: opt).min_levels_max, opt: opt).weight
|
24
|
+
end
|
25
|
+
def max_weight(include_outsourcing=false, opt: Mgmg::Option.new)
|
26
|
+
if include_outsourcing
|
27
|
+
build(-1, opt: opt).weight
|
28
|
+
else
|
29
|
+
build(min_smith(opt: opt), opt: opt).weight
|
30
|
+
end
|
31
|
+
end
|
32
|
+
def min_level(w=0, include_outsourcing=false, opt: Mgmg::Option.new)
|
33
|
+
built = build(-1, opt: opt)
|
34
|
+
w = build(built.min_levels_max, -1, opt: opt).weight - w if w <= 0
|
35
|
+
return -1 if include_outsourcing && built.weight <= w
|
36
|
+
ms = min_smith(opt: opt)
|
37
|
+
return ms if build(ms, opt: opt).weight <= w
|
38
|
+
ary = [ms]
|
39
|
+
4.downto(1) do |wi| # 単品の最大重量は[斧|重鎧](金10石10)の5
|
40
|
+
built.min_levels(wi).values.each do |v|
|
41
|
+
(ary.include?(v) or ary << v) if ms < v
|
42
|
+
end
|
43
|
+
end
|
44
|
+
ary.sort.each do |l|
|
45
|
+
return l if build(l, opt: opt).weight <= w
|
46
|
+
end
|
47
|
+
raise ArgumentError, "w=`#{w}' is given, but the minimum weight for the recipe is `#{min_weight(opt: opt)}'."
|
48
|
+
end
|
49
|
+
def min_levels(w=1, opt: Mgmg::Option.new)
|
50
|
+
build(opt: opt).min_levels(w)
|
14
51
|
end
|
15
|
-
def
|
16
|
-
|
52
|
+
def min_levels_max(w=1, opt: Mgmg::Option.new)
|
53
|
+
min_levels(w, opt: opt).values.append(-1).max
|
17
54
|
end
|
18
|
-
def min_smith(
|
19
|
-
Mgmg::Equip.min_smith(self,
|
55
|
+
def min_smith(opt: Mgmg::Option.new)
|
56
|
+
Mgmg::Equip.min_smith(self, opt: opt)
|
20
57
|
end
|
21
|
-
def min_comp(
|
22
|
-
Mgmg::Equip.min_comp(self,
|
58
|
+
def min_comp(opt: Mgmg::Option.new)
|
59
|
+
Mgmg::Equip.min_comp(self, opt: opt)
|
23
60
|
end
|
24
|
-
def build(smith=-1, comp=smith,
|
25
|
-
Mgmg::Equip.build(self, smith, comp, left_associative: left_associative)
|
61
|
+
def build(smith=-1, comp=smith, opt: Mgmg::Option.new)
|
62
|
+
Mgmg::Equip.build(self, smith, comp, left_associative: opt.left_associative).reinforce(*opt.reinforcement)
|
26
63
|
end
|
27
|
-
def ir(
|
28
|
-
Mgmg::IR.build(self, left_associative: left_associative)
|
64
|
+
def ir(opt: Mgmg::Option.new)
|
65
|
+
Mgmg::IR.build(self, left_associative: opt.left_associative, reinforcement: opt.reinforcement)
|
29
66
|
end
|
30
|
-
def poly(para=:cost,
|
31
|
-
la = left_associative
|
67
|
+
def poly(para=:cost, opt: Mgmg::Option.new)
|
32
68
|
case para
|
33
69
|
when :atkstr
|
34
|
-
self.poly(:attack,
|
70
|
+
self.poly(:attack, opt: opt) + self.poly(:str, opt: opt)
|
35
71
|
when :atk_sd
|
36
|
-
self.poly(:attack,
|
72
|
+
self.poly(:attack, opt: opt) + self.poly(:str, opt: opt).quo(2) + self.poly(:dex, opt: opt).quo(2)
|
37
73
|
when :dex_as
|
38
|
-
self.poly(:dex,
|
74
|
+
self.poly(:dex, opt: opt) + self.poly(:attack, opt: opt).quo(2) + self.poly(:str, opt: opt).quo(2)
|
39
75
|
when :mag_das
|
40
|
-
self.poly(:magic,
|
76
|
+
self.poly(:magic, opt: opt) + self.poly(:dex_as, opt: opt).quo(2)
|
41
77
|
when :magmag
|
42
|
-
self.poly(:magdef,
|
78
|
+
self.poly(:magdef, opt: opt) + self.poly(:magic, opt: opt).quo(2)
|
43
79
|
when :pmdef
|
44
|
-
pd = self.poly(:phydef,
|
45
|
-
md = self.poly(:magmag,
|
80
|
+
pd = self.poly(:phydef, opt: opt)
|
81
|
+
md = self.poly(:magmag, opt: opt)
|
46
82
|
pd <= md ? pd : md
|
47
83
|
when :cost
|
48
84
|
if Mgmg::SystemEquip.keys.include?(self)
|
49
85
|
return Mgmg::TPolynomial.new(Mgmg::Mat.new(1, 1, 0.quo(1)), 28, 0, 12, 12)
|
50
86
|
end
|
51
|
-
built = self.build(-1)
|
87
|
+
built = self.build(-1, opt: opt)
|
52
88
|
const = (built.star**2) * ( /\+/.match(self) ? 5 : ( built.kind < 8 ? 2 : 1 ) )
|
53
|
-
ret = poly(:attack,
|
54
|
-
ret += poly(:hp,
|
55
|
-
ret += poly(:str,
|
89
|
+
ret = poly(:attack, opt: opt) + poly(:phydef, opt: opt) + poly(:magdef, opt: opt)
|
90
|
+
ret += poly(:hp, opt: opt).quo(4) + poly(:mp, opt: opt).quo(4)
|
91
|
+
ret += poly(:str, opt: opt) + poly(:dex, opt: opt) + poly(:speed, opt: opt) + poly(:magic, opt: opt)
|
56
92
|
ret.mat.body[0][0] += const
|
57
93
|
ret
|
58
94
|
else
|
59
|
-
Mgmg::TPolynomial.build(self, para, left_associative:
|
95
|
+
Mgmg::TPolynomial.build(self, para, left_associative: opt.left_associative)
|
60
96
|
end
|
61
97
|
end
|
62
|
-
def eff(para, smith, comp=smith,
|
63
|
-
a = build(smith, comp,
|
64
|
-
b = build(smith+1, comp,
|
65
|
-
c = build(smith, comp+2,
|
98
|
+
def eff(para, smith, comp=smith, opt: Mgmg::Option.new)
|
99
|
+
a = build(smith, comp, opt: opt).para_call(para)
|
100
|
+
b = build(smith+1, comp, opt: opt).para_call(para)
|
101
|
+
c = build(smith, comp+2, opt: opt).para_call(para)
|
66
102
|
sden = smith==0 ? 1 : 2*smith-1
|
67
103
|
cden = comp==0 ? 4 : 8*comp
|
68
104
|
[(b-a).quo(sden), (c-a).quo(cden)]
|
69
105
|
end
|
70
|
-
def peff(para, smith, comp=smith,
|
71
|
-
poly(para,
|
106
|
+
def peff(para, smith, comp=smith, opt: Mgmg::Option.new)
|
107
|
+
poly(para, opt: opt).eff(smith, comp)
|
72
108
|
end
|
73
|
-
def show(smith=-1, comp=smith,
|
74
|
-
|
109
|
+
def show(smith=-1, comp=smith, para: :power, opt: Mgmg::Option.new)
|
110
|
+
rein = case opt.reinforcement
|
111
|
+
when Array
|
112
|
+
opt.reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
113
|
+
else
|
114
|
+
[Mgmg::Reinforcement.compile(opt.reinforcement)]
|
115
|
+
end
|
116
|
+
built = build(smith, comp, opt: opt)
|
75
117
|
pstr = '%.3f' % built.para_call(para)
|
76
118
|
pstr.sub!(/\.?0+\Z/, '')
|
77
|
-
puts "
|
119
|
+
puts "With levels (#{smith}, #{comp}: #{Mgmg.exp(smith, comp).comma3}), building"
|
78
120
|
puts " #{self}"
|
79
|
-
|
121
|
+
rein = rein.empty? ? '' : "reinforced by {#{rein.join(',')}} "
|
122
|
+
puts "#{rein}yields (#{pstr}, #{built.total_cost})"
|
80
123
|
puts " #{built}"
|
81
124
|
end
|
82
|
-
def phydef_optimize(smith=nil, comp=smith,
|
83
|
-
Mgmg::Optimize.phydef_optimize(self, smith, comp,
|
125
|
+
def phydef_optimize(smith=nil, comp=smith, opt: Mgmg::Option.new)
|
126
|
+
Mgmg::Optimize.phydef_optimize(self, smith, comp, opt: opt)
|
84
127
|
end
|
85
|
-
def buster_optimize(smith=nil, comp=smith,
|
86
|
-
Mgmg::Optimize.buster_optimize(self, smith, comp,
|
128
|
+
def buster_optimize(smith=nil, comp=smith, opt: Mgmg::Option.new)
|
129
|
+
Mgmg::Optimize.buster_optimize(self, smith, comp, opt: opt)
|
87
130
|
end
|
88
131
|
end
|
89
132
|
module Enumerable
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
133
|
+
using Mgmg::Refiner
|
134
|
+
def to_recipe(para=:power, **kw)
|
135
|
+
Mgmg::Recipe.new(self, para, **kw)
|
136
|
+
end
|
137
|
+
def build(smith=-1, armor=smith, comp=armor.tap{armor=smith}, opt: Mgmg::Option.new)
|
138
|
+
opt = opt.dup
|
139
|
+
rein = opt.reinforcement
|
140
|
+
opt.reinforcement = []
|
141
|
+
self.sum(Mgmg::Equip::Zero) do |str|
|
142
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
143
|
+
str.build(smith, comp, opt: opt)
|
95
144
|
else
|
96
|
-
str.build(armor, comp,
|
145
|
+
str.build(armor, comp, opt: opt)
|
97
146
|
end
|
98
|
-
end.
|
147
|
+
end.reinforce(*rein)
|
99
148
|
end
|
100
|
-
def ir(
|
101
|
-
self.
|
102
|
-
str.ir(
|
103
|
-
end.
|
149
|
+
def ir(opt: Mgmg::Option.new)
|
150
|
+
self.sum(Mgmg::IR::Zero) do |str|
|
151
|
+
str.ir(opt: opt)
|
152
|
+
end.add_reinforcement(opt.reinforcement)
|
104
153
|
end
|
105
|
-
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith},
|
106
|
-
|
154
|
+
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, para: :power, opt: Mgmg::Option.new)
|
155
|
+
rein = case opt.reinforcement
|
156
|
+
when Array
|
157
|
+
opt.reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
158
|
+
else
|
159
|
+
[Mgmg::Reinforcement.compile(opt.reinforcement)]
|
160
|
+
end
|
161
|
+
built = self.build(smith, armor, comp, opt: opt)
|
107
162
|
pstr = '%.3f' % built.para_call(para)
|
108
163
|
pstr.sub!(/\.?0+\Z/, '')
|
109
|
-
puts "
|
164
|
+
puts "With levels (#{smith}, #{armor}, #{comp}: #{Mgmg.exp(smith, armor, comp).comma3}), building"
|
110
165
|
puts " #{self.join(', ')}"
|
111
|
-
|
166
|
+
rein = rein.empty? ? '' : "reinforced by {#{rein.join(',')}} "
|
167
|
+
puts "#{rein}yields (#{pstr}, #{built.total_cost})"
|
112
168
|
puts " #{built}"
|
113
169
|
end
|
114
|
-
def
|
115
|
-
build(
|
170
|
+
def min_weight(opt: Mgmg::Option.new)
|
171
|
+
build(*build(opt: opt).min_levels_max, -1, opt: opt).weight
|
172
|
+
end
|
173
|
+
def max_weight(include_outsourcing=false, opt: Mgmg::Option.new)
|
174
|
+
if include_outsourcing
|
175
|
+
build(-1, opt: opt).weight
|
176
|
+
else
|
177
|
+
build(*min_smith(opt: opt), -1, opt: opt).weight
|
178
|
+
end
|
179
|
+
end
|
180
|
+
def min_weights(opt: Mgmg::Option.new)
|
181
|
+
weapons, armors = [], []
|
182
|
+
each do |str|
|
183
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
184
|
+
weapons << str
|
185
|
+
else
|
186
|
+
armors << str
|
187
|
+
end
|
188
|
+
end
|
189
|
+
[weapons.min_weight(opt: opt), armors.min_weight(opt: opt)]
|
190
|
+
end
|
191
|
+
def max_weights(include_outsourcing=false, opt: Mgmg::Option.new)
|
192
|
+
weapons, armors = [], []
|
193
|
+
each do |str|
|
194
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
195
|
+
weapons << str
|
196
|
+
else
|
197
|
+
armors << str
|
198
|
+
end
|
199
|
+
end
|
200
|
+
[weapons.max_weight(include_outsourcing, opt: opt), armors.max_weight(include_outsourcing, opt: opt)]
|
201
|
+
end
|
202
|
+
def min_level(ws=0, wa=ws, include_outsourcing=false, opt: Mgmg::Option.new)
|
203
|
+
weapons, armors = [], []
|
204
|
+
each do |str|
|
205
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
206
|
+
weapons << str
|
207
|
+
else
|
208
|
+
armors << str
|
209
|
+
end
|
210
|
+
end
|
211
|
+
ms, ma = min_smith(opt: opt)
|
212
|
+
rs = min_level_sub(ws, ms, 0, weapons, include_outsourcing, opt: opt)
|
213
|
+
ra = min_level_sub(wa, ma, 1, armors, include_outsourcing, opt: opt)
|
214
|
+
[rs, ra]
|
215
|
+
end
|
216
|
+
private def min_level_sub(w, ms, i, recipe, include_outsourcing, opt: Mgmg::Option.new)
|
217
|
+
built = recipe.build(opt: opt)
|
218
|
+
w = recipe.build(built.min_levels_max[i], opt: opt).weight - w if w <= 0
|
219
|
+
return -1 if include_outsourcing && built.weight <= w
|
220
|
+
return ms if build(ms, opt: opt).weight <= w
|
221
|
+
ary = [ms]
|
222
|
+
4.downto(1) do |wi|
|
223
|
+
built.min_levels(wi).values.each do |v|
|
224
|
+
(ary.include?(v) or ary << v) if ms << v
|
225
|
+
end
|
226
|
+
end
|
227
|
+
ary.sort.each do |l|
|
228
|
+
return l if recipe.build(l, opt: opt).weight <= w
|
229
|
+
end
|
230
|
+
raise ArgumentError, "w#{%w|s a|[i]}=`#{w}' is given, but the minimum weight for the #{%w|weapon(s) armor(s)|[i]} is `#{recipe.min_weight(opt: opt)}'."
|
231
|
+
end
|
232
|
+
def min_levels(w=1, opt: Mgmg::Option.new)
|
233
|
+
build(opt: opt).min_levels(w)
|
116
234
|
end
|
117
|
-
def
|
118
|
-
ret = [
|
119
|
-
|
120
|
-
|
121
|
-
if Mgmg::EquipPosition[m[1].build(0).kind] == 0
|
235
|
+
def min_levels_max(w=1, opt: Mgmg::Option.new)
|
236
|
+
ret = [-1, -1]
|
237
|
+
min_levels(w, opt: opt).each do |str, level|
|
238
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
122
239
|
ret[0] = [ret[0], level].max
|
123
240
|
else
|
124
241
|
ret[1] = [ret[1], level].max
|
@@ -126,12 +243,11 @@ module Enumerable
|
|
126
243
|
end
|
127
244
|
ret
|
128
245
|
end
|
129
|
-
def min_smith(
|
130
|
-
ret = [
|
246
|
+
def min_smith(opt: Mgmg::Option.new)
|
247
|
+
ret = [-1, -1]
|
131
248
|
self.each do |str|
|
132
|
-
s = Mgmg::Equip.min_smith(str,
|
133
|
-
|
134
|
-
if Mgmg::EquipPosition[m[1].build(0).kind] == 0
|
249
|
+
s = Mgmg::Equip.min_smith(str, opt: opt)
|
250
|
+
if Mgmg::EquipPosition[str.build(opt: opt).kind] == 0
|
135
251
|
ret[0] = [ret[0], s].max
|
136
252
|
else
|
137
253
|
ret[1] = [ret[1], s].max
|
@@ -139,9 +255,9 @@ module Enumerable
|
|
139
255
|
end
|
140
256
|
ret
|
141
257
|
end
|
142
|
-
def min_comp(
|
258
|
+
def min_comp(opt: Mgmg::Option.new)
|
143
259
|
self.map do |str|
|
144
|
-
Mgmg::Equip.min_comp(str,
|
145
|
-
end.max
|
260
|
+
Mgmg::Equip.min_comp(str, opt: opt)
|
261
|
+
end.append(-1).max
|
146
262
|
end
|
147
263
|
end
|
data/mgmg.gemspec
CHANGED
@@ -35,9 +35,9 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
36
36
|
spec.require_paths = ["lib"]
|
37
37
|
|
38
|
-
spec.add_development_dependency "bundler", ">= 2.
|
39
|
-
spec.add_development_dependency "rake", ">= 13.0.
|
40
|
-
spec.add_development_dependency "irb", ">= 1.
|
38
|
+
spec.add_development_dependency "bundler", ">= 2.3.16"
|
39
|
+
spec.add_development_dependency "rake", ">= 13.0.6"
|
40
|
+
spec.add_development_dependency "irb", ">= 1.4.1"
|
41
41
|
|
42
|
-
spec.required_ruby_version = '>=
|
42
|
+
spec.required_ruby_version = '>= 3.1.0'
|
43
43
|
end
|