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.
data/lib/mgmg/ir.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module Mgmg
2
2
  using Refiner
3
3
  class IR
4
+ Cache = Hash.new
4
5
  class Const
5
6
  def initialize(value)
6
7
  @value = value
@@ -94,44 +95,44 @@ module Mgmg
94
95
  def to_s
95
96
  @body.map(&:to_s).join('+')
96
97
  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)]
98
+ class << self
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
106
111
  else
107
- unconsts = a.body.dup
112
+ unconsts << a
108
113
  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)])
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
119
124
  else
120
- unconsts.concat(b.body)
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)
121
135
  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
136
  end
136
137
  end
137
138
  end
@@ -315,87 +316,92 @@ module Mgmg
315
316
  end
316
317
  Zero = self.new(28, Vec.new(6, 0).freeze, 12, 12, Array.new(9){Const.new(0)}.freeze)
317
318
  Zero.rein.freeze; Zero.freeze
318
- end
319
- class << IR
320
- def build(str, left_associative: true, reinforcement: [])
321
- str = Mgmg.check_string(str)
322
- stack, str = build_sub0([], str)
323
- build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
324
- end
325
- private def build_sub0(stack, str)
326
- SystemEquip.each do |k, v|
327
- if SystemEquipRegexp[k].match(str)
328
- stack << from_equip(v)
329
- str = str.gsub(k, "<#{stack.length-1}>")
330
- end
331
- end
332
- [stack, str]
333
- end
334
- private def build_sub(stack, str, lassoc)
335
- if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
336
- stack << build_sub(stack, m[2], lassoc)
337
- build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
338
- elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
339
- compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
340
- elsif m = /\A\<(\d+)\>\Z/.match(str)
341
- stack[m[1].to_i]
342
- else
343
- smith(str)
344
- end
345
- end
346
319
 
347
- def compose(main, sub)
348
- main_k, sub_k = main.kind, sub.kind
349
- main_s, sub_s = main.star, sub.star
350
- main_main, sub_main = main.main, sub.main
351
- main_sub, sub_sub = main.sub, sub.sub
352
-
353
- coef = Equip9[main_k].dup
354
- coef.sub!(Equip9[sub_k])
355
- coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
356
- coef.add!(Material9[main_main]).sub!(Material9[sub_main])
357
- den = ( main_k==sub_k ? 200 : 100 )
358
- para = Array.new(9) do |i|
359
- if EquipFilter[main_k][i] == 0
360
- main.para[i]
361
- else
362
- Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
320
+ class << self
321
+ def build(str, left_associative: true, reinforcement: [], include_system_equips: true)
322
+ str = Mgmg.check_string(str)
323
+ stack = []
324
+ stack, str = build_sub0(stack, str) if include_system_equips
325
+ build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
326
+ end
327
+ private def build_sub0(stack, str)
328
+ SystemEquip.each do |k, v|
329
+ if SystemEquipRegexp[k].match(str)
330
+ stack << from_equip(v)
331
+ str = str.gsub(k, "<#{stack.length-1}>")
332
+ end
363
333
  end
364
- end
365
-
366
- new(main_k, main_s+sub_s, main_sub, sub_main, para)
367
- end
368
- def smith(str)
369
- str = Mgmg.check_string(str)
370
- unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
371
- raise InvalidSmithError.new(str)
372
- end
373
- kind = EquipIndex[m[1].to_sym]
374
- unless kind
375
- raise InvalidEquipClassError.new(m[1])
376
- end
377
- main_m, main_s, main_mc = Mgmg.parse_material(m[2])
378
- sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
379
- sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
380
-
381
- coef = Equip9[kind].dup
382
- coef.e_mul!(Main9[main_m]).e_div!(100)
383
- den = ( main_mc==sub_mc ? 200 : 100 )
384
- para = Array.new(9) do |i|
385
- if coef[i] == 0
386
- Mgmg::IR::Const.new(0)
334
+ [stack, str]
335
+ end
336
+ private def build_sub(stack, str, lassoc)
337
+ if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
338
+ stack << build_sub(stack, m[2], lassoc)
339
+ build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
340
+ elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
341
+ compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
342
+ elsif m = /\A\<(\d+)\>\Z/.match(str)
343
+ stack[m[1].to_i]
387
344
  else
