mgmg 1.3.2 → 1.4.2
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 +21 -0
- data/README.md +42 -244
- data/lib/mgmg/const.rb +2 -1
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +45 -46
- data/lib/mgmg/ir.rb +407 -0
- data/lib/mgmg/poly.rb +11 -2
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +154 -43
- data/lib/mgmg/utils.rb +39 -0
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +54 -16
- data/reference.md +374 -0
- metadata +7 -3
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,10 +52,19 @@ 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, key.min_level(w)]
|
61
|
+
end.to_h
|
62
|
+
end
|
63
|
+
end
|
64
|
+
def min_level(w=1)
|
56
65
|
if @kind == 28
|
57
66
|
ret = [0, 0]
|
58
|
-
|
67
|
+
min_levels(w).each do |str, ml|
|
59
68
|
if str.build(-1).kind < 8
|
60
69
|
if ret[0] < ml
|
61
70
|
ret[0] = ml
|
@@ -68,7 +77,7 @@ module Mgmg
|
|
68
77
|
end
|
69
78
|
ret
|
70
79
|
else
|
71
|
-
|
80
|
+
min_levels(w).values.append(0).max
|
72
81
|
end
|
73
82
|
end
|
74
83
|
|
@@ -83,13 +92,16 @@ module Mgmg
|
|
83
92
|
attack()+str()
|
84
93
|
end
|
85
94
|
def atk_sd
|
86
|
-
attack()
|
95
|
+
attack()+str().quo(2)+dex().quo(2)
|
87
96
|
end
|
88
97
|
def dex_as
|
89
|
-
attack()+str()+dex()
|
98
|
+
attack().quo(2)+str().quo(2)+dex()
|
90
99
|
end
|
91
100
|
def mag_das
|
92
|
-
magic()
|
101
|
+
magic()+dex_as().quo(2)
|
102
|
+
end
|
103
|
+
def magic2
|
104
|
+
magic()*2
|
93
105
|
end
|
94
106
|
[:fire, :earth, :water].each.with_index do |s, i|
|
95
107
|
define_method(s){ @element[i] }
|
@@ -98,35 +110,34 @@ module Mgmg
|
|
98
110
|
def power
|
99
111
|
case @kind
|
100
112
|
when 0, 1
|
101
|
-
atk_sd()
|
113
|
+
atk_sd()
|
102
114
|
when 2, 3
|
103
|
-
atkstr()
|
115
|
+
atkstr()
|
104
116
|
when 4
|
105
|
-
[dex_as()
|
117
|
+
[dex_as(), mag_das()].max
|
106
118
|
when 5
|
107
|
-
dex_as()
|
119
|
+
dex_as()
|
108
120
|
when 6, 7
|
109
|
-
[magic()*
|
121
|
+
[magic()*2, atkstr()].max
|
110
122
|
when 28
|
111
|
-
|
123
|
+
@para.sum-((hp()+mp())*3.quo(4))
|
112
124
|
else
|
113
125
|
ret = @para.max
|
114
126
|
if ret == magdef()
|
115
|
-
ret
|
127
|
+
ret+magic().quo(2)
|
116
128
|
else
|
117
|
-
ret
|
129
|
+
ret
|
118
130
|
end
|
119
131
|
end
|
120
132
|
end
|
121
133
|
def magmag
|
122
|
-
magdef()
|
134
|
+
magdef()+magic().quo(2)
|
123
135
|
end
|
124
136
|
def fpower
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
end
|
137
|
+
power().to_f
|
138
|
+
end
|
139
|
+
def pmdef
|
140
|
+
[phydef(), magmag()].min
|
130
141
|
end
|
131
142
|
|
132
143
|
def smith_cost(outsourcing=false)
|
@@ -146,9 +157,9 @@ module Mgmg
|
|
146
157
|
end
|
147
158
|
def comp_cost(outsourcing=false)
|
148
159
|
if outsourcing
|
149
|
-
[(@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max
|
160
|
+
[(@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp(), 0].max.div(2)
|
150
161
|
else
|
151
|
-
[((@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max
|
162
|
+
[((@star**2)*5+@para.sum+hp().cdiv(4)-hp()+mp().cdiv(4)-mp()).div(2), 0].max.div(2)
|
152
163
|
end
|
153
164
|
end
|
154
165
|
alias :cost :comp_cost
|
@@ -171,8 +182,7 @@ module Mgmg
|
|
171
182
|
end
|
172
183
|
end
|
173
184
|
@weight += other.weight
|
174
|
-
@main = 12
|
175
|
-
@sub = 12
|
185
|
+
@main, @sub = 12, 12
|
176
186
|
@para.add!(other.para)
|
177
187
|
@element.add!(other.element)
|
178
188
|
@total_cost.add!(other.total_cost)
|
@@ -257,7 +267,9 @@ module Mgmg
|
|
257
267
|
|
258
268
|
ret = new(main_k, main.weight+sub.weight, main_s+sub_s, main_sub, sub_main, para, ele)
|
259
269
|
ret.total_cost.add!(main.total_cost).add!(sub.total_cost)
|
260
|
-
|
270
|
+
cc = ret.comp_cost(outsourcing)
|
271
|
+
ret.total_cost[1] += cc
|
272
|
+
ret.total_cost[main_k < 8 ? 0 : 2] += cc
|
261
273
|
ret.min_levels.merge!(main.min_levels, sub.min_levels)
|
262
274
|
ret.history = [*main.history, *sub.history, ret]
|
263
275
|
ret
|
@@ -272,8 +284,8 @@ module Mgmg
|
|
272
284
|
unless kind
|
273
285
|
raise InvalidEquipClassError.new(m[1])
|
274
286
|
end
|
275
|
-
main_m, main_s, main_mc = parse_material(m[2])
|
276
|
-
sub_m, sub_s, sub_mc = parse_material(m[3])
|
287
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
288
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
277
289
|
para = Vec.new(9, 0)
|
278
290
|
ele = Vec.new(3, 0)
|
279
291
|
|
@@ -292,11 +304,7 @@ module Mgmg
|
|
292
304
|
weight = ( ( EquipWeight[kind] + SubWeight[sub_m] - level.div(2) ) * ( MainWeight[main_m] ) ).div(10000)
|
293
305
|
|
294
306
|
ret = new(kind, ( weight<1 ? 1 : weight ), (main_s+sub_s).div(2), main_mc, sub_mc, para, ele)
|
295
|
-
|
296
|
-
ret.total_cost[0] = ret.smith_cost(outsourcing)
|
297
|
-
else
|
298
|
-
ret.total_cost[2] = ret.smith_cost(outsourcing)
|
299
|
-
end
|
307
|
+
ret.total_cost[kind < 8 ? 0 : 2] += ret.smith_cost(outsourcing)
|
300
308
|
ret.min_levels.store(str, str.min_level)
|
301
309
|
ret
|
302
310
|
end
|
@@ -307,23 +315,14 @@ module Mgmg
|
|
307
315
|
raise InvalidSmithError.new(str)
|
308
316
|
end
|
309
317
|
kind = EquipIndex[m[1].to_sym]
|
310
|
-
main_m, main_s, = parse_material(m[2])
|
311
|
-
sub_m, sub_s, = parse_material(m[3])
|
318
|
+
main_m, main_s, = Mgmg.parse_material(m[2])
|
319
|
+
sub_m, sub_s, = Mgmg.parse_material(m[3])
|
312
320
|
|
313
321
|
q, r = ((weight+1)*10000).divmod(MainWeight[main_m])
|
314
322
|
l = ( EquipWeight[kind] + SubWeight[sub_m] - q + ( r==0 ? 1 : 0 ) )*2
|
315
323
|
[(main_s-1)*3, (sub_s-1)*3, l].max
|
316
324
|
end
|
317
325
|
|
318
|
-
private def parse_material(str)
|
319
|
-
m = /\A.+?(\d+)\Z/.match(str)
|
320
|
-
mat = MaterialIndex[str.to_sym]
|
321
|
-
if m.nil? || mat.nil?
|
322
|
-
raise InvalidMaterialError.new(str)
|
323
|
-
end
|
324
|
-
[mat, m[1].to_i, mat<90 ? mat.div(10): 9]
|
325
|
-
end
|
326
|
-
|
327
326
|
def min_comp(str, left_associative: true)
|
328
327
|
str = Mgmg.check_string(str)
|
329
328
|
stack, str = minc_sub0([], str)
|
@@ -388,8 +387,8 @@ module Mgmg
|
|
388
387
|
unless kind
|
389
388
|
raise InvalidEquipClassError.new(m[1])
|
390
389
|
end
|
391
|
-
main_m, main_s, main_mc = parse_material(m[2])
|
392
|
-
sub_m, sub_s, sub_mc = parse_material(m[3])
|
390
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
391
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
393
392
|
[main_s, sub_s].max
|
394
393
|
end
|
395
394
|
end
|
data/lib/mgmg/ir.rb
ADDED
@@ -0,0 +1,407 @@
|
|
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
|
+
def coerce(other)
|
317
|
+
if other == 0
|
318
|
+
zero = self.class.new(28, Vec.new(6, 0), 12, 12, Array.new(9){Const.new(0)})
|
319
|
+
[zero, self]
|
320
|
+
else
|
321
|
+
raise TypeError, "Mgmg::IR can't be coerced into other than 0"
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
class << IR
|
326
|
+
def build(str, left_associative: true, reinforcement: [])
|
327
|
+
str = Mgmg.check_string(str)
|
328
|
+
stack, str = build_sub0([], str)
|
329
|
+
build_sub(stack, str, left_associative).add_reinforcement(reinforcement)
|
330
|
+
end
|
331
|
+
private def build_sub0(stack, str)
|
332
|
+
SystemEquip.each do |k, v|
|
333
|
+
if Regexp.compile(k).match(str)
|
334
|
+
stack << from_equip(v)
|
335
|
+
str = str.gsub(k, "<#{stack.length-1}>")
|
336
|
+
end
|
337
|
+
end
|
338
|
+
[stack, str]
|
339
|
+
end
|
340
|
+
private def build_sub(stack, str, lassoc)
|
341
|
+
if m = /\A(.*\+?)\[([^\[\]]+)\](\+?[^\[]*)\Z/.match(str)
|
342
|
+
stack << build_sub(stack, m[2], lassoc)
|
343
|
+
build_sub(stack, "#{m[1]}<#{stack.length-1}>#{m[3]}", lassoc)
|
344
|
+
elsif m = ( lassoc ? /\A(.+)\+(.+?)\Z/ : /\A(.+?)\+(.+)\Z/ ).match(str)
|
345
|
+
compose(build_sub(stack, m[1], lassoc), build_sub(stack, m[2], lassoc))
|
346
|
+
elsif m = /\A\<(\d+)\>\Z/.match(str)
|
347
|
+
stack[m[1].to_i]
|
348
|
+
else
|
349
|
+
smith(str)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def compose(main, sub)
|
354
|
+
main_k, sub_k = main.kind, sub.kind
|
355
|
+
main_s, sub_s = main.star, sub.star
|
356
|
+
main_main, sub_main = main.main, sub.main
|
357
|
+
main_sub, sub_sub = main.sub, sub.sub
|
358
|
+
|
359
|
+
coef = Equip9[main_k].dup
|
360
|
+
coef.sub!(Equip9[sub_k])
|
361
|
+
coef.add!( 100 + (main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) )
|
362
|
+
coef.add!(Material9[main_main]).sub!(Material9[sub_main])
|
363
|
+
den = ( main_k==sub_k ? 200 : 100 )
|
364
|
+
para = Array.new(9) do |i|
|
365
|
+
if EquipFilter[main_k][i] == 0
|
366
|
+
main.para[i]
|
367
|
+
else
|
368
|
+
Mgmg::IR::Compose.new(main.para[i], sub.para[i], Equip9[main_k][i], coef[i], den)
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
new(main_k, main_s+sub_s, main_sub, sub_main, para)
|
373
|
+
end
|
374
|
+
def smith(str)
|
375
|
+
str = Mgmg.check_string(str)
|
376
|
+
unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
|
377
|
+
raise InvalidSmithError.new(str)
|
378
|
+
end
|
379
|
+
kind = EquipIndex[m[1].to_sym]
|
380
|
+
unless kind
|
381
|
+
raise InvalidEquipClassError.new(m[1])
|
382
|
+
end
|
383
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
384
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
385
|
+
sa = ( Mgmg::EquipPosition[kind] == 0 ? :s : :a )
|
386
|
+
|
387
|
+
coef = Equip9[kind].dup
|
388
|
+
coef.e_mul!(Main9[main_m]).e_div!(100)
|
389
|
+
den = ( main_mc==sub_mc ? 200 : 100 )
|
390
|
+
para = Array.new(9) do |i|
|
391
|
+
if coef[i] == 0
|
392
|
+
Mgmg::IR::Const.new(0)
|
393
|
+
else
|
394
|
+
Mgmg::IR::Smith.new(Sub9[sub_m][i], coef[i], den, sa)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
new(kind, (main_s+sub_s).div(2), main_mc, sub_mc, para)
|
399
|
+
end
|
400
|
+
def from_equip(equip)
|
401
|
+
para = equip.para.map do |value|
|
402
|
+
Mgmg::IR::Const.new(value)
|
403
|
+
end
|
404
|
+
new(equip.kind, equip.star, equip.main, equip.sub, para)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
data/lib/mgmg/poly.rb
CHANGED
@@ -276,6 +276,15 @@ module Mgmg
|
|
276
276
|
end
|
277
277
|
true
|
278
278
|
end
|
279
|
+
def <=>(other)
|
280
|
+
if self == other
|
281
|
+
0
|
282
|
+
elsif self < other
|
283
|
+
-1
|
284
|
+
else
|
285
|
+
1
|
286
|
+
end
|
287
|
+
end
|
279
288
|
end
|
280
289
|
class << TPolynomial
|
281
290
|
ParamIndex = Hash.new
|
@@ -292,8 +301,8 @@ module Mgmg
|
|
292
301
|
raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
|
293
302
|
end
|
294
303
|
kind = EquipIndex[m[1].to_sym]
|
295
|
-
main_m, main_s, main_mc =
|
296
|
-
sub_m, sub_s, sub_mc =
|
304
|
+
main_m, main_s, main_mc = Mgmg.parse_material(m[2])
|
305
|
+
sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
|
297
306
|
para = ParamIndex[para]
|
298
307
|
|
299
308
|
c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Mgmg
|
2
|
+
class Reinforcement
|
3
|
+
def initialize(vec)
|
4
|
+
@vec = vec
|
5
|
+
end
|
6
|
+
attr_accessor :vec
|
7
|
+
def initialize_copy(other)
|
8
|
+
@vec = other.vec.dup
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
'(' + @vec.map.with_index{|e, i| e==0 ? nil : "#{Equip::ParamList[i]}:#{e}"}.compact.join(', ') + ')'
|
13
|
+
end
|
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
|
+
SystemCuisine[arg]
|
46
|
+
else
|
47
|
+
raise ArgumentError, "Unknown skill or preset cuisine name `#{arg}' is given."
|
48
|
+
end
|
49
|
+
else
|
50
|
+
raise ArgumentError, "The argument should be Mgmg::Cuisine or skill name String. (`#{arg}' is given)"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Equip
|
56
|
+
def reinforce(*arg)
|
57
|
+
arg.each do |r|
|
58
|
+
r = Reinforcement.compile(r)
|
59
|
+
@para.map!.with_index do |pr, i|
|
60
|
+
if r.vec[i] == 0
|
61
|
+
pr
|
62
|
+
else
|
63
|
+
pr * (100+r.vec[i]).quo(100)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|