mgmg 1.4.0 → 1.5.0

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.
data/lib/mgmg/equip.rb CHANGED
@@ -9,7 +9,7 @@ module Mgmg
9
9
  @total_cost = Vec[0, 0, 0]
10
10
  @history, @min_levels = [self], Hash.new
11
11
  end
12
- attr_accessor :kind, :weight, :star, :main, :sub, :para, :element, :total_cost, :history, :min_levels
12
+ attr_accessor :kind, :weight, :star, :main, :sub, :para, :element, :total_cost, :history
13
13
  def initialize_copy(other)
14
14
  @kind = other.kind
15
15
  @weight = other.weight
@@ -52,11 +52,20 @@ module Mgmg
52
52
  end
53
53
  end
54
54
 
55
- def min_level
55
+ def min_levels(w=1)
56
+ if w == 1
57
+ @min_levels
58
+ else
59
+ @min_levels.map do |key, value|
60
+ [key, Equip.min_level(key, w)]
61
+ end.to_h
62
+ end
63
+ end
64
+ def min_levels_max(w=1)
56
65
  if @kind == 28
57
- ret = [0, 0]
58
- @min_levels.each do |str, ml|
59
- if str.build(-1).kind < 8
66
+ ret = [-1, -1]
67
+ min_levels(w).each do |str, ml|
68
+ if str.build.kind < 8
60
69
  if ret[0] < ml
61
70
  ret[0] = ml
62
71
  end
@@ -68,7 +77,7 @@ module Mgmg
68
77
  end
69
78
  ret
70
79
  else
71
- @min_levels.values.append(0).max
80
+ min_levels(w).values.append(-1).max
72
81
  end
73
82
  end
74
83
 
@@ -91,6 +100,9 @@ module Mgmg
91
100
  def mag_das
92
101
  magic()+dex_as().quo(2)
93
102
  end
103
+ def magic2
104
+ magic()*2
105
+ end
94
106
  [:fire, :earth, :water].each.with_index do |s, i|
95
107
  define_method(s){ @element[i] }
96
108
  end
@@ -181,15 +193,9 @@ module Mgmg
181
193
  def +(other)
182
194
  self.dup.add!(other)
183
195
  end
184
- def coerce(other)
185
- if other == 0
186
- zero = self.class.new(28, 0, Vec.new(6, 0), 12, 12, Vec.new(9, 0), Vec.new(3, 0))
187
- zero.history.clear
188
- [zero, self]
189
- else
190
- raise TypeError, "Mgmg::Equip can't be coerced into other than 0"
191
- end
192
- end
196
+ Zero = self.new(28, 0, Vec.new(6, 0), 12, 12, Vec.new(9, 0), Vec.new(3, 0))
197
+ Zero.history.clear
198
+ Zero.freeze
193
199
  end
194
200
 
195
201
  class << Equip
@@ -200,7 +206,7 @@ module Mgmg
200
206
  end
201
207
  private def build_sub0(stack, str)
202
208
  SystemEquip.each do |k, v|
203
- if Regexp.compile(k).match(str)
209
+ if SystemEquipRegexp[k].match(str)
204
210
  stack << v
205
211
  str = str.gsub(k, "<#{stack.length-1}>")
206
212
  end
@@ -272,8 +278,8 @@ module Mgmg
272
278
  unless kind
273
279
  raise InvalidEquipClassError.new(m[1])
274
280
  end
275
- main_m, main_s, main_mc = parse_material(m[2])
276
- sub_m, sub_s, sub_mc = parse_material(m[3])
281
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
282
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
277
283
  para = Vec.new(9, 0)
278
284
  ele = Vec.new(3, 0)
279
285
 
@@ -293,7 +299,7 @@ module Mgmg
293
299
 
294
300
  ret = new(kind, ( weight<1 ? 1 : weight ), (main_s+sub_s).div(2), main_mc, sub_mc, para, ele)
295
301
  ret.total_cost[kind < 8 ? 0 : 2] += ret.smith_cost(outsourcing)