388
- Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
345
+ smith(str)
389
346
  end
390
347
  end
391
348
 
392
- new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
393
- end
394
- def from_equip(equip)
395
- para = equip.para.map do |value|
396
- Mgmg::IR::Const.new(value)
349
+ def compose(main, sub)
350
+ main_k, sub_k = main.kind, sub.kind
351
+ main_s, sub_s = main.star, sub.star
352
+ main_main, sub_main = main.main, sub.main
353
+ main_sub, sub_sub = main.sub, sub.sub
354
+
355
+ coef = Equip9[main_k].dup
356
+ coef.sub!(Equip9[sub_k])
357
+ coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
358
+ coef.add!(Material9[main_main]).sub!(Material9[sub_main])
359
+ den = ( main_k==sub_k ? 200 : 100 )
360
+ para = Array.new(9) do |i|
361
+ if EquipFilter[main_k][i] == 0
362
+ main.para[i]
363
+ else
364
+ Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
365
+ end
366
+ end
367
+
368
+ new(main_k, main_s+sub_s, main_sub, sub_main, para)
369
+ end
370
+ def smith(str)
371
+ str = Mgmg.check_string(str)
372
+ return Cache[str].dup if Cache.has_key?(str)
373
+ unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
374
+ raise InvalidSmithError.new(str)
375
+ end
376
+ kind = EquipIndex[m[1].to_sym]
377
+ unless kind
378
+ raise InvalidEquipClassError.new(m[1])
379
+ end
380
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
381
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
382
+ sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
383
+
384
+ coef = Equip9[kind].dup
385
+ coef.e_mul!(Main9[main_m]).e_div!(100)
386
+ den = ( main_mc==sub_mc ? 200 : 100 )
387
+ para = Array.new(9) do |i|
388
+ if coef[i] == 0
389
+ Mgmg::IR::Const.new(0)
390
+ else
391
+ Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
392
+ end
393
+ end
394
+
395
+ ret = new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
396
+ Cache.store(str, ret.freeze)
397
+ ret.dup
398
+ end
399
+ def from_equip(equip)
400
+ para = equip.para.map do |value|
401
+ Mgmg::IR::Const.new(value)
402
+ end
403
+ new(equip.kind, equip.star, equip.main, equip.sub, para)
397
404
  end
398
- new(equip.kind, equip.star, equip.main, equip.sub, para)
399
405
  end
400
406
  end
401
407
  end
data/lib/mgmg/optimize.rb CHANGED
@@ -4,9 +4,9 @@ module Mgmg
4
4
  InvList = [%w|帽子 フード サンダル|.freeze, %w|宝1 骨1 木1 木2 骨2|.freeze, %w|宝1 骨1 木1|.freeze].freeze
5
5
  def phydef_optimize(str, smith, comp=smith, opt: Option.new)
6
6
  best = if smith.nil? then
7
- [str, str.poly(:phydef, opt: opt), str.poly(:magdef, opt: opt), str.poly(:cost, opt: opt)]
7
+ [str, str.poly(:phydef, opt:), str.poly(:magdef, opt:), str.poly(:cost, opt:)]
8
8
  else
9
- [str, str.build(smith, comp, opt: opt)]
9
+ [str, str.build(smith, comp, opt:)]
10
10
  end
11
11
  str = Mgmg.check_string(str)
12
12
  ai = 0
@@ -23,7 +23,7 @@ module Mgmg
23
23
  m = /([^\+]*\([^\(]+[綿皮]1\))\]*\Z/.match(str)
24
24
  if m
25
25
  if smith
