mgmg 1.4.0 → 1.4.1
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 +9 -0
- data/README.md +2 -235
- data/lib/mgmg/equip.rb +22 -19
- data/lib/mgmg/ir.rb +373 -0
- data/lib/mgmg/search.rb +153 -42
- data/lib/mgmg/utils.rb +14 -0
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +15 -6
- data/reference.md +289 -0
- metadata +5 -3
data/lib/mgmg/ir.rb
ADDED
@@ -0,0 +1,373 @@
|
|
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)
|
139
|
+
@kind, @star, @main, @sub, @para = kind, star, main_m, sub_m, para
|
140
|
+
end
|
141
|
+
attr_accessor :kind, :star, :main, :sub, :para
|
142
|
+
def initialize_copy(other)
|
143
|
+
@kind = other.kind
|
144
|
+
@star = other.star
|
145
|
+
@main = other.main
|
146
|
+
@sub = other.sub
|
147
|
+
@para = other.para.dup
|
148
|
+
end
|
149
|
+
|
150
|
+
def compose(other)
|
151
|
+
self.class.compose(self, other)
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_s
|
155
|
+
par = @para.map.with_index{|e, i| e.to_s=='0' ? nil : "#{Mgmg::Equip::ParamList[i]}:#{e.to_s}"}.compact
|
156
|
+
if @kind == 28
|
157
|
+
ep = @star.map.with_index{|e, i| e==0 ? nil : "#{Mgmg::Equip::EqPosList[i]}:#{e}"}.compact
|
158
|
+
"複数装備(#{ep.join(', ')})<#{par.join(', ')}>"
|
159
|
+
else
|
160
|
+
"#{EquipName[@kind]}☆#{@star}(#{MaterialClass[@main]}#{MaterialClass[@sub]})<#{par.join(', ')}>"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def para_call(para, s, ac, x=nil)
|
165
|
+
if x.nil?
|
166
|
+
method(para).call(s, ac)
|
167
|
+
else
|
168
|
+
method(para).call(s, ac, x)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
%i|attack phydef magdef hp mp str dex speed magic|.each.with_index do |sym, i|
|
173
|
+
define_method(sym) do |s=nil, ac=s, x=nil|
|
174
|
+
if s.nil?
|
175
|
+
@para[i]
|
176
|
+
elsif x.nil?
|
177
|
+
@para[i].evaluate(s, ac)
|
178
|
+
else
|
179
|
+
@para[i].evaluate3(s, ac, x)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
def atkstr(s, ac, x=nil)
|
184
|
+
attack(s, ac, x)+str(s, ac, x)
|
185
|
+
end
|
186
|
+
def atk_sd(s, ac, x=nil)
|
187
|
+
attack(s, ac, x)+str(s, ac, x).quo(2)+dex(s, ac, x).quo(2)
|
188
|
+
end
|
189
|
+
def dex_as(s, ac, x=nil)
|
190
|
+
attack(s, ac, x).quo(2)+str(s, ac, x).quo(2)+dex(s, ac, x)
|
191
|
+
end
|
192
|
+
def mag_das(s, ac, x=nil)
|
193
|
+
magic(s, ac, x)+dex_as(s, ac, x).quo(2)
|
194
|
+
end
|
195
|
+
def magic2(s, ac, x=nil)
|
196
|
+
magic(s, ac, x)*2
|
197
|
+
end
|
198
|
+
def magmag(s, ac, x=nil)
|
199
|
+
magdef(s, ac, x)+magic(s, ac, x).quo(2)
|
200
|
+
end
|
201
|
+
def pmdef(s, ac, x=nil)
|
202
|
+
[phydef(s, ac, x), magmag(s, ac, x)].min
|
203
|
+
end
|
204
|
+
|
205
|
+
def power(s, a=s, c=a.tap{a=s})
|
206
|
+
case @kind
|
207
|
+
when 0, 1
|
208
|
+
atk_sd(s, c)
|
209
|
+
when 2, 3
|
210
|
+
atkstr(s, c)
|
211
|
+
when 4
|
212
|
+
[dex_as(s, c), mag_das(s, c)].max
|
213
|
+
when 5
|
214
|
+
dex_as(s, c)
|
215
|
+
when 6, 7
|
216
|
+
[magic(s, c)*2, atkstr(s, c)].max
|
217
|
+
when 28
|
218
|
+
@para.sum{|e| e.evaluate3(s, a, c)}-((hp(s, a, c)+mp(s, a, c))*3.quo(4))
|
219
|
+
else
|
220
|
+
ret = @para.map{|e| e.evaluate3(s, a, c)}.max
|
221
|
+
if ret == magdef(s, a, c)
|
222
|
+
ret+magic(s, a, c).quo(2)
|
223
|
+
else
|
224
|
+
ret
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
def fpower(s, a=s, c=a.tap{a=s})
|
229
|
+
power(s, a, c).to_f
|
230
|
+
end
|
231
|
+
|
232
|
+
def smith_cost(s, c=s, outsourcing=false)
|
233
|
+
if outsourcing
|
234
|
+
if @kind < 8
|
235
|
+
(@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)
|
236
|
+
else
|
237
|
+
(@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)
|
238
|
+
end
|
239
|
+
else
|
240
|
+
if @kind < 8
|
241
|
+
((@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)
|
242
|
+
else
|
243
|
+
((@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)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
def comp_cost(s, c=s, outsourcing=false)
|
248
|
+
if outsourcing
|
249
|
+
[(@star**2)*5+@para.sum{|e| e.evaluate(s, c)}+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max.div(2)
|
250
|
+
else
|
251
|
+
[((@star**2)*5+@para.sum{|e| e.evaluate(s, c)}+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max.div(2)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
alias :cost :comp_cost
|
255
|
+
|
256
|
+
def add!(other)
|
257
|
+
if @kind == 28
|
258
|
+
if other.kind == 28
|
259
|
+
@star.add!(other.star)
|
260
|
+
else
|
261
|
+
@star[EquipPosition[other.kind]] += 1
|
262
|
+
end
|
263
|
+
else
|
264
|
+
@star = Vec.new(6, 0)
|
265
|
+
@star[EquipPosition[@kind]] = 1
|
266
|
+
@kind = 28
|
267
|
+
if other.kind == 28
|
268
|
+
@star.add!(other.star)
|
269
|
+
else
|
270
|
+
@star[EquipPosition[other.kind]] += 1
|
271
|
+
end
|
272
|
+
end
|
273
|
+
@main, @sub = 12, 12
|
274
|
+
@para = Array.new(9) do |i|
|
275
|
+
Multi.sum(self.para[i], other.para[i])
|
276
|
+
end
|
277
|
+
self
|
278
|
+
end
|
279
|
+
def +(other)
|
280
|
+
self.dup.add!(other)
|
281
|
+
end
|
282
|
+
def coerce(other)
|
283
|
+
if other == 0
|
284
|
+
zero = self.class.new(28, Vec.new(6, 0), 12, 12, Array.new(9){Const.new(0)})
|
285
|
+
[zero, self]
|
286
|
+
else
|
287
|
+
raise TypeError, "Mgmg::IR can't be coerced into other than 0"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
class << IR
|
292
|
+
def build(str, left_associative: true)
|
293
|
+
str = Mgmg.check_string(str)
|
294
|
+
stack, str = build_sub0([], str)
|
295
|
+
build_sub(stack, str, left_associative)
|
296
|
+
end
|
297
|
+
private def build_sub0(stack, str)
|
298
|
+
SystemEquip.each do |k, v|
|
299
|
+
if Regexp.compile(k).match(str)
|
300
|
+
stack << from_equip(v)
|
301
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
302
|
+
end
|
303
|
+
end
|
304
|
+
[stack, str]
|
305
|
+
end
|
306
|
+
private def build_sub(stack, str, lassoc)
|
307
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
308
|
+
stack << build_sub(stack, m[2], lassoc)
|
309
|
+
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
310
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
311
|
+
compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
|
312
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
313
|
+
stack[m[1].to_i]
|
314
|
+
else
|
315
|
+
smith(str)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def compose(main, sub)
|
320
|
+
main_k, sub_k = main.kind, sub.kind
|
321
|
+
main_s, sub_s = main.star, sub.star
|
322
|
+
main_main, sub_main = main.main, sub.main
|
323
|
+
main_sub, sub_sub = main.sub, sub.sub
|
324
|
+
|
325
|
+
coef = Equip9[main_k].dup
|
326
|
+
coef.sub!(Equip9[sub_k])
|
327
|
+
coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
|
328
|
+
coef.add!(Material9[main_main]).sub!(Material9[sub_main])
|
329
|
+
den = ( main_k==sub_k ? 200 : 100 )
|
330
|
+
para = Array.new(9) do |i|
|
331
|
+
if EquipFilter[main_k][i] == 0
|
332
|
+
main.para[i]
|
333
|
+
else
|
334
|
+
Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
new(main_k, main_s+sub_s, main_sub, sub_main, para)
|
339
|
+
end
|
340
|
+
def smith(str)
|
341
|
+
str = Mgmg.check_string(str)
|
342
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
343
|
+
raise InvalidSmithError.new(str)
|
344
|
+
end
|
345
|
+
kind = EquipIndex[m[1].to_sym]
|
346
|
+
unless kind
|
347
|
+
raise InvalidEquipClassError.new(m[1])
|
348
|
+
end
|
349
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
350
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
351
|
+
sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
|
352
|
+
|
353
|
+
coef = Equip9[kind].dup
|
354
|
+
coef.e_mul!(Main9[main_m]).e_div!(100)
|
355
|
+
den = ( main_mc==sub_mc ? 200 : 100 )
|
356
|
+
para = Array.new(9) do |i|
|
357
|
+
if coef[i] == 0
|
358
|
+
Mgmg::IR::Const.new(0)
|
359
|
+
else
|
360
|
+
Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
|
365
|
+
end
|
366
|
+
def from_equip(equip)
|
367
|
+
para = equip.para.map do |value|
|
368
|
+
Mgmg::IR::Const.new(value)
|
369
|
+
end
|
370
|
+
new(equip.kind, equip.star, equip.main, equip.sub, para)
|
371
|
+
end
|
372
|
+
end
|
373
|
+
end
|