296
- ret.min_levels.store(str, str.min_level)
302
+ ret.min_levels.store(str, Equip.min_level(str))
297
303
  ret
298
304
  end
299
305
 
@@ -303,31 +309,22 @@ module Mgmg
303
309
  raise InvalidSmithError.new(str)
304
310
  end
305
311
  kind = EquipIndex[m[1].to_sym]
306
- main_m, main_s, = parse_material(m[2])
307
- sub_m, sub_s, = parse_material(m[3])
312
+ main_m, main_s, = Mgmg.parse_material(m[2])
313
+ sub_m, sub_s, = Mgmg.parse_material(m[3])
308
314
 
309
315
  q, r = ((weight+1)*10000).divmod(MainWeight[main_m])
310
316
  l = ( EquipWeight[kind] + SubWeight[sub_m] - q + ( r==0 ? 1 : 0 ) )*2
311
317
  [(main_s-1)*3, (sub_s-1)*3, l].max
312
318
  end
313
319
 
314
- private def parse_material(str)
315
- m = /\A.+?(\d+)\Z/.match(str)
316
- mat = MaterialIndex[str.to_sym]
317
- if m.nil? || mat.nil?
318
- raise InvalidMaterialError.new(str)
319
- end
320
- [mat, m[1].to_i, mat<90 ? mat.div(10) : 9]
321
- end
322
-
323
- def min_comp(str, left_associative: true)
320
+ def min_comp(str, opt: Option.new)
324
321
  str = Mgmg.check_string(str)
325
322
  stack, str = minc_sub0([], str)
326
- (minc_sub(stack, str, left_associative)[1]-1)*3
323
+ (minc_sub(stack, str, opt.left_associative)[1]-1)*3
327
324
  end
328
325
  private def minc_sub0(stack, str)
329
326
  SystemEquip.each do |k, v|
330
- if Regexp.compile(k).match(str)
327
+ if SystemEquipRegexp[k].match(str)
331
328
  stack << v.star
332
329
  str = str.gsub(k, "<#{stack.length-1}>")
333
330
  end
@@ -349,14 +346,15 @@ module Mgmg
349
346
  end
350
347
  end
351
348
 
352
- def min_smith(str, left_associative: true)
349
+ def min_smith(str, opt: Option.new)
353
350
  str = Mgmg.check_string(str)
354
351
  stack, str = mins_sub0([], str)
355
- (([mins_sub(stack, str, left_associative)]+stack).max-1)*3
352
+ ret = (([mins_sub(stack, str, opt.left_associative)]+stack).max-1)*3
353
+ ret < 0 ? -1 : ret
356
354
  end
357
355
  private def mins_sub0(stack, str)
358
356
  SystemEquip.each do |k, v|
359
- if Regexp.compile(k).match(str)
357
+ if SystemEquipRegexp[k].match(str)
360
358
  stack << 0
361
359
  str = str.gsub(k, "<#{stack.length-1}>")
362
360
  end
@@ -370,7 +368,7 @@ module Mgmg
370
368
  elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
371
369
  [mins_sub(stack, m[1], lassoc), mins_sub(stack, m[2], lassoc)].max
372
370
  elsif m = /\A\<(\d+)\>\Z/.match(str)
373
- 1
371
+ 0
374
372
  else
375
373
  mins_sub2(str)
376
374
  end
@@ -384,8 +382,8 @@ module Mgmg
384
382
  unless kind
385
383
  raise InvalidEquipClassError.new(m[1])
386
384
  end
387
- main_m, main_s, main_mc = parse_material(m[2])
388
- sub_m, sub_s, sub_mc = parse_material(m[3])
385
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
386
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
389
387
  [main_s, sub_s].max
390
388
  end
391
389
  end