26
- if m[1].sub(/綿1\)/, '皮1)').build(smith, opt: opt).weight == m[1].sub(/皮1\)/, '綿1)').build(smith, opt: opt).weight
26
+ if m[1].sub(/綿1\)/, '皮1)').build(smith, opt:).weight == m[1].sub(/皮1\)/, '綿1)').build(smith, opt:).weight
27
27
  skin = true
28
28
  end
29
29
  else
@@ -40,9 +40,9 @@ module Mgmg
40
40
  while b
41
41
  r = pd_apply_idx(str, a, b)
42
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)
43
+ pd_better(best, [r, r.poly(:phydef, opt:), r.poly(:magdef, opt:), r.poly(:cost, opt:)], opt.magdef_maximize)
44
44
  else
45
- pd_better(best, [r, r.build(smith, comp, opt: opt)], opt.magdef_maximize)
45
+ pd_better(best, [r, r.build(smith, comp, opt:)], opt.magdef_maximize)
46
46
  end
47
47
  b = pd_next_b(b)
48
48
  end
@@ -58,9 +58,9 @@ module Mgmg
58
58
  while b
59
59
  r = pd_apply_idx(str, a, b)
60
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)
61
+ pd_better(best, [r, r.poly(:phydef, opt:), r.poly(:magdef, opt:), r.poly(:cost, opt:)], opt.magdef_maximize)
62
62
  else
63
- pd_better(best, [r, r.build(smith, comp, opt: opt)], opt.magdef_maximize)
63
+ pd_better(best, [r, r.build(smith, comp, opt:)], opt.magdef_maximize)
64
64
  end
65
65
  b = pd_next_b(b)
66
66
  end
@@ -159,7 +159,7 @@ module Mgmg
159
159
 
160
160
  MwList = %w|綿 皮 骨 木 水|.freeze
161
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)] )
162
+ best = ( smith.nil? ? [str, str.poly(:mag_das, opt:)] : [str, str.build(smith, comp, opt:)] )
163
163
  str = Mgmg.check_string(str)
164
164
  ai = -1
165
165
  org = nil
@@ -174,7 +174,7 @@ module Mgmg
174
174
  a = Array.new(ai){ [0, 0, 0] }
175
175
  while a
176
176
  r = bus_apply_idx(str, a)
177
- best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das, opt: opt)] : [r, r.build(smith, comp, opt: opt)] ))
177
+ best = bus_better(best, ( smith.nil? ? [r, r.poly(:mag_das, opt:)] : [r, r.build(smith, comp, opt:)] ))
178
178
  a = bus_next_a(a)
179
179
  end
180
180
  best[0]
data/lib/mgmg/option.rb CHANGED
@@ -1,11 +1,16 @@
1
1
  module Mgmg
2
2
  class Option
3
+ Defaults = {
4
+ left_associative: true, include_system_equips: true,
5
+ smith_max: 10000, armor_max: 10000, comp_max: 10000
6
+ }
3
7
  def initialize(
4
- left_associative: true,
5
- smith_min: nil, armor_min:nil, comp_min: nil, smith_max: 10000, armor_max: 10000, comp_max: 10000,
8
+ left_associative: Defaults[:left_associative],
9
+ smith_min: nil, armor_min:nil, comp_min: nil, smith_max: Defaults[:smith_max], armor_max: Defaults[:armor_max], comp_max: Defaults[:comp_max],
6
10
  step: 1, magdef_maximize: true,
7
11
  target_weight: 0, reinforcement: [], buff: nil,
8
- irep: nil, cut_exp: Float::INFINITY
12
+ irep: nil, cut_exp: Float::INFINITY,
13
+ include_system_equips: Defaults[:include_system_equips]
9
14
  )
10
15
  @left_associative = left_associative
11
16
  @smith_min = smith_min
@@ -27,9 +32,10 @@ module Mgmg
27
32
  end
28
33
  @irep = irep
29
34
  @cut_exp = cut_exp
35
+ @include_system_equips = include_system_equips
30
36
  end
