mgmg 1.5.2 → 1.5.5
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 +15 -0
- data/lib/mgmg/cuisine.rb +49 -49
- data/lib/mgmg/equip.rb +182 -171
- data/lib/mgmg/ir.rb +114 -108
- data/lib/mgmg/option.rb +28 -4
- data/lib/mgmg/poly.rb +68 -61
- data/lib/mgmg/recipe.rb +1 -1
- data/lib/mgmg/reinforce.rb +34 -35
- data/lib/mgmg/search.rb +2 -2
- data/lib/mgmg/utils.rb +3 -4
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +11 -4
- data/reference.md +27 -25
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcdae95e0d1ee5dc8d65fe012d739a896b5be27e2a68ff5a2619477461e2e9d7
|
4
|
+
data.tar.gz: 2a2976e6c36a2cd2c3c6bc7c6e829f7e78e2791d18bc087188b369db7ecacb17
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d40a50cc4cde3a115d7d9f27a93945a27f4b77ece5091917d30cf32675679f6ae52290163168cd5d8c3cf57ded10f29bbb3a6fc803e67d209c35cf8c949f3912
|
7
|
+
data.tar.gz: 27f15eef233a9f19a92bca31d4b4683e78fb1207768fd7b8cbc7cc2aab8d6d79c23ac3db93237a0e8b508dfaa4f50da745f001de50ce74bf5d34824ee3909dc6
|
data/CHANGELOG.md
CHANGED
@@ -141,3 +141,18 @@
|
|
141
141
|
|
142
142
|
## 1.5.2 2022/06/28
|
143
143
|
- `String#poly`が`:magic2`に対応していなかったバグを修正.
|
144
|
+
|
145
|
+
## 1.5.3 2022/06/28
|
146
|
+
- `Recipe#option`がキーワード引数を受け取れなかったバグを修正.
|
147
|
+
|
148
|
+
## 1.5.4 2022/06/30
|
149
|
+
- 既製品の探索を制御する`:include_system_equips`オプションを追加.
|
150
|
+
- 既製品を含まないレシピを計算するとき,これを偽に設定することで,高速化される.
|
151
|
+
- デフォルト値は`true`.ただし,既製品を含まないレシピ文字列を`to_recipe`すると,自動的に`false`に書き換える.
|
152
|
+
- 一部のメソッドで計算結果をキャッシュすることで,同じ材料装備を含む大量のレシピを計算する場合に高速化された.
|
153
|
+
- `Mgmg.#clear_cache`ですべてのキャッシュをクリアできる.
|
154
|
+
- 一部のオプションのデフォルト値をグローバルに変更するための定数ハッシュ`Mgmg::Option::Defaults`を追加.
|
155
|
+
|
156
|
+
## 1.5.5 2022/07/02
|
157
|
+
- `Enumerable#to_recipe`が動かなくなったバグを修正.
|
158
|
+
- `String#min_level`において,正しい答えを返さなくなったバグを修正.
|
data/lib/mgmg/cuisine.rb
CHANGED
@@ -22,6 +22,55 @@ module Mgmg
|
|
22
22
|
"料理[攻撃:#{self.attack}, 物防:#{self.phydef}, 魔防:#{self.magdef}]"
|
23
23
|
end
|
24
24
|
alias :inspect :to_s
|
25
|
+
|
26
|
+
MainFood = {
|
27
|
+
'獣肉' => Vec[10, 0, 0],
|
28
|
+
'ウッチ' => Vec[ 0, 10, 10],
|
29
|
+
'ゴッチ' => Vec[ 0, 12, 12],
|
30
|
+
'ガガッチ' => Vec[ 0, 14, 14],
|
31
|
+
'ドランギョ' => Vec[15, 15, 10],
|
32
|
+
'ドラバーン' => Vec[20, 20, 15],
|
33
|
+
'フレドラン' => Vec[50, 0, 0],
|
34
|
+
'アースドラン' => Vec[ 0, 50, 0],
|
35
|
+
'アクアドラン' => Vec[ 0, 0, 50],
|
36
|
+
'ダークドン' => Vec[30, 30, 30],
|
37
|
+
}
|
38
|
+
SubFood = {
|
39
|
+
'氷酒' => Vec[ 50, 70, 50],
|
40
|
+
'氷水酒' => Vec[ 50, 90, 50],
|
41
|
+
'氷河酒' => Vec[ 50, 110, 50],
|
42
|
+
'カエン酒' => Vec[ 70, 50, 70],
|
43
|
+
'爆炎酒' => Vec[ 90, 50, 90],
|
44
|
+
'煉獄酒' => Vec[110, 50, 110],
|
45
|
+
}
|
46
|
+
Cookery = {
|
47
|
+
'焼き' => Vec[50, 50, 30],
|
48
|
+
'蒸す' => Vec[30, 75, 75],
|
49
|
+
}
|
50
|
+
Cookery.store('丸焼き', Cookery['焼き'])
|
51
|
+
Cookery.store('すき焼き', Cookery['焼き'])
|
52
|
+
Cookery.store('焼く', Cookery['焼き'])
|
53
|
+
Cookery.store('焼', Cookery['焼き'])
|
54
|
+
Cookery.store('蒸し焼き', Cookery['蒸す'])
|
55
|
+
Cookery.store('ボイル', Cookery['蒸す'])
|
56
|
+
Cookery.store('蒸し', Cookery['蒸す'])
|
57
|
+
Cookery.store('蒸', Cookery['蒸す'])
|
58
|
+
|
59
|
+
class << self
|
60
|
+
def cook(cookery_s, main_s, sub_s, level)
|
61
|
+
begin
|
62
|
+
c = Cookery[cookery_s]
|
63
|
+
m = MainFood[main_s]
|
64
|
+
s = SubFood[sub_s]
|
65
|
+
v = Vec[1, 1, 1]
|
66
|
+
v.e_mul!(m).e_mul!(c).e_mul!(s.dup.add!(100+level)).e_div!(10000)
|
67
|
+
new(v)
|
68
|
+
rescue
|
69
|
+
arg = [cookery_s, main_s, sub_s, level].inspect
|
70
|
+
raise ArgumentError, "Some of arguments for cooking seems to be wrong. #{arg} is given, but they should be [cookery (String), main food (String), sub food (String), cooking level (Integer)]. Not all of cookeries and foods are supported."
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
25
74
|
end
|
26
75
|
|
27
76
|
SystemCuisine = {
|
@@ -72,55 +121,6 @@ module Mgmg
|
|
72
121
|
end
|
73
122
|
end
|
74
123
|
|
75
|
-
MainFood = {
|
76
|
-
'獣肉' => Vec[10, 0, 0],
|
77
|
-
'ウッチ' => Vec[ 0, 10, 10],
|
78
|
-
'ゴッチ' => Vec[ 0, 12, 12],
|
79
|
-
'ガガッチ' => Vec[ 0, 14, 14],
|
80
|
-
'ドランギョ' => Vec[15, 15, 10],
|
81
|
-
'ドラバーン' => Vec[20, 20, 15],
|
82
|
-
'フレドラン' => Vec[50, 0, 0],
|
83
|
-
'アースドラン' => Vec[ 0, 50, 0],
|
84
|
-
'アクアドラン' => Vec[ 0, 0, 50],
|
85
|
-
'ダークドン' => Vec[30, 30, 30],
|
86
|
-
}
|
87
|
-
SubFood = {
|
88
|
-
'氷酒' => Vec[ 50, 70, 50],
|
89
|
-
'氷水酒' => Vec[ 50, 90, 50],
|
90
|
-
'氷河酒' => Vec[ 50, 110, 50],
|
91
|
-
'カエン酒' => Vec[ 70, 50, 70],
|
92
|
-
'爆炎酒' => Vec[ 90, 50, 90],
|
93
|
-
'煉獄酒' => Vec[110, 50, 110],
|
94
|
-
}
|
95
|
-
Cookery = {
|
96
|
-
'焼き' => Vec[50, 50, 30],
|
97
|
-
'蒸す' => Vec[30, 75, 75],
|
98
|
-
}
|
99
|
-
Cookery.store('丸焼き', Cookery['焼き'])
|
100
|
-
Cookery.store('すき焼き', Cookery['焼き'])
|
101
|
-
Cookery.store('焼く', Cookery['焼き'])
|
102
|
-
Cookery.store('焼', Cookery['焼き'])
|
103
|
-
Cookery.store('蒸し焼き', Cookery['蒸す'])
|
104
|
-
Cookery.store('ボイル', Cookery['蒸す'])
|
105
|
-
Cookery.store('蒸し', Cookery['蒸す'])
|
106
|
-
Cookery.store('蒸', Cookery['蒸す'])
|
107
|
-
|
108
|
-
class << Cuisine
|
109
|
-
def cook(cookery_s, main_s, sub_s, level)
|
110
|
-
begin
|
111
|
-
c = Cookery[cookery_s]
|
112
|
-
m = MainFood[main_s]
|
113
|
-
s = SubFood[sub_s]
|
114
|
-
v = Vec[1, 1, 1]
|
115
|
-
v.e_mul!(m).e_mul!(c).e_mul!(s.dup.add!(100+level)).e_div!(10000)
|
116
|
-
new(v)
|
117
|
-
rescue
|
118
|
-
arg = [cookery_s, main_s, sub_s, level].inspect
|
119
|
-
raise ArgumentError, "Some of arguments for cooking seems to be wrong. #{arg} is given, but they should be [cookery (String), main food (String), sub food (String), cooking level (Integer)]. Not all of cookeries and foods are supported."
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
124
|
module_function def cuisine(*arg)
|
125
125
|
case arg.size
|
126
126
|
when 3
|
data/lib/mgmg/equip.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Mgmg
|
2
|
+
CacheMLS = Hash.new
|
2
3
|
using Refiner
|
3
4
|
class Equip
|
5
|
+
Cache, CacheML = Hash.new, Hash.new
|
4
6
|
ParamList = %w|攻撃 物防 魔防 HP MP 腕力 器用 素早 魔力|
|
5
7
|
ElementList = %w|火 地 水|
|
6
8
|
EqPosList = %w|武 頭 胴 腕 足 飾|
|
@@ -196,195 +198,204 @@ module Mgmg
|
|
196
198
|
Zero = self.new(28, 0, Vec.new(6, 0).freeze, 12, 12, Vec.new(9, 0).freeze, Vec.new(3, 0).freeze)
|
197
199
|
Zero.total_cost.freeze; Zero.history.clear.freeze
|
198
200
|
Zero.freeze
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
end
|
207
|
-
private def build_sub0(stack, str)
|
208
|
-
SystemEquip.each do |k, v|
|
209
|
-
if SystemEquipRegexp[k].match(str)
|
210
|
-
stack << v
|
211
|
-
str = str.gsub(k, "<#{stack.length-1}>")
|
212
|
-
end
|
201
|
+
|
202
|
+
class << self
|
203
|
+
def build(str, s_level, c_level, left_associative: true, include_system_equips: true)
|
204
|
+
str = Mgmg.check_string(str)
|
205
|
+
stack = []
|
206
|
+
stack, str = build_sub0(stack, str) if include_system_equips
|
207
|
+
build_sub(stack, str, s_level, c_level, left_associative)
|
213
208
|
end
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
221
|
-
if c_level < 0
|
222
|
-
compose(build_sub(stack, m[1], s_level, c_level, lassoc), build_sub(stack, m[2], s_level, c_level, lassoc), 0, true)
|
223
|
-
else
|
224
|
-
compose(build_sub(stack, m[1], s_level, c_level, lassoc), build_sub(stack, m[2], s_level, c_level, lassoc), c_level, false)
|
209
|
+
private def build_sub0(stack, str)
|
210
|
+
SystemEquip.each do |k, v|
|
211
|
+
if SystemEquipRegexp[k].match(str)
|
212
|
+
stack << v
|
213
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
214
|
+
end
|
225
215
|
end
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
if
|
230
|
-
|
216
|
+
[stack, str]
|
217
|
+
end
|
218
|
+
private def build_sub(stack, str, s_level, c_level, lassoc)
|
219
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
220
|
+
stack << build_sub(stack, m[2], s_level, c_level, lassoc)
|
221
|
+
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", s_level, c_level, lassoc)
|
222
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
223
|
+
if c_level < 0
|
224
|
+
compose(build_sub(stack, m[1], s_level, c_level, lassoc), build_sub(stack, m[2], s_level, c_level, lassoc), 0, true)
|
225
|
+
else
|
226
|
+
compose(build_sub(stack, m[1], s_level, c_level, lassoc), build_sub(stack, m[2], s_level, c_level, lassoc), c_level, false)
|
227
|
+
end
|
228
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
229
|
+
stack[m[1].to_i]
|
231
230
|
else
|
232
|
-
|
231
|
+
if s_level < 0
|
232
|
+
smith(str, 0, true)
|
233
|
+
else
|
234
|
+
smith(str, s_level, false)
|
235
|
+
end
|
233
236
|
end
|
234
237
|
end
|
235
|
-
end
|
236
|
-
|
237
|
-
def compose(main, sub, level, outsourcing)
|
238
|
-
main_k, sub_k = main.kind, sub.kind
|
239
|
-
main_s, sub_s = main.star, sub.star
|
240
|
-
main_main, sub_main = main.main, sub.main
|
241
|
-
main_sub, sub_sub = main.sub, sub.sub
|
242
|
-
para = Vec.new(9, 0)
|
243
|
-
ele = Vec.new(3, 0)
|
244
|
-
|
245
|
-
# 9パラメータ
|
246
|
-
coef = Equip9[main_k].dup
|
247
|
-
para[] = coef
|
248
|
-
para.add!(level).e_div!(2)
|
249
|
-
para.e_mul!(sub.para).e_div!(100)
|
250
|
-
coef.sub!(Equip9[sub_k])
|
251
|
-
coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
|
252
|
-
coef.add!(Material9[main_main]).sub!(Material9[sub_main])
|
253
|
-
coef.e_mul!(EquipFilter[main_k])
|
254
|
-
para.e_mul!(coef).e_div!( main_k==sub_k ? 200 : 100 )
|
255
|
-
para.add!(main.para)
|
256
238
|
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
239
|
+
def compose(main, sub, level, outsourcing)
|
240
|
+
main_k, sub_k = main.kind, sub.kind
|
241
|
+
main_s, sub_s = main.star, sub.star
|
242
|
+
main_main, sub_main = main.main, sub.main
|
243
|
+
main_sub, sub_sub = main.sub, sub.sub
|
244
|
+
para = Vec.new(9, 0)
|
245
|
+
ele = Vec.new(3, 0)
|
246
|
+
|
247
|
+
# 9パラメータ
|
248
|
+
coef = Equip9[main_k].dup
|
249
|
+
para[] = coef
|
250
|
+
para.add!(level).e_div!(2)
|
251
|
+
para.e_mul!(sub.para).e_div!(100)
|
252
|
+
coef.sub!(Equip9[sub_k])
|
253
|
+
coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
|
254
|
+
coef.add!(Material9[main_main]).sub!(Material9[sub_main])
|
255
|
+
coef.e_mul!(EquipFilter[main_k])
|
256
|
+
para.e_mul!(coef).e_div!( main_k==sub_k ? 200 : 100 )
|
257
|
+
para.add!(main.para)
|
258
|
+
|
259
|
+
# エレメント
|
260
|
+
ele[] = sub.element
|
261
|
+
ele.e_mul!([75, level].min).e_div!( main_k==sub_k ? 200 : 100 )
|
262
|
+
ele.add!(main.element)
|
263
|
+
|
264
|
+
ret = new(main_k, main.weight+sub.weight, main_s+sub_s, main_sub, sub_main, para, ele)
|
265
|
+
ret.total_cost.add!(main.total_cost).add!(sub.total_cost)
|
266
|
+
cc = ret.comp_cost(outsourcing)
|
267
|
+
ret.total_cost[1] += cc
|
268
|
+
ret.total_cost[main_k < 8 ? 0 : 2] += cc
|
269
|
+
ret.min_levels.merge!(main.min_levels, sub.min_levels)
|
270
|
+
ret.history = [*main.history, *sub.history, ret]
|
271
|
+
ret
|
280
272
|
end
|
281
|
-
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
282
|
-
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
283
|
-
para = Vec.new(9, 0)
|
284
|
-
ele = Vec.new(3, 0)
|
285
273
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
274
|
+
def smith(str, level, outsourcing)
|
275
|
+
str = Mgmg.check_string(str)
|
276
|
+
return Cache[str].dup if level==0 && Cache.has_key?(str)
|
277
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
278
|
+
raise InvalidSmithError.new(str)
|
279
|
+
end
|
280
|
+
kind = EquipIndex[m[1].to_sym]
|
281
|
+
unless kind
|
282
|
+
raise InvalidEquipClassError.new(m[1])
|
283
|
+
end
|
284
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
285
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
286
|
+
para = Vec.new(9, 0)
|
287
|
+
ele = Vec.new(3, 0)
|
288
|
+
|
289
|
+
# 9パラメータ
|
290
|
+
para[] = Equip9[kind]
|
291
|
+
para.e_mul!(Main9[main_m]).e_div!(100)
|
292
|
+
coef = Sub9[sub_m].dup
|
293
|
+
coef.add!(level)
|
294
|
+
para.e_mul!(coef).e_div!( main_mc==sub_mc ? 200 : 100 )
|
295
|
+
|
296
|
+
# エレメント
|
297
|
+
ele[] = MainEL[main_m]
|
298
|
+
ele.e_mul!(SubEL[sub_m]).e_div!(6)
|
299
|
+
|
300
|
+
# 重量
|
301
|
+
weight = ( ( EquipWeight[kind] + SubWeight[sub_m] - level.div(2) ) * ( MainWeight[main_m] ) ).div(10000)
|
302
|
+
|
303
|
+
ret = new(kind, ( weight<1 ? 1 : weight ), (main_s+sub_s).div(2), main_mc, sub_mc, para, ele)
|
304
|
+
ret.total_cost[kind < 8 ? 0 : 2] += ret.smith_cost(outsourcing)
|
305
|
+
ret.min_levels.store(str, Equip.min_level(str))
|
306
|
+
Cache.store(str, ret.freeze) if level==0
|
307
|
+
ret.dup
|
310
308
|
end
|
311
|
-
kind = EquipIndex[m[1].to_sym]
|
312
|
-
main_m, main_s, = Mgmg.parse_material(m[2])
|
313
|
-
sub_m, sub_s, = Mgmg.parse_material(m[3])
|
314
309
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
str = Mgmg.check_string(str)
|
322
|
-
stack, str = minc_sub0([], str)
|
323
|
-
(minc_sub(stack, str, opt.left_associative)[1]-1)*3
|
324
|
-
end
|
325
|
-
private def minc_sub0(stack, str)
|
326
|
-
SystemEquip.each do |k, v|
|
327
|
-
if SystemEquipRegexp[k].match(str)
|
328
|
-
stack << v.star
|
329
|
-
str = str.gsub(k, "<#{stack.length-1}>")
|
310
|
+
def min_level(str, weight=1)
|
311
|
+
str = Mgmg.check_string(str)
|
312
|
+
key = [str.dup.freeze, weight].freeze
|
313
|
+
return CacheML[key] if CacheML.has_key?(key)
|
314
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
315
|
+
raise InvalidSmithError.new(str)
|
330
316
|
end
|
317
|
+
kind = EquipIndex[m[1].to_sym]
|
318
|
+
main_m, main_s, = Mgmg.parse_material(m[2])
|
319
|
+
sub_m, sub_s, = Mgmg.parse_material(m[3])
|
320
|
+
|
321
|
+
q, r = ((weight+1)*10000).divmod(MainWeight[main_m])
|
322
|
+
l = ( EquipWeight[kind] + SubWeight[sub_m] - q + ( r==0 ? 1 : 0 ) )*2
|
323
|
+
ret = [(main_s-1)*3, (sub_s-1)*3, l].max
|
324
|
+
CacheML.store(key, ret)
|
325
|
+
ret
|
331
326
|
end
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
stack
|
337
|
-
minc_sub(stack,
|
338
|
-
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
339
|
-
a, _ = minc_sub(stack, m[1], lassoc)
|
340
|
-
b, _ = minc_sub(stack, m[2], lassoc)
|
341
|
-
[a+b, [a, b].max]
|
342
|
-
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
343
|
-
[stack[m[1].to_i], 1]
|
344
|
-
else
|
345
|
-
[smith(str, 0, true).star, 1]
|
327
|
+
|
328
|
+
def min_comp(str, opt: Option.new)
|
329
|
+
str = Mgmg.check_string(str)
|
330
|
+
stack = []
|
331
|
+
stack, str = minc_sub0(stack, str) if opt.include_system_equips
|
332
|
+
(minc_sub(stack, str, opt.left_associative)[1]-1)*3
|
346
333
|
end
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
ret < 0 ? -1 : ret
|
354
|
-
end
|
355
|
-
private def mins_sub0(stack, str)
|
356
|
-
SystemEquip.each do |k, v|
|
357
|
-
if SystemEquipRegexp[k].match(str)
|
358
|
-
stack << 0
|
359
|
-
str = str.gsub(k, "<#{stack.length-1}>")
|
334
|
+
private def minc_sub0(stack, str)
|
335
|
+
SystemEquip.each do |k, v|
|
336
|
+
if SystemEquipRegexp[k].match(str)
|
337
|
+
stack << v.star
|
338
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
339
|
+
end
|
360
340
|
end
|
341
|
+
[stack, str]
|
361
342
|
end
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
343
|
+
private def minc_sub(stack, str, lassoc)
|
344
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
345
|
+
stack << minc_sub(stack, m[2], lassoc)[0]
|
346
|
+
minc_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
347
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
348
|
+
a, _ = minc_sub(stack, m[1], lassoc)
|
349
|
+
b, _ = minc_sub(stack, m[2], lassoc)
|
350
|
+
[a+b, [a, b].max]
|
351
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
352
|
+
[stack[m[1].to_i], 1]
|
353
|
+
else
|
354
|
+
[smith(str, 0, true).star, 1]
|
355
|
+
end
|
374
356
|
end
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
357
|
+
|
358
|
+
def min_smith(str, opt: Option.new)
|
359
|
+
str = Mgmg.check_string(str)
|
360
|
+
stack = []
|
361
|
+
stack, str = mins_sub0(stack, str) if opt.include_system_equips
|
362
|
+
ret = (([mins_sub(stack, str, opt.left_associative)]+stack).max-1)*3
|
363
|
+
ret < 0 ? -1 : ret
|
380
364
|
end
|
381
|
-
|
382
|
-
|
383
|
-
|
365
|
+
private def mins_sub0(stack, str)
|
366
|
+
SystemEquip.each do |k, v|
|
367
|
+
if SystemEquipRegexp[k].match(str)
|
368
|
+
stack << 0
|
369
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
370
|
+
end
|
371
|
+
end
|
372
|
+
[stack, str]
|
373
|
+
end
|
374
|
+
private def mins_sub(stack, str, lassoc)
|
375
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
376
|
+
stack << mins_sub(stack, m[2], lassoc)
|
377
|
+
mins_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
378
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
379
|
+
[mins_sub(stack, m[1], lassoc), mins_sub(stack, m[2], lassoc)].max
|
380
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
381
|
+
0
|
382
|
+
else
|
383
|
+
mins_sub2(str)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
private def mins_sub2(str)
|
387
|
+
str = Mgmg.check_string(str)
|
388
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
389
|
+
raise InvalidSmithError.new(str)
|
390
|
+
end
|
391
|
+
kind = EquipIndex[m[1].to_sym]
|
392
|
+
unless kind
|
393
|
+
raise InvalidEquipClassError.new(m[1])
|
394
|
+
end
|
395
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
396
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
397
|
+
[main_s, sub_s].max
|
384
398
|
end
|
385
|
-
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
386
|
-
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
387
|
-
[main_s, sub_s].max
|
388
399
|
end
|
389
400
|
end
|
390
401
|
end
|