data/lib/mgmg/ir.rb ADDED
@@ -0,0 +1,400 @@
1
+ module Mgmg
2
+ using Refiner
3
+ class IR
4
+ class Const
5
+ def initialize(value)
6
+ @value = value
7
+ end
8
+ attr_accessor :value
9
+ def initialize_copy(other)
10
+ @value = other.value
11
+ end
12
+ def evaluate(s, c)
13
+ @value
14
+ end
15
+ def evaluate3(s, a, c)
16
+ @value
17
+ end
18
+ def to_s
19
+ @value.to_s
20
+ end
21
+ end
22
+ class Smith
23
+ def initialize(sub9, coef, den, sa=nil)
24
+ @sub9, @coef, @den, @sa = sub9, coef, den, sa
25
+ end
26
+ attr_accessor :sub9, :coef, :den, :sa
27
+ def initialize_copy(other)
28
+ @sub9, @coef, @den, @sa = other.sub9, other.coef, other.den, other.sa
29
+ end
30
+ def evaluate(s, c)
31
+ ((s+@sub9)*@coef).div(@den)
32
+ end
33
+ def evaluate3(s, a, c)
34
+ if @sa==:a
35
+ ((a+@sub9)*@coef).div(@den)
36
+ else
37
+ ((s+@sub9)*@coef).div(@den)
38
+ end
39
+ end
40
+ def to_s
41
+ if sa==:a
42
+ "[#{@coef}(a+#{@sub9})/#{den}]"
43
+ else
44
+ "[#{@coef}(s+#{@sub9})/#{den}]"
45
+ end
46
+ end
47
+ end
48
+ class Compose
49
+ def initialize(main, sub, equip9, coef, den)
50
+ @main, @sub, @equip9, @coef, @den = main, sub, equip9, coef, den
51
+ end
52
+ attr_accessor :main, :sub, :equip9, :coef, :den
53
+ def initialize_copy(other)
54
+ @main, @sub = other.main.dup, other.sub.dup
55
+ @equip9, @coef, @den = other.equip9, other.coef, other.den
56
+ end
57
+ def evaluate(s, c)
58
+ @main.evaluate(s, c) + ( ( @sub.evaluate(s, c) * (c+@equip9).div(2) ).cdiv(100) * @coef ).cdiv(@den)
59
+ end
60
+ def evaluate3(s, a, c)
61
+ @main.evaluate3(s, a, c) + ( ( @sub.evaluate3(s, a, c) * (c+@equip9).div(2) ).cdiv(100) * @coef ).cdiv(@den)
62
+ end
63
+ def to_s
64
+ ms, ss = @main.to_s, @sub.to_s
65
+ if ss == '0'
66
+ ms
67
+ else
68
+ if ms == '0'
69
+ "[[#{ss}[(c+#{@equip9})/2]/100]/#{@den}]"
70
+ else
71
+ "#{ms}+[[#{ss}[(c+#{@equip9})/2]/100]/#{@den}]"
72
+ end
73
+ end
74
+ end
75
+ end
76
+ class Multi
77
+ def initialize(body)
78
+ @body = body
79
+ end
80
+ attr_accessor :body
81
+ def initialize_copy(other)
82
+ @body = other.body.dup
83
+ end
84
+ def evaluate(s, c)
85
+ @body.sum do |e|
86
+ e.evaluate(s, c)
87
+ end
88
+ end
89
+ def evaluate3(s, a, c)
90
+ @body.sum do |e|
91
+ e.evaluate3(s, a, c)
92
+ end
93
+ end
94
+ def to_s
95
+ @body.map(&:to_s).join('+')
96
+ end
97
+ end
98
+ class << Multi
99
+ def sum(a, b)
100
+ unconsts, const = [], Const.new(0)
101
+ case a
102
+ when Multi
103
+ if a.body[0].kind_of?(Const)
104
+ const.value += a.body[0].value
105
+ unconsts = a.body[1..(-1)]
106
+ else
107
+ unconsts = a.body.dup
108
+ end
109
+ when Const
110
+ const.value += a.value
111
+ else
112
+ unconsts << a
113
+ end
114
+ case b
115
+ when Multi
116
+ if b.body[0].kind_of?(Const)
117
+ const.value += b.body[0].value
118
+ unconsts.concat(b.body[1..(-1)])
119
+ else
120
+ unconsts.concat(b.body)
121
+ end
122
+ when Const
123
+ const.value += b.value
124
+ else
125
+ unconsts << b
126
+ end
127
+ body = ( const.value == 0 ? unconsts : [const, *unconsts] )
128
+ case body.size
129
+ when 0
130
+ const
131
+ when 1
132
+ body[0]
133
+ else
134
+ new(body)
135
+ end
136
+ end
137
+ end
138
+ def initialize(kind, star, main_m, sub_m, para, rein=[])
139
+ @kind, @star, @main, @sub, @para = kind, star, main_m, sub_m, para
140
+ add_reinforcement(rein)
141
+ end
142
+ def add_reinforcement(rein)
143
+ @rein = if rein.kind_of?(Array)
144
+ rein.map do |r|
145
+ Reinforcement.compile(r)
146
+ end
147
+ else
148
+ [Reinforcement.compile(rein)]
149
+ end
150
+ self
151
+ end
152
+ attr_accessor :kind, :star, :main, :sub, :para, :rein
153
+ def initialize_copy(other)
154
+ @kind = other.kind
155
+ @star = other.star
156
+ @main = other.main
157
+ @sub = other.sub
158
+ @para = other.para.dup
159
+ @rein = other.rein.dup
160
+ end
161
+
162
+ def compose(other)
163
+ self.class.compose(self, other)
164
+ end
165
+
166
+ def to_s
167
+ par = @para.map.with_index{|e, i| e.to_s=='0' ? nil : "#{Mgmg::Equip::ParamList[i]}:#{e.to_s}"}.compact
168
+ if @kind == 28
169
+ ep = @star.map.with_index{|e, i| e==0 ? nil : "#{Mgmg::Equip::EqPosList[i]}:#{e}"}.compact
170
+ "複数装備(#{ep.join(', ')})<#{par.join(', ')}>#{@rein.empty? ? '' : '{'+@rein.join(',')+'}'}"
171
+ else
172
+ "#{EquipName[@kind]}☆#{@star}(#{MaterialClass[@main]}#{MaterialClass[@sub]})<#{par.join(', ')}>#{@rein.empty? ? '' : '{'+@rein.join(',')+'}'}"
173
+ end
174
+ end
175
+
176
+ def para_call(para, s, ac, x=nil)
177
+ if x.nil?
178
+ method(para).call(s, ac)
179
+ else
180
+ method(para).call(s, ac, x)
181
+ end
182
+ end
183
+
184
+ %i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |sym, i|
185
+ define_method(sym) do |s=nil, ac=s, x=nil|
186
+ ret = if s.nil?
187
+ @para[i]
188
+ elsif x.nil?
189
+ @para[i].evaluate(s, ac)
190
+ else
191
+ @para[i].evaluate3(s, ac, x)
192
+ end
193
+ @rein.each do |r|
194
+ if r.vec[i] != 0
195
+ ret *= (100+r.vec[i]).quo(100)
196
+ end
197
+ end
198
+ ret
199
+ end
200
+ end
201
+ def atkstr(s, ac, x=nil)
202
+ attack(s, ac, x)+str(s, ac, x)
203
+ end
204
+ def atk_sd(s, ac, x=nil)
205
+ attack(s, ac, x)+str(s, ac, x).quo(2)+dex(s, ac, x).quo(2)
206
+ end
207
+ def dex_as(s, ac, x=nil)
208
+ attack(s, ac, x).quo(2)+str(s, ac, x).quo(2)+dex(s, ac, x)
209
+ end
210
+ def mag_das(s, ac, x=nil)
211
+ magic(s, ac, x)+dex_as(s, ac, x).quo(2)
212
+ end
213
+ def magic2(s, ac, x=nil)
214
+ magic(s, ac, x)*2
215
+ end
216
+ def magmag(s, ac, x=nil)
217
+ magdef(s, ac, x)+magic(s, ac, x).quo(2)
218
+ end
219
+ def pmdef(s, ac, x=nil)
220
+ [phydef(s, ac, x), magmag(s, ac, x)].min
221
+ end
222
+
223
+ def power(s, a=s, c=a.tap{a=s})
224
+ case @kind
225
+ when 0, 1
226
+ atk_sd(s, c)
227
+ when 2, 3
228
+ atkstr(s, c)
229
+ when 4
230
+ [dex_as(s, c), mag_das(s, c)].max
231
+ when 5
232
+ dex_as(s, c)
233
+ when 6, 7
234
+ [magic(s, c)*2, atkstr(s, c)].max
235
+ when 28
236
+ @para.enum_for(:sum).with_index do |e, i|
237
+ x = e.evaluate3(s, a, c)
238
+ @rein.each do |r|
239
+ if r.vec[i] != 0
240
+ x *= (100+r.vec[i]).quo(100)
241
+ end
242
+ end
243
+ x
244
+ end-((hp(s, a, c)+mp(s, a, c))*3.quo(4))
245
+ else
246
+ ret = @para.map.with_index do |e, i|
247
+ x = e.evaluate3(s, a, c)
248
+ @rein.each do |r|
249
+ if r.vec[i] != 0
250
+ x *= (100+r.vec[i]).quo(100)
251
+ end
252
+ end
253
+ x
254
+ end.max
255
+ if ret == magdef(s, a, c)
256
+ ret+magic(s, a, c).quo(2)
257
+ else
258
+ ret
259
+ end
260
+ end
261
+ end
262
+ def fpower(s, a=s, c=a.tap{a=s})
263
+ power(s, a, c).to_f
264
+ end
265
+
266
+ def smith_cost(s, c=s, outsourcing=false)
267
+ if outsourcing
268
+ if @kind < 8
269
+ (@star**2)*2+@para.sum{|e| e.evaluate(s, c)}+hp(s, c).cdiv(4)-hp(s, c)+mp(s, c).cdiv(4)-mp(s, c)
270
+ else
271
+ (@star**2)+@para.sum{|e| e.evaluate(s, c)}+hp(s, c).cdiv(4)-hp(s, c)+mp(s, c).cdiv(4)-mp(s, c)
272
+ end
273
+ else
274
+ if @kind < 8
275
+ ((@star**2)*2+@para.sum{|e| e.evaluate(s, c)}+hp(s, c).cdiv(4)-hp(s, c)+mp(s, c).cdiv(4)-mp(s, c)).div(2)
276
+ else
277
+ ((@star**2)+@para.sum{|e| e.evaluate(s, c)}+hp(s, c).cdiv(4)-hp(s, c)+mp(s, c).cdiv(4)-mp(s, c)).div(2)
278
+ end
279
+ end
280
+ end
281
+ def comp_cost(s, c=s, outsourcing=false)
282
+ if outsourcing
283
+ [(@star**2)*5+@para.sum{|e| e.evaluate(s, c)}+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max.div(2)
284
+ else
285
+ [((@star**2)*5+@para.sum{|e| e.evaluate(s, c)}+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max.div(2)
286
+ end
287
+ end
288
+ alias :cost :comp_cost
289
+
290
+ def add!(other)
291
+ if @kind == 28
292
+ if other.kind == 28
293
+ @star.add!(other.star)
294
+ else
295
+ @star[EquipPosition[other.kind]] += 1
296
+ end
297
+ else
298
+ @star = Vec.new(6, 0)
299
+ @star[EquipPosition[@kind]] = 1
300
+ @kind = 28
301
+ if other.kind == 28
302
+ @star.add!(other.star)
303
+ else
304
+ @star[EquipPosition[other.kind]] += 1
305
+ end
306
+ end
307
+ @main, @sub = 12, 12
308
+ @para = Array.new(9) do |i|
309
+ Multi.sum(self.para[i], other.para[i])
310
+ end
311
+ self
312
+ end
313
+ def +(other)
314
+ self.dup.add!(other)
315
+ end
316
+ Zero = self.new(28, Vec.new(6, 0), 12, 12, Array.new(9){Const.new(0)})
317
+ end
318
+ class << IR
319
+ def build(str, left_associative: true, reinforcement: [])
320
+ str = Mgmg.check_string(str)
321
+ stack, str = build_sub0([], str)
322
+ build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
323
+ end
324
+ private def build_sub0(stack, str)
325
+ SystemEquip.each do |k, v|
326
+ if SystemEquipRegexp[k].match(str)
327
+ stack << from_equip(v)
328
+ str = str.gsub(k, "<#{stack.length-1}>")
329
+ end
330
+ end
331
+ [stack, str]
332
+ end
333
+ private def build_sub(stack, str, lassoc)
334
+ if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
335
+ stack << build_sub(stack, m[2], lassoc)
336
+ build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
337
+ elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
338
+ compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
339
+ elsif m = /\A\<(\d+)\>\Z/.match(str)
340
+ stack[m[1].to_i]
341
+ else
342
+ smith(str)
343
+ end
344
+ end
345
+
346
+ def compose(main, sub)
347
+ main_k, sub_k = main.kind, sub.kind
348
+ main_s, sub_s = main.star, sub.star
349
+ main_main, sub_main = main.main, sub.main
350
+ main_sub, sub_sub = main.sub, sub.sub
351
+
352
+ coef = Equip9[main_k].dup
353
+ coef.sub!(Equip9[sub_k])
354
+ coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
355
+ coef.add!(Material9[main_main]).sub!(Material9[sub_main])
356
+ den = ( main_k==sub_k ? 200 : 100 )
357
+ para = Array.new(9) do |i|
358
+ if EquipFilter[main_k][i] == 0
359
+ main.para[i]
360
+ else
361
+ Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
362
+ end
363
+ end
364
+
365
+ new(main_k, main_s+sub_s, main_sub, sub_main, para)
366
+ end
367
+ def smith(str)
368
+ str = Mgmg.check_string(str)
369
+ unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
370
+ raise InvalidSmithError.new(str)
371
+ end
372
+ kind = EquipIndex[m[1].to_sym]
373
+ unless kind
374
+ raise InvalidEquipClassError.new(m[1])
375
+ end
376
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
377
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
378
+ sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
379
+
380
+ coef = Equip9[kind].dup
381
+ coef.e_mul!(Main9[main_m]).e_div!(100)
382
+ den = ( main_mc==sub_mc ? 200 : 100 )
383
+ para = Array.new(9) do |i|
384
+ if coef[i] == 0
385
+ Mgmg::IR::Const.new(0)
386
+ else
387
+ Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
388
+ end
389
+ end
390
+
391
+ new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
392
+ end
393
+ def from_equip(equip)
394
+ para = equip.para.map do |value|
395
+ Mgmg::IR::Const.new(value)
396
+ end
397
+ new(equip.kind, equip.star, equip.main, equip.sub, para)
398
+ end
399
+ end
400
+ end
data/lib/mgmg/optimize.rb CHANGED
@@ -2,8 +2,12 @@ module Mgmg
2
2
  module Optimize; end
3
3
  class << Optimize
4
4
  InvList = [%w|帽子 フード サンダル|.freeze, %w|宝1 骨1 木1 木2 骨2|.freeze, %w|宝1 骨1 木1|.freeze].freeze
5
- def phydef_optimize(str, smith, comp=smith, left_associative: true, magdef_maximize: true)
6
- best = ( smith.nil? ? [str, str.poly(:phydef), str.poly(:magdef), str.poly(:cost)] : [str, str.build(smith, comp)] )
5
+ def phydef_optimize(str, smith, comp=smith, opt: Option.new)
6
+ best = if smith.nil? then
7
+ [str, str.poly(:phydef, opt: opt), str.poly(:magdef, opt: opt), str.poly(:cost, opt: opt)]
8
+ else
9
+ [str, str.build(smith, comp, opt: opt)]
10
+ end
7
11
  str = Mgmg.check_string(str)
8
12
  ai = 0
9
13
  while str.sub!(/(帽子|フード|サンダル)\([宝木骨][12][宝木骨]1\)/){
@@ -19,7 +23,7 @@ module Mgmg
19
23
  m = /([^\+]*\([^\(]+[綿皮]1\))\]*\Z/.match(str)
20
24
  if m
21
25
  if smith
22
- if m[1].sub(/綿1\)/, '皮1)').build(smith).weight == m[1].sub(/皮1\)/, '綿1)').build(smith).weight
26
+ if m[1].sub(/綿1\)/, '皮1)').build(smith, opt: opt).weight == m[1].sub(/皮1\)/, '綿1)').build(smith, opt: opt).weight
23
27
  skin = true