31
37
  attr_accessor :left_associative, :smith_min, :armor_min, :comp_min, :smith_max, :armor_max, :comp_max
32
- attr_accessor :step, :magdef_maximize, :target_weight, :reinforcement, :irep, :cut_exp
38
+ attr_accessor :step, :magdef_maximize, :target_weight, :reinforcement, :irep, :cut_exp, :include_system_equips
33
39
  def initialize_copy(other)
34
40
  @left_associative = other.left_associative
35
41
  @smith_min = other.smith_min
@@ -44,6 +50,7 @@ module Mgmg
44
50
  @reinforcement = other.reinforcement.dup
45
51
  @irep = other.irep
46
52
  @cut_exp = other.cut_exp
53
+ @include_system_equips = other.include_system_equips
47
54
  end
48
55
  def update_sa_min(recipe, force=true)
49
56
  case recipe
@@ -69,9 +76,11 @@ module Mgmg
69
76
  self
70
77
  end
71
78
  def set_default(recipe, force: false)
79
+ @include_system_equips = false if @include_system_equips && !Mgmg::SystemEquipRegexp.values.any?{|re| re.match(recipe)}
72
80
  update_sa_min(recipe, force)
73
81
  @comp_min = recipe.min_comp(opt: self) if force || @comp_min.nil?
74
82
  @irep = recipe.ir(opt: self) if force || @irep.nil?
83
+
75
84
  self
76
85
  end
77
86
  def buff
@@ -81,4 +90,10 @@ module Mgmg
81
90
  @reinforcement = v
82
91
  end
83
92
  end
93
+
94
+ module_function def option(recipe=nil, **kw)
95
+ ret = Option.new(**kw)
96
+ ret.set_default(recipe) unless recipe.nil?
97
+ ret
98
+ end
84
99
  end
data/lib/mgmg/poly.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  module Mgmg
2
2
  using Refiner
3
3
  class TPolynomial
4
+ Cache = Hash.new
4
5
  def initialize(mat, kind, star, main_m, sub_m)
5
6
  @mat, @kind, @star, @main, @sub = mat, kind, star, main_m, sub_m
6
7
  end
@@ -285,71 +286,77 @@ module Mgmg
285
286
  1
286
287
  end
287
288
  end
288
- end
289
- class << TPolynomial
290
- ParamIndex = Hash.new
291
- %i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |s, i|
292
- ParamIndex.store(s, i)
293
- ParamIndex.store(i, i)
294
- ParamIndex.store(Equip::ParamList[i], i)
295
- end
296
- def from_equip(equip, para)
297
- new(Mat.new(1, 1, equip.para[ParamIndex[para]]), equip.kind, equip.star, equip.main, equip.sub)
298
- end
299
- def smith(str, para)
300
- unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
301
- raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
289
+
290
+ class << self
291
+ ParamIndex = Hash.new
292
+ %i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |s, i|
293
+ ParamIndex.store(s, i)
294
+ ParamIndex.store(i, i)
295
+ ParamIndex.store(Equip::ParamList[i], i)
302
296
  end
303
- kind = EquipIndex[m[1].to_sym]
304
- main_m, main_s, main_mc = Mgmg.parse_material(m[2])
305
- sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
306
- para = ParamIndex[para]
307
-
308
- c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
309
- new(Mat.v_array(c*Sub9[sub_m][para], c), kind, (main_s+sub_s).div(2), main_mc, sub_mc)
310
- end
311
- def compose(main, sub, para)
312
- main_k, sub_k = main.kind, sub.kind
313
- main_s, sub_s = main.star, sub.star
314
- main_main, sub_main = main.main, sub.main
315
- main_sub, sub_sub = main.sub, sub.sub
316
- para = ParamIndex[para]
317
-
318
- if Equip9[main_k][para] == 0
319
- c = 0.quo(1)
320
- else
321
- c = ( 100 + Equip9[main_k][para] - Equip9[sub_k][para] + Material9[main_main][para] - Material9[sub_main][para] +
322
- (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) ).quo( main_k==sub_k ? 40000 : 20000 )
297
+ def from_equip(equip, para)
298
+ new(Mat.new(1, 1, equip.para[ParamIndex[para]]), equip.kind, equip.star, equip.main, equip.sub)
323
299
  end
