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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3f377aff6ac79ec7111b1b81fcfc5148505ca5f57606be79192f832d80d7c92
|
4
|
+
data.tar.gz: 3cca84c8c97b44f18945d1817a921d42b7702f77a61dff4e8836a52f1a9a0f14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76db175b332d5c5d69ab12f171b734ceb82d4102151b19ce17e710e4776acaabe5e706f0b830eef251a664ae2d702b92d504af6409441da164dd64be1736a19f
|
7
|
+
data.tar.gz: aa9416fcbaca9dc1d631925c4b5b3eb946196d81aab90748567c3c638adba12bf6474a70f1c815806527afe334cad434d841ce19e22350816df443e4c485fbdc
|
data/CHANGELOG.md
CHANGED
@@ -138,3 +138,17 @@
|
|
138
138
|
- `Mgmg::Recipe#build`,`Mgmg::Recipe#search`など`String`等に対する操作と同様にでき,注目パラメータとオプションは,`to_recipe`でセットしたものがデフォルトで使われるようになる.各メソッド呼び出し時にキーワード引数を与えることで,一時的に上書きすることもできる.
|
139
139
|
- `String#to_recipe`にのみ,☆20制限のチェック機構を導入した.
|
140
140
|
- 計算を繰り返した際,複数装備の装備数が増加していってしまうバグを修正した.
|
141
|
+
|
142
|
+
## 1.5.2 2022/06/28
|
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`を追加.
|
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,203 @@ 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
|
-
def min_comp(str, opt: Option.new)
|
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
|
+
return CacheML[str] if CacheML.has_key?(str)
|
313
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
314
|
+
raise InvalidSmithError.new(str)
|
330
315
|
end
|
316
|
+
kind = EquipIndex[m[1].to_sym]
|
317
|
+
main_m, main_s, = Mgmg.parse_material(m[2])
|
318
|
+
sub_m, sub_s, = Mgmg.parse_material(m[3])
|
319
|
+
|
320
|
+
q, r = ((weight+1)*10000).divmod(MainWeight[main_m])
|
321
|
+
l = ( EquipWeight[kind] + SubWeight[sub_m] - q + ( r==0 ? 1 : 0 ) )*2
|
322
|
+
ret = [(main_s-1)*3, (sub_s-1)*3, l].max
|
323
|
+
CacheML.store(str, ret)
|
324
|
+
ret
|
331
325
|
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]
|
326
|
+
|
327
|
+
def min_comp(str, opt: Option.new)
|
328
|
+
str = Mgmg.check_string(str)
|
329
|
+
stack = []
|
330
|
+
stack, str = minc_sub0(stack, str) if opt.include_system_equips
|
331
|
+
(minc_sub(stack, str, opt.left_associative)[1]-1)*3
|
346
332
|
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}>")
|
333
|
+
private def minc_sub0(stack, str)
|
334
|
+
SystemEquip.each do |k, v|
|
335
|
+
if SystemEquipRegexp[k].match(str)
|
336
|
+
stack << v.star
|
337
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
338
|
+
end
|
360
339
|
end
|
340
|
+
[stack, str]
|
361
341
|
end
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
342
|
+
private def minc_sub(stack, str, lassoc)
|
343
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
344
|
+
stack << minc_sub(stack, m[2], lassoc)[0]
|
345
|
+
minc_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
346
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
347
|
+
a, _ = minc_sub(stack, m[1], lassoc)
|
348
|
+
b, _ = minc_sub(stack, m[2], lassoc)
|
349
|
+
[a+b, [a, b].max]
|
350
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
351
|
+
[stack[m[1].to_i], 1]
|
352
|
+
else
|
353
|
+
[smith(str, 0, true).star, 1]
|
354
|
+
end
|
374
355
|
end
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
356
|
+
|
357
|
+
def min_smith(str, opt: Option.new)
|
358
|
+
str = Mgmg.check_string(str)
|
359
|
+
stack = []
|
360
|
+
stack, str = mins_sub0(stack, str) if opt.include_system_equips
|
361
|
+
ret = (([mins_sub(stack, str, opt.left_associative)]+stack).max-1)*3
|
362
|
+
ret < 0 ? -1 : ret
|
380
363
|
end
|
381
|
-
|
382
|
-
|
383
|
-
|
364
|
+
private def mins_sub0(stack, str)
|
365
|
+
SystemEquip.each do |k, v|
|
366
|
+
if SystemEquipRegexp[k].match(str)
|
367
|
+
stack << 0
|
368
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
369
|
+
end
|
370
|
+
end
|
371
|
+
[stack, str]
|
372
|
+
end
|
373
|
+
private def mins_sub(stack, str, lassoc)
|
374
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
375
|
+
stack << mins_sub(stack, m[2], lassoc)
|
376
|
+
mins_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
377
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
378
|
+
[mins_sub(stack, m[1], lassoc), mins_sub(stack, m[2], lassoc)].max
|
379
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
380
|
+
0
|
381
|
+
else
|
382
|
+
mins_sub2(str)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
private def mins_sub2(str)
|
386
|
+
str = Mgmg.check_string(str)
|
387
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
388
|
+
raise InvalidSmithError.new(str)
|
389
|
+
end
|
390
|
+
kind = EquipIndex[m[1].to_sym]
|
391
|
+
unless kind
|
392
|
+
raise InvalidEquipClassError.new(m[1])
|
393
|
+
end
|
394
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
395
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
396
|
+
[main_s, sub_s].max
|
384
397
|
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
398
|
end
|
389
399
|
end
|
390
400
|
end
|