24
28
  end
25
29
  else
@@ -35,7 +39,11 @@ module Mgmg
35
39
  b = b0
36
40
  while b
37
41
  r = pd_apply_idx(str, a, b)
38
- best = pd_better(best, ( smith.nil? ? [r, r.poly(:phydef), r.poly(:magdef), r.poly(:cost)] : [r, r.build(smith, comp)] ), magdef_maximize)
42
+ best = if smith.nil? then
43
+ pd_better(best, [r, r.poly(:phydef, opt: opt), r.poly(:magdef, opt: opt), r.poly(:cost, opt: opt)], opt.magdef_maximize)
44
+ else
45
+ pd_better(best, [r, r.build(smith, comp, opt: opt)], opt.magdef_maximize)
46
+ end
39
47
  b = pd_next_b(b)
40
48
  end
41
49
  a = pd_next_a(a)
@@ -49,7 +57,11 @@ module Mgmg
49
57
  b = b0
50
58
  while b
51
59
  r = pd_apply_idx(str, a, b)
52
- best = pd_better(best, ( smith.nil? ? [r, r.poly(:phydef), r.poly(:magdef), r.poly(:cost)] : [r, r.build(smith, comp)] ), magdef_maximize)
60
+ best = if smith.nil? then
61
+ pd_better(best, [r, r.poly(:phydef, opt: opt), r.poly(:magdef, opt: opt), r.poly(:cost, opt: opt)], opt.magdef_maximize)
62
+ else
63
+ pd_better(best, [r, r.build(smith, comp, opt: opt)], opt.magdef_maximize)
64
+ end
53
65
  b = pd_next_b(b)