324
- mat = main.mat.padd(sub.mat.pprod(Mat.h_array(c*Equip9[main_k][para], c)))
325
- new(mat, main_k, main_s+sub_s, main_sub, sub_main)
326
- end
327
- def build(str, para, left_associative: true)
328
- str = Mgmg.check_string(str)
329
- _para = ParamIndex[para]
330
- if _para.nil?
331
- raise ArgumentError, "unknown parameter symbol `#{para.inspect}' given"
300
+ def smith(str, para)
301
+ key = [str.freeze, para].freeze
302
+ return Cache[key].dup if Cache.has_key?(key)
303
+ unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
304
+ raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
305
+ end
306
+ kind = EquipIndex[m[1].to_sym]
307
+ main_m, main_s, main_mc = Mgmg.parse_material(m[2])
308
+ sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
309
+ para = ParamIndex[para]
310
+
311
+ c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
312
+ ret = new(Mat.v_array(c*Sub9[sub_m][para], c), kind, (main_s+sub_s).div(2), main_mc, sub_mc)
313
+ Cache.store(key, ret.freeze)
314
+ ret.dup
332
315
  end
333
- stack, str = build_sub0([], str, _para)
334
- build_sub(stack, str, _para, left_associative)
335
- end
336
- private def build_sub0(stack, str, para)
337
- SystemEquip.each do |k, v|
338
- stack << from_equip(v, para)
339
- str = str.gsub(k, "<#{stack.length-1}>")
316
+ def compose(main, sub, para)
317
+ main_k, sub_k = main.kind, sub.kind
318
+ main_s, sub_s = main.star, sub.star
319
+ main_main, sub_main = main.main, sub.main
320
+ main_sub, sub_sub = main.sub, sub.sub
321
+ para = ParamIndex[para]
322
+
323
+ if Equip9[main_k][para] == 0
324
+ c = 0.quo(1)
325
+ else
326
+ c = ( 100 + Equip9[main_k][para] - Equip9[sub_k][para] + Material9[main_main][para] - Material9[sub_main][para] +
327
+ (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) ).quo( main_k==sub_k ? 40000 : 20000 )
328
+ end
329
+ mat = main.mat.padd(sub.mat.pprod(Mat.h_array(c*Equip9[main_k][para], c)))
330
+ new(mat, main_k, main_s+sub_s, main_sub, sub_main)
340
331
  end
341
- [stack, str]
342
- end
343
- private def build_sub(stack, str, para, lassoc)
344
- if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
345
- stack << build_sub(stack, m[2], para, lassoc)
346
- build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", para, lassoc)
347
- elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
348
- compose(build_sub(stack, m[1], para, lassoc), build_sub(stack, m[2], para, lassoc), para)
349
- elsif m = /\A\<(\d+)\>\Z/.match(str)
350
- stack[m[1].to_i]
351
- else
352
- smith(str, para)
332
+ def build(str, para, left_associative: true, include_system_equips: true)
333
+ str = Mgmg.check_string(str)
334
+ _para = ParamIndex[para]
335
+ if _para.nil?
336
+ raise ArgumentError, "unknown parameter symbol `#{para.inspect}' given"
337
+ end
338
+ stack = []
339
+ stack, str = build_sub0(stack, str, _para) if include_system_equips
340
+ build_sub(stack, str, _para, left_associative)
341
+ end
342
+ private def build_sub0(stack, str, para)
343
+ SystemEquip.each do |k, v|
344
+ stack << from_equip(v, para)
345
+ str = str.gsub(k, "<#{stack.length-1}>")
346
+ end
347
+ [stack, str]
348
+ end
349
+ private def build_sub(stack, str, para, lassoc)
350
+ if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
351
+ stack << build_sub(stack, m[2], para, lassoc)
352
+ build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", para, lassoc)
353
+ elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
354
+ compose(build_sub(stack, m[1], para, lassoc), build_sub(stack, m[2], para, lassoc), para)
355
+ elsif m = /\A\<(\d+)\>\Z/.match(str)
356
+ stack[m[1].to_i]
357
+ else
358
+ smith(str, para)
359
+ end
353
360
  end
