mgmg 1.5.1 → 1.5.4
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 +14 -0
- data/lib/mgmg/cuisine.rb +49 -49
- data/lib/mgmg/equip.rb +181 -171
- data/lib/mgmg/ir.rb +114 -108
- data/lib/mgmg/optimize.rb +9 -9
- data/lib/mgmg/option.rb +19 -4
- data/lib/mgmg/poly.rb +68 -61
- data/lib/mgmg/recipe.rb +9 -9
- data/lib/mgmg/reinforce.rb +34 -35
- data/lib/mgmg/search.rb +10 -10
- data/lib/mgmg/system_equip.rb +2 -4
- data/lib/mgmg/utils.rb +3 -4
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +71 -62
- data/reference.md +27 -25
- metadata +2 -2
data/lib/mgmg/search.rb
CHANGED
@@ -48,11 +48,11 @@ class String
|
|
48
48
|
def search(para, target, opt: Mgmg::Option.new)
|
49
49
|
opt = opt.dup.set_default(self)
|
50
50
|
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
51
|
-
opt.comp_min = comp_search(para, target, opt.smith_max, opt:
|
51
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt:)
|
52
52
|
opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
|
53
53
|
opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
|
54
54
|
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
|
55
|
-
opt.comp_max = comp_search(para, target, opt.smith_min, opt:
|
55
|
+
opt.comp_max = comp_search(para, target, opt.smith_min, opt:)
|
56
56
|
ret = nil
|
57
57
|
exp = Mgmg.exp(opt.smith_min, opt.comp_max)
|
58
58
|
opt.cut_exp, ret = exp, [opt.smith_min, opt.comp_max] if exp < opt.cut_exp
|
@@ -60,7 +60,7 @@ class String
|
|
60
60
|
opt.cut_exp, ret = exp, [opt.smith_max, opt.comp_min] if exp < opt.cut_exp
|
61
61
|
(opt.comp_min+opt.step).step(opt.comp_max-1, opt.step) do |comp|
|
62
62
|
break if opt.cut_exp < Mgmg.exp(opt.smith_min, comp)
|
63
|
-
smith = smith_search(para, target, comp, opt:
|
63
|
+
smith = smith_search(para, target, comp, opt:)
|
64
64
|
exp = Mgmg.exp(smith, comp)
|
65
65
|
if exp < opt.cut_exp
|
66
66
|
opt.cut_exp, ret = exp, [smith, comp]
|
@@ -144,7 +144,7 @@ module Enumerable
|
|
144
144
|
opt.cut_exp, ret = exp2, [opt.smith_max, opt.armor_min] if exp2 < opt.cut_exp
|
145
145
|
(opt.armor_min+1).upto(opt.armor_max-1) do |armor|
|
146
146
|
break if opt.cut_exp < Mgmg.exp(opt.smith_min, armor, comp)
|
147
|
-
smith = smith_search(para, target, armor, comp, opt:
|
147
|
+
smith = smith_search(para, target, armor, comp, opt:)
|
148
148
|
exp = Mgmg.exp(smith, armor, comp)
|
149
149
|
if exp < opt.cut_exp
|
150
150
|
opt.cut_exp, ret = exp, [smith, armor]
|
@@ -158,7 +158,7 @@ module Enumerable
|
|
158
158
|
else
|
159
159
|
(opt.smith_min+1).upto(opt.smith_max-1) do |smith|
|
160
160
|
break if opt.cut_exp < Mgmg.exp(smith, opt.armor_min, comp)
|
161
|
-
armor = armor_search(para, target, smith, comp, opt:
|
161
|
+
armor = armor_search(para, target, smith, comp, opt:)
|
162
162
|
exp = Mgmg.exp(smith, armor, comp)
|
163
163
|
if exp < opt.cut_exp
|
164
164
|
opt.cut_exp, ret = exp, [smith, armor]
|
@@ -195,11 +195,11 @@ module Enumerable
|
|
195
195
|
end
|
196
196
|
def search(para, target, opt: Mgmg::Option.new)
|
197
197
|
opt = opt.dup.set_default(self)
|
198
|
-
opt.comp_min = comp_search(para, target, opt.smith_max, opt.armor_max, opt:
|
199
|
-
opt.smith_max, opt.armor_max = sa_search(para, target, opt.comp_min, opt:
|
200
|
-
opt.smith_min, opt.armor_min = sa_search(para, target, opt.comp_max, opt:
|
198
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt.armor_max, opt:)
|
199
|
+
opt.smith_max, opt.armor_max = sa_search(para, target, opt.comp_min, opt:)
|
200
|
+
opt.smith_min, opt.armor_min = sa_search(para, target, opt.comp_max, opt:)
|
201
201
|
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_min)
|
202
|
-
opt.comp_max = comp_search(para, target, opt.smith_min, opt.armor_min, opt:
|
202
|
+
opt.comp_max = comp_search(para, target, opt.smith_min, opt.armor_min, opt:)
|
203
203
|
ret = nil
|
204
204
|
exp = Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_max)
|
205
205
|
opt.cut_exp, ret = exp, [opt.smith_min, opt.armor_min,opt. comp_max] if exp < opt.cut_exp
|
@@ -207,7 +207,7 @@ module Enumerable
|
|
207
207
|
opt.cut_exp, ret = exp, [opt.smith_max, opt.armor_max, opt.comp_min] if exp < opt.cut_exp
|
208
208
|
(opt.comp_min+1).upto(opt.comp_max-1) do |comp|
|
209
209
|
break if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, comp)
|
210
|
-
smith, armor = sa_search(para, target, comp, opt:
|
210
|
+
smith, armor = sa_search(para, target, comp, opt:)
|
211
211
|
exp = Mgmg.exp(smith, armor, comp)
|
212
212
|
if exp < opt.cut_exp
|
213
213
|
opt.cut_exp, ret = exp, [smith, armor, comp]
|
data/lib/mgmg/system_equip.rb
CHANGED
@@ -323,10 +323,8 @@ module Mgmg
|
|
323
323
|
SystemEquip.store(k.sub(/脛当て\Z/, 'すね当て'), SystemEquip[k])
|
324
324
|
end
|
325
325
|
end
|
326
|
-
SystemEquip.freeze
|
327
326
|
SystemEquipRegexp = Hash.new
|
328
|
-
SystemEquip.
|
329
|
-
SystemEquipRegexp.store(k
|
327
|
+
SystemEquip.each_key do |k|
|
328
|
+
SystemEquipRegexp.store(k, Regexp.compile(k).freeze)
|
330
329
|
end
|
331
|
-
SystemEquipRegexp.freeze
|
332
330
|
end
|
data/lib/mgmg/utils.rb
CHANGED
@@ -153,10 +153,9 @@ module Mgmg
|
|
153
153
|
module_function def invexp3(exp, sa, comp)
|
154
154
|
Math.sqrt(exp - ((sa-1)**2) - (2*((comp-1)**2)) - 4).round + 1
|
155
155
|
end
|
156
|
-
module_function def
|
157
|
-
|
158
|
-
|
159
|
-
ret
|
156
|
+
module_function def clear_cache
|
157
|
+
CacheMLS.clear; Equip::Cache.clear; Equip::CacheML.clear; TPolynomial::Cache.clear; IR::Cache.clear
|
158
|
+
nil
|
160
159
|
end
|
161
160
|
|
162
161
|
CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]/.freeze
|
data/lib/mgmg/version.rb
CHANGED
data/lib/mgmg.rb
CHANGED
@@ -20,21 +20,28 @@ class String
|
|
20
20
|
ret
|
21
21
|
end
|
22
22
|
def min_weight(opt: Mgmg::Option.new)
|
23
|
-
build(build(opt:
|
23
|
+
build(build(opt:).min_levels_max, opt:).weight
|
24
24
|
end
|
25
25
|
def max_weight(include_outsourcing=false, opt: Mgmg::Option.new)
|
26
26
|
if include_outsourcing
|
27
|
-
build(-1, opt:
|
27
|
+
build(-1, opt:).weight
|
28
28
|
else
|
29
|
-
build(min_smith(opt:
|
29
|
+
build(min_smith(opt:), opt:).weight
|
30
30
|
end
|
31
31
|
end
|
32
32
|
def min_level(w=0, include_outsourcing=false, opt: Mgmg::Option.new)
|
33
|
-
|
34
|
-
|
33
|
+
key = [self.dup.freeze, w, include_outsourcing, opt.left_associative].freeze
|
34
|
+
return Mgmg::CacheMLS[key] if Mgmg::CacheMLS.has_key?(key)
|
35
|
+
ret = __min_level_sub(w, include_outsourcing, opt)
|
36
|
+
Mgmg::CacheMLS.store(key, ret)
|
37
|
+
ret
|
38
|
+
end
|
39
|
+
private def __min_level_sub(w, include_outsourcing, opt)
|
40
|
+
built = build(-1, opt:)
|
41
|
+
w = build(built.min_levels_max, -1, opt:).weight - w if w <= 0
|
35
42
|
return -1 if include_outsourcing && built.weight <= w
|
36
|
-
ms = min_smith(opt:
|
37
|
-
return ms if build(ms, opt:
|
43
|
+
ms = min_smith(opt:)
|
44
|
+
return ms if build(ms, opt:).weight <= w
|
38
45
|
ary = [ms]
|
39
46
|
4.downto(1) do |wi| # 単品の最大重量は[斧|重鎧](金10石10)の5
|
40
47
|
built.min_levels(wi).values.each do |v|
|
@@ -42,69 +49,71 @@ class String
|
|
42
49
|
end
|
43
50
|
end
|
44
51
|
ary.sort.each do |l|
|
45
|
-
return l if build(l, opt:
|
52
|
+
return l if build(l, opt:).weight <= w
|
46
53
|
end
|
47
|
-
raise ArgumentError, "w=`#{w}' is given, but the minimum weight for the recipe is `#{min_weight(opt:
|
54
|
+
raise ArgumentError, "w=`#{w}' is given, but the minimum weight for the recipe is `#{min_weight(opt:)}'."
|
48
55
|
end
|
49
56
|
def min_levels(w=1, opt: Mgmg::Option.new)
|
50
|
-
build(opt:
|
57
|
+
build(opt:).min_levels(w)
|
51
58
|
end
|
52
59
|
def min_levels_max(w=1, opt: Mgmg::Option.new)
|
53
|
-
min_levels(w, opt:
|
60
|
+
min_levels(w, opt:).values.append(-1).max
|
54
61
|
end
|
55
62
|
def min_smith(opt: Mgmg::Option.new)
|
56
|
-
Mgmg::Equip.min_smith(self, opt:
|
63
|
+
Mgmg::Equip.min_smith(self, opt:)
|
57
64
|
end
|
58
65
|
def min_comp(opt: Mgmg::Option.new)
|
59
|
-
Mgmg::Equip.min_comp(self, opt:
|
66
|
+
Mgmg::Equip.min_comp(self, opt:)
|
60
67
|
end
|
61
68
|
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)
|
69
|
+
Mgmg::Equip.build(self, smith, comp, left_associative: opt.left_associative, include_system_equips: opt.include_system_equips).reinforce(*opt.reinforcement)
|
63
70
|
end
|
64
71
|
def ir(opt: Mgmg::Option.new)
|
65
|
-
Mgmg::IR.build(self, left_associative: opt.left_associative, reinforcement: opt.reinforcement)
|
72
|
+
Mgmg::IR.build(self, left_associative: opt.left_associative, reinforcement: opt.reinforcement, include_system_equips: opt.include_system_equips)
|
66
73
|
end
|
67
74
|
def poly(para=:cost, opt: Mgmg::Option.new)
|
68
75
|
case para
|
69
76
|
when :atkstr
|
70
|
-
self.poly(:attack, opt:
|
77
|
+
self.poly(:attack, opt:) + self.poly(:str, opt:)
|
71
78
|
when :atk_sd
|
72
|
-
self.poly(:attack, opt:
|
79
|
+
self.poly(:attack, opt:) + self.poly(:str, opt:).quo(2) + self.poly(:dex, opt:).quo(2)
|
73
80
|
when :dex_as
|
74
|
-
self.poly(:dex, opt:
|
81
|
+
self.poly(:dex, opt:) + self.poly(:attack, opt:).quo(2) + self.poly(:str, opt:).quo(2)
|
75
82
|
when :mag_das
|
76
|
-
self.poly(:magic, opt:
|
83
|
+
self.poly(:magic, opt:) + self.poly(:dex_as, opt:).quo(2)
|
84
|
+
when :magic2
|
85
|
+
self.poly(:magic, opt:).scalar(2)
|
77
86
|
when :magmag
|
78
|
-
self.poly(:magdef, opt:
|
87
|
+
self.poly(:magdef, opt:) + self.poly(:magic, opt:).quo(2)
|
79
88
|
when :pmdef
|
80
|
-
pd = self.poly(:phydef, opt:
|
81
|
-
md = self.poly(:magmag, opt:
|
89
|
+
pd = self.poly(:phydef, opt:)
|
90
|
+
md = self.poly(:magmag, opt:)
|
82
91
|
pd <= md ? pd : md
|
83
92
|
when :cost
|
84
|
-
if Mgmg::SystemEquip.
|
93
|
+
if opt.include_system_equips and Mgmg::SystemEquip.has_key?(self) then
|
85
94
|
return Mgmg::TPolynomial.new(Mgmg::Mat.new(1, 1, 0.quo(1)), 28, 0, 12, 12)
|
86
95
|
end
|
87
|
-
built = self.build(-1, opt:
|
96
|
+
built = self.build(-1, opt:)
|
88
97
|
const = (built.star**2) * ( /\+/.match(self) ? 5 : ( built.kind < 8 ? 2 : 1 ) )
|
89
|
-
ret = poly(:attack, opt:
|
90
|
-
ret += poly(:hp, opt:
|
91
|
-
ret += poly(:str, opt:
|
98
|
+
ret = poly(:attack, opt:) + poly(:phydef, opt:) + poly(:magdef, opt:)
|
99
|
+
ret += poly(:hp, opt:).quo(4) + poly(:mp, opt:).quo(4)
|
100
|
+
ret += poly(:str, opt:) + poly(:dex, opt:) + poly(:speed, opt:) + poly(:magic, opt:)
|
92
101
|
ret.mat.body[0][0] += const
|
93
102
|
ret
|
94
103
|
else
|
95
|
-
Mgmg::TPolynomial.build(self, para, left_associative: opt.left_associative)
|
104
|
+
Mgmg::TPolynomial.build(self, para, left_associative: opt.left_associative, include_system_equips: opt.include_system_equips)
|
96
105
|
end
|
97
106
|
end
|
98
107
|
def eff(para, smith, comp=smith, opt: Mgmg::Option.new)
|
99
|
-
a = build(smith, comp, opt:
|
100
|
-
b = build(smith+1, comp, opt:
|
101
|
-
c = build(smith, comp+2, opt:
|
108
|
+
a = build(smith, comp, opt:).para_call(para)
|
109
|
+
b = build(smith+1, comp, opt:).para_call(para)
|
110
|
+
c = build(smith, comp+2, opt:).para_call(para)
|
102
111
|
sden = smith==0 ? 1 : 2*smith-1
|
103
112
|
cden = comp==0 ? 4 : 8*comp
|
104
113
|
[(b-a).quo(sden), (c-a).quo(cden)]
|
105
114
|
end
|
106
115
|
def peff(para, smith, comp=smith, opt: Mgmg::Option.new)
|
107
|
-
poly(para, opt:
|
116
|
+
poly(para, opt:).eff(smith, comp)
|
108
117
|
end
|
109
118
|
def show(smith=-1, comp=smith, para: :power, opt: Mgmg::Option.new)
|
110
119
|
rein = case opt.reinforcement
|
@@ -113,7 +122,7 @@ class String
|
|
113
122
|
else
|
114
123
|
[Mgmg::Reinforcement.compile(opt.reinforcement)]
|
115
124
|
end
|
116
|
-
built = build(smith, comp, opt:
|
125
|
+
built = build(smith, comp, opt:)
|
117
126
|
pstr = '%.3f' % built.para_call(para)
|
118
127
|
pstr.sub!(/\.?0+\Z/, '')
|
119
128
|
puts "With levels (#{smith}, #{comp}: #{Mgmg.exp(smith, comp).comma3}), building"
|
@@ -123,10 +132,10 @@ class String
|
|
123
132
|
puts " #{built}"
|
124
133
|
end
|
125
134
|
def phydef_optimize(smith=nil, comp=smith, opt: Mgmg::Option.new)
|
126
|
-
Mgmg::Optimize.phydef_optimize(self, smith, comp, opt:
|
135
|
+
Mgmg::Optimize.phydef_optimize(self, smith, comp, opt:)
|
127
136
|
end
|
128
137
|
def buster_optimize(smith=nil, comp=smith, opt: Mgmg::Option.new)
|
129
|
-
Mgmg::Optimize.buster_optimize(self, smith, comp, opt:
|
138
|
+
Mgmg::Optimize.buster_optimize(self, smith, comp, opt:)
|
130
139
|
end
|
131
140
|
end
|
132
141
|
module Enumerable
|
@@ -139,16 +148,16 @@ module Enumerable
|
|
139
148
|
rein = opt.reinforcement
|
140
149
|
opt.reinforcement = []
|
141
150
|
self.sum(Mgmg::Equip::Zero) do |str|
|
142
|
-
if Mgmg::EquipPosition[str.build(opt:
|
143
|
-
str.build(smith, comp, opt:
|
151
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
152
|
+
str.build(smith, comp, opt:)
|
144
153
|
else
|
145
|
-
str.build(armor, comp, opt:
|
154
|
+
str.build(armor, comp, opt:)
|
146
155
|
end
|
147
156
|
end.reinforce(*rein)
|
148
157
|
end
|
149
158
|
def ir(opt: Mgmg::Option.new)
|
150
159
|
self.sum(Mgmg::IR::Zero) do |str|
|
151
|
-
str.ir(opt:
|
160
|
+
str.ir(opt:)
|
152
161
|
end.add_reinforcement(opt.reinforcement)
|
153
162
|
end
|
154
163
|
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, para: :power, opt: Mgmg::Option.new)
|
@@ -158,7 +167,7 @@ module Enumerable
|
|
158
167
|
else
|
159
168
|
[Mgmg::Reinforcement.compile(opt.reinforcement)]
|
160
169
|
end
|
161
|
-
built = self.build(smith, armor, comp, opt:
|
170
|
+
built = self.build(smith, armor, comp, opt:)
|
162
171
|
pstr = '%.3f' % built.para_call(para)
|
163
172
|
pstr.sub!(/\.?0+\Z/, '')
|
164
173
|
puts "With levels (#{smith}, #{armor}, #{comp}: #{Mgmg.exp(smith, armor, comp).comma3}), building"
|
@@ -168,56 +177,56 @@ module Enumerable
|
|
168
177
|
puts " #{built}"
|
169
178
|
end
|
170
179
|
def min_weight(opt: Mgmg::Option.new)
|
171
|
-
build(*build(opt:
|
180
|
+
build(*build(opt:).min_levels_max, -1, opt:).weight
|
172
181
|
end
|
173
182
|
def max_weight(include_outsourcing=false, opt: Mgmg::Option.new)
|
174
183
|
if include_outsourcing
|
175
|
-
build(-1, opt:
|
184
|
+
build(-1, opt:).weight
|
176
185
|
else
|
177
|
-
build(*min_smith(opt:
|
186
|
+
build(*min_smith(opt:), -1, opt:).weight
|
178
187
|
end
|
179
188
|
end
|
180
189
|
def min_weights(opt: Mgmg::Option.new)
|
181
190
|
weapons, armors = [], []
|
182
191
|
each do |str|
|
183
|
-
if Mgmg::EquipPosition[str.build(opt:
|
192
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
184
193
|
weapons << str
|
185
194
|
else
|
186
195
|
armors << str
|
187
196
|
end
|
188
197
|
end
|
189
|
-
[weapons.min_weight(opt:
|
198
|
+
[weapons.min_weight(opt:), armors.min_weight(opt:)]
|
190
199
|
end
|
191
200
|
def max_weights(include_outsourcing=false, opt: Mgmg::Option.new)
|
192
201
|
weapons, armors = [], []
|
193
202
|
each do |str|
|
194
|
-
if Mgmg::EquipPosition[str.build(opt:
|
203
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
195
204
|
weapons << str
|
196
205
|
else
|
197
206
|
armors << str
|
198
207
|
end
|
199
208
|
end
|
200
|
-
[weapons.max_weight(include_outsourcing, opt:
|
209
|
+
[weapons.max_weight(include_outsourcing, opt:), armors.max_weight(include_outsourcing, opt:)]
|
201
210
|
end
|
202
211
|
def min_level(ws=0, wa=ws, include_outsourcing=false, opt: Mgmg::Option.new)
|
203
212
|
weapons, armors = [], []
|
204
213
|
each do |str|
|
205
|
-
if Mgmg::EquipPosition[str.build(opt:
|
214
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
206
215
|
weapons << str
|
207
216
|
else
|
208
217
|
armors << str
|
209
218
|
end
|
210
219
|
end
|
211
|
-
ms, ma = min_smith(opt:
|
212
|
-
rs = min_level_sub(ws, ms, 0, weapons, include_outsourcing, opt:
|
213
|
-
ra = min_level_sub(wa, ma, 1, armors, include_outsourcing, opt:
|
220
|
+
ms, ma = min_smith(opt:)
|
221
|
+
rs = min_level_sub(ws, ms, 0, weapons, include_outsourcing, opt:)
|
222
|
+
ra = min_level_sub(wa, ma, 1, armors, include_outsourcing, opt:)
|
214
223
|
[rs, ra]
|
215
224
|
end
|
216
225
|
private def min_level_sub(w, ms, i, recipe, include_outsourcing, opt: Mgmg::Option.new)
|
217
|
-
built = recipe.build(opt:
|
218
|
-
w = recipe.build(built.min_levels_max[i], opt:
|
226
|
+
built = recipe.build(opt:)
|
227
|
+
w = recipe.build(built.min_levels_max[i], opt:).weight - w if w <= 0
|
219
228
|
return -1 if include_outsourcing && built.weight <= w
|
220
|
-
return ms if build(ms, opt:
|
229
|
+
return ms if build(ms, opt:).weight <= w
|
221
230
|
ary = [ms]
|
222
231
|
4.downto(1) do |wi|
|
223
232
|
built.min_levels(wi).values.each do |v|
|
@@ -225,17 +234,17 @@ module Enumerable
|
|
225
234
|
end
|
226
235
|
end
|
227
236
|
ary.sort.each do |l|
|
228
|
-
return l if recipe.build(l, opt:
|
237
|
+
return l if recipe.build(l, opt:).weight <= w
|
229
238
|
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:
|
239
|
+
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:)}'."
|
231
240
|
end
|
232
241
|
def min_levels(w=1, opt: Mgmg::Option.new)
|
233
|
-
build(opt:
|
242
|
+
build(opt:).min_levels(w)
|
234
243
|
end
|
235
244
|
def min_levels_max(w=1, opt: Mgmg::Option.new)
|
236
245
|
ret = [-1, -1]
|
237
|
-
min_levels(w, opt:
|
238
|
-
if Mgmg::EquipPosition[str.build(opt:
|
246
|
+
min_levels(w, opt:).each do |str, level|
|
247
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
239
248
|
ret[0] = [ret[0], level].max
|
240
249
|
else
|
241
250
|
ret[1] = [ret[1], level].max
|
@@ -246,8 +255,8 @@ module Enumerable
|
|
246
255
|
def min_smith(opt: Mgmg::Option.new)
|
247
256
|
ret = [-1, -1]
|
248
257
|
self.each do |str|
|
249
|
-
s = Mgmg::Equip.min_smith(str, opt:
|
250
|
-
if Mgmg::EquipPosition[str.build(opt:
|
258
|
+
s = Mgmg::Equip.min_smith(str, opt:)
|
259
|
+
if Mgmg::EquipPosition[str.build(opt:).kind] == 0
|
251
260
|
ret[0] = [ret[0], s].max
|
252
261
|
else
|
253
262
|
ret[1] = [ret[1], s].max
|
@@ -257,7 +266,7 @@ module Enumerable
|
|
257
266
|
end
|
258
267
|
def min_comp(opt: Mgmg::Option.new)
|
259
268
|
self.map do |str|
|
260
|
-
Mgmg::Equip.min_comp(str, opt:
|
269
|
+
Mgmg::Equip.min_comp(str, opt:)
|
261
270
|
end.append(-1).max
|
262
271
|
end
|
263
272
|
end
|
data/reference.md
CHANGED
@@ -19,23 +19,23 @@
|
|
19
19
|
|
20
20
|
`self`が解釈不能な場合,例外が発生します.また,製作Lvや完成品の☆制限のチェックを行っていないほか,本ライブラリでは`武器+防具`や`防具+武器`の合成も可能になっています.街の鍛冶・防具製作・道具製作屋に任せた場合をシミュレートする場合は製作Lvを負の値(`-1`など,負であれば何でもよい)にします(製作Lv0相当の性能を計算し,消費エレメント量は委託仕様となります).
|
21
21
|
|
22
|
-
`opt`は,`left_associative`のみ使用します.
|
22
|
+
`opt`は,`left_associative`と`include_system_equips`のみ使用します.
|
23
23
|
|
24
24
|
## `Enumerable#build(smith=-1, armor=smith, comp=armor.tap{armor=smith}, opt: Mgmg.option())`
|
25
25
|
複数のレシピ文字列からなる`self`の各要素を製作し,そのすべてを装備したときの`Mgmg::Equip`を返します.製作では`鍛冶Lv=smith`, `防具製作Lv=armor`, `道具製作Lv=comp`とします.1つしか指定しなければすべてそのLv,2つなら1つ目を`smith=armor`,2つ目を`comp`に,3つならそれぞれの値とします.製作Lvが負の場合,製作Lv0として計算した上で,消費エレメント量は街の製作屋に頼んだ場合の値を計算します.武器複数など,同時装備が不可能な場合でも,特にチェックはされません.
|
26
26
|
|
27
|
-
`opt`は,`left_associative`のみ使用します.
|
27
|
+
`opt`は,`left_associative`と`include_system_equips`のみ使用します.
|
28
28
|
|
29
29
|
## `String#min_weight(opt: Mgmg.option())`
|
30
30
|
製作可能な最小重量を返します.基本的には合成回数+1ですが,既製品を含む場合はその限りではありません.
|
31
31
|
|
32
|
-
|
32
|
+
`opt`は,`include_system_equips`のみ使用します.
|
33
33
|
|
34
34
|
## `String#max_weight(include_outsourcing=false, opt: Mgmg.option())`
|
35
35
|
製作可能な最大重量を返します.`include_outsourcing`が真の場合,委託製作時の重量を返します.
|
36
36
|
委託製作では,製作Lv0相当となるため,素材の☆による最低製作Lvで作るよりも重くなる場合があります.
|
37
37
|
|
38
|
-
|
38
|
+
`opt`は,`include_system_equips`のみ使用します.
|
39
39
|
|
40
40
|
## `String#min_level(w=0, include_outsourcing=false, opt: Mgmg.option())`
|
41
41
|
`self`を重量`w`以下で作るための最低製作Lvを返します.
|
@@ -60,12 +60,12 @@
|
|
60
60
|
## `Enumerable#min_levels(weight=1, opt: Mgmg.option())`
|
61
61
|
すべての要素`str`に対する`str.min_levels`をマージした`Hash`を返します.
|
62
62
|
|
63
|
-
|
63
|
+
`opt`は,`include_system_equips`のみ使用します.
|
64
64
|
|
65
65
|
## `Enumerable#min_levels_max(weight=1, opt: Mgmg.option())`
|
66
66
|
`self.min_levels`から武器,防具それぞれに対する最大値を求め,`[必要最小鍛冶Lv, 必要最小防具製作Lv]`を返します.武器,防具の一方のみが含まれる場合,もう一方は`-1`になります.
|
67
67
|
|
68
|
-
|
68
|
+
`opt`は,`include_system_equips`のみ使用します.
|
69
69
|
|
70
70
|
## `String#min_comp(opt: Mgmg.option())`,`Enumerable#min_comp(opt: Mgmg.option())`
|
71
71
|
レシピ通りに合成するのに必要な道具製作Lvを返します.ただし,全体が「[]」で囲われているか,非合成レシピの場合,代わりに`-1`を返します.
|
@@ -79,7 +79,7 @@
|
|
79
79
|
|
80
80
|
`Enumerable`の場合,すべての要素に対し,武器,防具それぞれの最大値を求め,`[必要最小鍛冶Lv, 必要最小防具製作Lv]`を返します.武器,防具の一方のみが含まれる場合,もう一方は`-1`になります.
|
81
81
|
|
82
|
-
|
82
|
+
`opt`は,`include_system_equips`のみ使用します.
|
83
83
|
|
84
84
|
## `String#poly(para=:cost, opt: Mgmg.option())`
|
85
85
|
レシピ文字列である`self`を解釈し,`para`で指定した9パラ値について,丸めを無視した鍛冶・防具製作Lvと道具製作Lvの2変数からなる多項式関数を示す`Mgmg::TPolynomial`クラスのインスタンスを生成し,返します.`para`は次のシンボルのいずれかを指定します.
|
@@ -96,17 +96,17 @@
|
|
96
96
|
|
97
97
|
また,`:cost`を渡すことで,消費エレメント量に関する近似多項式を得られます.`self`に`"+"`が含まれていれば合成品とみなし,最後の合成に必要な地エレメント量を,それ以外では,武器なら消費火エレメント量を,防具なら消費水エレメント量を返します.ただし,`self`が既成品そのものの場合,零多項式を返します.
|
98
98
|
|
99
|
-
`opt`は,`left_associative`のみ使用します.
|
99
|
+
`opt`は,`left_associative`と`include_system_equips`のみ使用します.
|
100
100
|
|
101
101
|
## `String#ir(opt: Mgmg.option())`
|
102
102
|
レシピ文字列である`self`を解釈し,9パラ値について,丸めを考慮した鍛冶・防具製作Lvと道具製作Lvの2変数からなる関数オブジェクトを保持する`Mgmg::IR`クラスのインスタンスを生成し,返します.詳しくは,[後述](#mgmgir)の`Mgmg::IR`クラスの説明を参照ください.
|
103
103
|
|
104
|
-
`opt`は,`left_associative`と`reinforcement`を使用します.
|
104
|
+
`opt`は,`left_associative`と`include_system_equips`,`reinforcement`を使用します.
|
105
105
|
|
106
106
|
## `Enumerable#ir(opt: Mgmg.option())`
|
107
107
|
複数のレシピ文字列からなる`self`の各要素を製作し,そのすべてを装備したときの`Mgmg::IR`を返します.この場合,鍛冶Lv,防具製作Lv,道具製作Lvの3変数からなる関数オブジェクトを保持するものとして扱われます.各装備の種別に応じ,鍛冶Lvまたは防具製作Lvを適用し,9パラ値を計算します.
|
108
108
|
|
109
|
-
`opt`は,`left_associative`と`reinforcement`を使用します.
|
109
|
+
`opt`は,`left_associative`と`include_system_equips`,`reinforcement`を使用します.
|
110
110
|
|
111
111
|
## `String#smith_seach(para, target, comp, opt: Mgmg.option())`
|
112
112
|
`para`の値が`target`以上となるのに必要な最小の鍛冶・防具製作Lvを二分探索で探索して返します.
|
@@ -441,21 +441,23 @@ alias として`*`があるほか`scalar(1.quo(value))`として`quo`,`/`,`s
|
|
441
441
|
## `Mgmg.#option(recipe=nil, **kw)`
|
442
442
|
`kw`はキーワード引数本体です.定義されているキーワードと意味,使用される主なメソッドは下表の通りです.デフォルト値は簡易的な表示であり,細かい点では不正確です.
|
443
443
|
`recipe`にレシピ`String`または`Enumerable`を渡すと,そのレシピを使ってデフォルト値を具体化しますが,各メソッドで自動的に具体化されるため,通常は必要ありません.
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
444
|
+
`Defaults`対応が「対応」となっているキーワード引数については,`Mgmg::Option::Defaults[:include_system_equips]=false`などとすることで,デフォルト値をグローバルに変更することができます.デフォルト値にかかわらず,メソッド呼び出し時に個別に指定すればその値が優先されます.
|
445
|
+
|
446
|
+
|キーワード|デフォルト値|`Defaults`対応|意味|主なメソッド,備考|
|
447
|
+
|:-|:-|:-|:-|:-|
|
448
|
+
|left_associative|`true`|対応|レシピ文字列を左結合で解釈する|`Mgmg::Option`を使用するすべてのメソッド|
|
449
|
+
|smith_min|`recipe.min_level(target_weight)`|非対応|鍛冶Lvに関する探索範囲の最小値|`String#search`など|
|
450
|
+
|armor_min|`recipe.min_level(*target_weight)[1]`|非対応|防具製作Lvに関する探索範囲の最小値|`Enumerable#search`など.`String`系では代わりに`smith_min`を使う|
|
451
|
+
|comp_min|`recipe.min_comp`|非対応|道具製作Lvに関する探索範囲の最小値|`String#search`など|
|
452
|
+
|smith_max, armor_max, comp_max|`10000`|対応|各製作Lvの探索範囲の最大値|`String#search`など|
|
453
|
+
|target_weight|`0`|非対応|`smith_min`のデフォルト値計算に使う目標重量|`String#search`など|
|
454
|
+
|step|`1`|非対応|探索時において道具製作Lvを動かす幅|`String#search`など|
|
455
|
+
|magdef_maximize|`true`|非対応|目標を魔防最大(真)かコスト最小(偽)にするためのスイッチ|`String#phydef_optimize`|
|
456
|
+
|reinforcement|`[]`|非対応|[前述](#mgmgequipreinforcearg)の`Mgmg::Equip#reinforce`による強化リスト|一部を除くすべてのメソッド|
|
457
|
+
|buff|`[]`|非対応|`reinforcement`のエイリアス|どちらか一方のみを指定する|
|
458
|
+
|irep|`recipe.ir()`|非対応|`Mgmg::IR`の使い回しによる高速化|`String#search`など,内部的に使用|
|
459
|
+
|cut_exp|`Float::INFINITY`|非対応|探索時の総経験値の打ち切り値|`String#search`など,内部的に使用|
|
460
|
+
|include_system_equips|`true`|対応|レシピ解釈時に,既製品を受け付ける|`Mgmg::Option`を使用するすべてのメソッド|
|
459
461
|
|
460
462
|
## `Mgmg::Recipe`
|
461
463
|
レシピ文字列,注目パラメータ,オプションをセットにして扱うためのクラスです.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mgmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- KAZOON
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|