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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/README.md +37 -248
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +37 -39
- data/lib/mgmg/ir.rb +400 -0
- data/lib/mgmg/optimize.rb +21 -9
- data/lib/mgmg/option.rb +85 -0
- data/lib/mgmg/poly.rb +2 -2
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +246 -175
- data/lib/mgmg/system_equip.rb +6 -0
- data/lib/mgmg/utils.rb +47 -1
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +176 -62
- data/mgmg.gemspec +4 -4
- data/reference.md +453 -0
- metadata +15 -10
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
|
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
|
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 = [
|
58
|
-
|
59
|
-
if str.build
|
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
|
-
|
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
|
-
|
185
|
-
|
186
|
-
|
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
|
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,
|
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
|
-
|
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
|
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,
|
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
|
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
|
-
|
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,
|
6
|
-
best =
|
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 =
|
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 =
|
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
|
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,
|
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]
|