354
361
  end
355
362
  end
data/lib/mgmg/recipe.rb CHANGED
@@ -30,7 +30,7 @@ module Mgmg
30
30
  end
31
31
  end
32
32
  def option(**kw)
33
- @option = temp_opt(*kw)
33
+ @option = temp_opt(**kw)
34
34
  @option
35
35
  end
36
36
  def option=(new_option)
@@ -70,9 +70,9 @@ module Mgmg
70
70
  smith, armor, comp = opt.smith_min, opt.armor_min, opt.comp_min if smith.nil?
71
71
  case @recipe
72
72
  when String
73
- recipe.build(smith, comp, opt: opt)
73
+ recipe.build(smith, comp, opt:)
74
74
  when Enumerable
75
- recipe.build(smith, armor, comp, opt: opt)
75
+ recipe.build(smith, armor, comp, opt:)
76
76
  else
77
77
  raise BrokenRecipeError
78
78
  end
@@ -82,16 +82,16 @@ module Mgmg
82
82
  smith, armor, comp = opt.smith_min, opt.armor_min, opt.comp_min if smith.nil?
83
83
  case @recipe
84
84
  when String
85
- recipe.show(smith, comp, para: para, opt: opt)
85
+ recipe.show(smith, comp, para:, opt:)
86
86
  when Enumerable
87
- recipe.show(smith, armor, comp, para: para, opt: opt)
87
+ recipe.show(smith, armor, comp, para:, opt:)
88
88
  else
89
89
  raise BrokenRecipeError
90
90
  end
91
91
  end
92
92
  def search(target, para: @para, **kw)
93
93
  opt = temp_opt(**kw)
94
- @recipe.search(para, target, opt: opt)
94
+ @recipe.search(para, target, opt:)
95
95
  end
96
96
  private def correct_level(s, ac, x, opt)
97
97
  if s.nil?
@@ -147,7 +147,7 @@ module Mgmg
147
147
  def poly(para=@para, **kw)
148
148
  opt = temp_opt(**kw)
149
149
  if @recipe.kind_of?(String)
150
- @recipe.poly(para, opt: opt)
150
+ @recipe.poly(para, opt:)
151
151
  else
152
152
  raise InvalidRecipeError, "Mgmg::Recipe#poly is available only for String recipes."
153
153
  end
@@ -155,7 +155,7 @@ module Mgmg
155
155
  def phydef_optimize(smith=nil, comp=smith, **kw)
156
156
  opt = temp_opt(**kw)
157
157
  if @recipe.kind_of?(String)
158
- @recipe.phydef_optimize(smith, comp, opt: opt)
158
+ @recipe.phydef_optimize(smith, comp, opt:)
159
159
  else
160
160
  raise InvalidRecipeError, "Mgmg::Recipe#phydef_optimize is available only for String recipes."
161
161
  end
@@ -163,7 +163,7 @@ module Mgmg
163
163
  def buster_optimize(smith=nil, comp=smith, **kw)
164
164
  opt = temp_opt(**kw)
165
165
  if @recipe.kind_of?(String)
166
- @recipe.buster_optimize(smith, comp, opt: opt)
166
+ @recipe.buster_optimize(smith, comp, opt:)
167
167
  else
168
168
  raise InvalidRecipeError, "Mgmg::Recipe#buster_optimize is available only for String recipes."
169
169
  end