54
66
  end
55
67
  a = pd_next_a(a)
@@ -102,7 +114,7 @@ module Mgmg
102
114
  end
103
115
  return pre
104
116
  else
105
- raise "Unexpected Error"
117
+ raise UnexpectedError
106
118
  end
107
119
  end
108
120
  private def pd_apply_idx(str, a, b)
@@ -146,8 +158,8 @@ module Mgmg
146
158
  end
147
159
 
148
160
  MwList = %w|綿 皮 骨 木 水|.freeze
149
- def buster_optimize(str, smith, comp=smith, left_associative: true)
150
- best = ( smith.nil? ? [str, str.poly(:mag_das)] : [str, str.build(smith, comp)] )
161
+ def buster_optimize(str, smith, comp=smith, opt: Option.new)
162
+ best = ( smith.nil? ? [str, str.poly(:mag_das, opt: opt)] : [str, str.build(smith, comp, opt: opt)] )
151
163
  str = Mgmg.check_string(str)
152
164
  ai = -1
153
165
  org = nil
@@ -162,7 +174,7 @@ module Mgmg
162
174
  a = Array.new(ai){ [0, 0, 0] }
163
175
  while a
164
176
  r = bus_apply_idx(str, a)
165
- best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das)] : [r, r.build(smith, comp)] ))
177
+ best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das, opt: opt)] : [r, r.build(smith, comp, opt: opt)] ))
166
178
  a = bus_next_a(a)
167
179
  end
168
180
  best[0]