@@ -12,46 +12,45 @@ module Mgmg
12
12
  '(' + @vec.map.with_index{|e, i| e==0 ? nil : "#{Equip::ParamList[i]}:#{e}"}.compact.join(', ') + ')'
13
13
  end
14
14
  alias :inspect :to_s
15
- end
16
-
17
- # スキル名 攻 物 防 HP MP 腕 器 速 魔
18
- Skill = {
19
- '物防御UP' => Reinforcement.new( Vec[ 0, 10, 0, 0, 0, 0, 0, 0, 0] ),
20
- '魔防御UP' => Reinforcement.new( Vec[ 0, 0, 10, 0, 0, 0, 0, 0, 0] ),
21
- '腕力UP' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 10, 0, 0, 0] ),
22
- 'メンテナンス' => Reinforcement.new( Vec[ 50, 0, 0, 0, 0, 0, 0, 0, 0] ),
23
- 'ガードアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 0, 0, 0, 0] ),
24
- 'パワーアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 50, 0, 0, 0] ),
25
- 'デックスアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 50, 0, 0] ),
26
- 'スピードアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 50, 0] ),
27
- 'マジックアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 0, 50] ),
28
- 'オールアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 50, 50, 50, 50] ),
29
- }
30
-
31
- class << Reinforcement
32
- def cuisine(c)
33
- Reinforcement.new( Vec[*(c.vec), *Array.new(6, 0)] )
34
- end
35
- def compile(arg)
36
- case arg
37
- when Reinforcement
38
- arg
39
- when Cuisine
40
- cuisine(arg)
41
- when String
42
- if Skill.has_key?(arg)
43
- Skill[arg]
44
- elsif SystemCuisine.has_key?(arg)
45
- cuisine(SystemCuisine[arg])
15
+
16
+ # スキル名 攻 物 防 HP MP 腕 器 速 魔
17
+ Skill = {
18
+ '物防御UP' => Reinforcement.new( Vec[ 0, 10, 0, 0, 0, 0, 0, 0, 0] ),
19
+ '魔防御UP' => Reinforcement.new( Vec[ 0, 0, 10, 0, 0, 0, 0, 0, 0] ),
20
+ '腕力UP' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 10, 0, 0, 0] ),
21
+ 'メンテナンス' => Reinforcement.new( Vec[ 50, 0, 0, 0, 0, 0, 0, 0, 0] ),
22
+ 'ガードアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 0, 0, 0, 0] ),
23
+ 'パワーアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 50, 0, 0, 0] ),
24
+ 'デックスアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 50, 0, 0] ),
25
+ 'スピードアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 50, 0] ),
26
+ 'マジックアップ' => Reinforcement.new( Vec[ 0, 0, 0, 0, 0, 0, 0, 0, 50] ),
27
+ 'オールアップ' => Reinforcement.new( Vec[ 0, 50, 0, 0, 0, 50, 50, 50, 50] ),
28
+ }
29
+
30
+ class << self
31
+ def cuisine(c)
32
+ Reinforcement.new( Vec[*(c.vec), *Array.new(6, 0)] )
33
+ end
34
+ def compile(arg)
35
+ case arg
36
+ when Reinforcement
37
+ arg
38
+ when Cuisine
39
+ cuisine(arg)
40
+ when String
41
+ if Skill.has_key?(arg)
42
+ Skill[arg]
43
+ elsif SystemCuisine.has_key?(arg)
44
+ cuisine(SystemCuisine[arg])
45
+ else
46
+ raise InvalidReinforcementNameError, arg
47
+ end
46
48
  else
47
- raise InvalidReinforcementNameError, arg
49
+ raise ArgumentError, "The argument should be Mgmg::Cuisine or skill name String. (`#{arg}' is given)"
48
50
  end
49
- else
50
- raise ArgumentError, "The argument should be Mgmg::Cuisine or skill name String. (`#{arg}' is given)"
51
51
  end
52
52
  end
53
53
  end
54
-
55
54
  class Equip
56
55
  def reinforce(*arg)
57
56
  arg.each do |r|