mgmg 1.4.1 → 1.5.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 +23 -0
- data/README.md +51 -10
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/equip.rb +19 -24
- data/lib/mgmg/ir.rb +401 -373
- data/lib/mgmg/optimize.rb +21 -9
- data/lib/mgmg/option.rb +84 -0
- data/lib/mgmg/poly.rb +2 -2
- data/lib/mgmg/recipe.rb +172 -0
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +204 -222
- data/lib/mgmg/system_equip.rb +6 -0
- data/lib/mgmg/utils.rb +70 -2
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +186 -70
- data/mgmg.gemspec +4 -4
- data/reference.md +271 -49
- metadata +14 -10
data/lib/mgmg/search.rb
CHANGED
@@ -1,288 +1,260 @@
|
|
1
1
|
class String
|
2
|
-
def smith_search(para, target, comp,
|
3
|
-
|
4
|
-
if smith_min
|
5
|
-
|
6
|
-
|
7
|
-
else
|
8
|
-
smith_min = build(-1, -1, left_associative: left_associative).min_level
|
9
|
-
end
|
10
|
-
end
|
11
|
-
if smith_max < smith_min
|
12
|
-
raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{smith_min}, #{smith_max}) are given"
|
13
|
-
elsif cut_exp < Float::INFINITY
|
2
|
+
def smith_search(para, target, comp, opt: Mgmg::Option.new)
|
3
|
+
opt = opt.dup.set_default(self)
|
4
|
+
if opt.smith_max < opt.smith_min
|
5
|
+
raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{opt.smith_min}, #{opt.smith_max}) are given"
|
6
|
+
elsif opt.cut_exp < Float::INFINITY
|
14
7
|
begin
|
15
|
-
smith_max = [smith_max, Mgmg.invexp2(cut_exp, comp)].min
|
8
|
+
opt.smith_max = [opt.smith_max, Mgmg.invexp2(opt.cut_exp, comp)].min
|
16
9
|
rescue
|
17
10
|
raise Mgmg::SearchCutException
|
18
11
|
end
|
19
12
|
end
|
20
|
-
if target <= irep.para_call(para, smith_min, comp)
|
21
|
-
return smith_min
|
22
|
-
elsif irep.para_call(para, smith_max, comp) < target
|
13
|
+
if target <= opt.irep.para_call(para, opt.smith_min, comp)
|
14
|
+
return opt.smith_min
|
15
|
+
elsif opt.irep.para_call(para, opt.smith_max, comp) < target
|
23
16
|
raise Mgmg::SearchCutException
|
24
17
|
end
|
25
|
-
while 1 < smith_max - smith_min do
|
26
|
-
smith = (smith_max - smith_min).div(2) + smith_min
|
27
|
-
if irep.para_call(para, smith, comp) < target
|
28
|
-
smith_min = smith
|
18
|
+
while 1 < opt.smith_max - opt.smith_min do
|
19
|
+
smith = (opt.smith_max - opt.smith_min).div(2) + opt.smith_min
|
20
|
+
if opt.irep.para_call(para, smith, comp) < target
|
21
|
+
opt.smith_min = smith
|
29
22
|
else
|
30
|
-
smith_max = smith
|
23
|
+
opt.smith_max = smith
|
31
24
|
end
|
32
25
|
end
|
33
|
-
smith_max
|
26
|
+
opt.smith_max
|
34
27
|
end
|
35
|
-
def comp_search(para, target, smith,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
elsif irep.para_call(para, smith, comp_max) < target
|
28
|
+
def comp_search(para, target, smith, opt: Mgmg::Option.new)
|
29
|
+
opt = opt.dup.set_default(self)
|
30
|
+
if opt.comp_max < opt.comp_min
|
31
|
+
raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{opt.comp_min}, #{opt.comp_max}) are given"
|
32
|
+
end
|
33
|
+
if target <= opt.irep.para_call(para, smith, opt.comp_min)
|
34
|
+
return opt.comp_min
|
35
|
+
elsif opt.irep.para_call(para, smith, opt.comp_max) < target
|
44
36
|
raise Mgmg::SearchCutException
|
45
37
|
end
|
46
|
-
while 1 < comp_max - comp_min do
|
47
|
-
comp = (comp_max - comp_min).div(2) + comp_min
|
48
|
-
if irep.para_call(para, smith, comp) < target
|
49
|
-
comp_min = comp
|
38
|
+
while 1 < opt.comp_max - opt.comp_min do
|
39
|
+
comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
|
40
|
+
if opt.irep.para_call(para, smith, comp) < target
|
41
|
+
opt.comp_min = comp
|
50
42
|
else
|
51
|
-
comp_max = comp
|
43
|
+
opt.comp_max = comp
|
52
44
|
end
|
53
45
|
end
|
54
|
-
comp_max
|
46
|
+
opt.comp_max
|
55
47
|
end
|
56
|
-
def search(para, target,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
exp = Mgmg.exp(smith_max, comp_min)
|
73
|
-
minex, ret = exp, [smith_max, comp_min] if exp < minex
|
74
|
-
(comp_min+step).step(comp_max-1, step) do |comp|
|
75
|
-
break if minex < Mgmg.exp(smith_min, comp)
|
76
|
-
smith = smith_search(para, target, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min)
|
48
|
+
def search(para, target, opt: Mgmg::Option.new)
|
49
|
+
opt = opt.dup.set_default(self)
|
50
|
+
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
51
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt: opt)
|
52
|
+
opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
|
53
|
+
opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
|
54
|
+
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
|
55
|
+
opt.comp_max = comp_search(para, target, opt.smith_min, opt: opt)
|
56
|
+
ret = nil
|
57
|
+
exp = Mgmg.exp(opt.smith_min, opt.comp_max)
|
58
|
+
opt.cut_exp, ret = exp, [opt.smith_min, opt.comp_max] if exp < opt.cut_exp
|
59
|
+
exp = Mgmg.exp(opt.smith_max, opt.comp_min)
|
60
|
+
opt.cut_exp, ret = exp, [opt.smith_max, opt.comp_min] if exp < opt.cut_exp
|
61
|
+
(opt.comp_min+opt.step).step(opt.comp_max-1, opt.step) do |comp|
|
62
|
+
break if opt.cut_exp < Mgmg.exp(opt.smith_min, comp)
|
63
|
+
smith = smith_search(para, target, comp, opt: opt)
|
77
64
|
exp = Mgmg.exp(smith, comp)
|
78
|
-
if exp <
|
79
|
-
|
80
|
-
elsif exp ==
|
81
|
-
if irep.para_call(para, *ret) < irep.para_call(para, smith, comp)
|
65
|
+
if exp < opt.cut_exp
|
66
|
+
opt.cut_exp, ret = exp, [smith, comp]
|
67
|
+
elsif exp == opt.cut_exp
|
68
|
+
if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, smith, comp) then
|
82
69
|
ret = [smith, comp]
|
83
70
|
end
|
84
71
|
end
|
85
72
|
rescue Mgmg::SearchCutException
|
86
73
|
end
|
87
|
-
raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{cut_exp}" if
|
74
|
+
raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{opt.cut_exp}" if ret.nil?
|
88
75
|
ret
|
89
76
|
end
|
90
77
|
end
|
91
78
|
module Enumerable
|
92
|
-
def smith_search(para, target, armor, comp,
|
93
|
-
|
94
|
-
if smith_min
|
95
|
-
|
96
|
-
|
97
|
-
else
|
98
|
-
smith_min = build(-1, -1, -1, left_associative: left_associative).min_level[0]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
if smith_max < smith_min
|
102
|
-
raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{smith_min}, #{smith_max}) are given"
|
103
|
-
elsif cut_exp < Float::INFINITY
|
79
|
+
def smith_search(para, target, armor, comp, opt: Mgmg::Option.new)
|
80
|
+
opt = opt.dup.set_default(self)
|
81
|
+
if opt.smith_max < opt.smith_min
|
82
|
+
raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{opt.smith_min}, #{opt.smith_max}) are given"
|
83
|
+
elsif opt.cut_exp < Float::INFINITY
|
104
84
|
begin
|
105
|
-
smith_max = [smith_max, Mgmg.invexp3(cut_exp, armor, comp)].min
|
85
|
+
opt.smith_max = [opt.smith_max, Mgmg.invexp3(opt.cut_exp, armor, comp)].min
|
106
86
|
rescue
|
107
87
|
raise Mgmg::SearchCutException
|
108
88
|
end
|
109
89
|
end
|
110
|
-
if irep.para_call(para, smith_max, armor, comp) < target
|
90
|
+
if opt.irep.para_call(para, opt.smith_max, armor, comp) < target
|
111
91
|
raise Mgmg::SearchCutException
|
112
|
-
elsif target <= irep.para_call(para, smith_min, armor, comp)
|
113
|
-
return smith_min
|
92
|
+
elsif target <= opt.irep.para_call(para, opt.smith_min, armor, comp)
|
93
|
+
return opt.smith_min
|
114
94
|
end
|
115
|
-
while 1 < smith_max - smith_min do
|
116
|
-
smith = (smith_max - smith_min).div(2) + smith_min
|
117
|
-
if irep.para_call(para, smith, armor, comp) < target
|
118
|
-
smith_min = smith
|
95
|
+
while 1 < opt.smith_max - opt.smith_min do
|
96
|
+
smith = (opt.smith_max - opt.smith_min).div(2) + opt.smith_min
|
97
|
+
if opt.irep.para_call(para, smith, armor, comp) < target
|
98
|
+
opt.smith_min = smith
|
119
99
|
else
|
120
|
-
smith_max = smith
|
100
|
+
opt.smith_max = smith
|
121
101
|
end
|
122
102
|
end
|
123
|
-
smith_max
|
103
|
+
opt.smith_max
|
124
104
|
end
|
125
|
-
def armor_search(para, target, smith, comp,
|
126
|
-
|
127
|
-
if armor_min
|
128
|
-
|
129
|
-
|
130
|
-
else
|
131
|
-
armor_min = build(-1, -1, -1, left_associative: left_associative).min_level[1]
|
132
|
-
end
|
133
|
-
end
|
134
|
-
if armor_max < armor_min
|
135
|
-
raise ArgumentError, "armor_min <= armor_max is needed, (armor_min, armor_max) = (#{armor_min}, #{armor_max}) are given"
|
136
|
-
elsif cut_exp < Float::INFINITY
|
105
|
+
def armor_search(para, target, smith, comp, opt: Mgmg::Option.new)
|
106
|
+
opt = opt.dup.set_default(self)
|
107
|
+
if opt.armor_max < opt.armor_min
|
108
|
+
raise ArgumentError, "armor_min <= armor_max is needed, (armor_min, armor_max) = (#{opt.armor_min}, #{opt.armor_max}) are given"
|
109
|
+
elsif opt.cut_exp < Float::INFINITY
|
137
110
|
begin
|
138
|
-
armor_max = [armor_max, Mgmg.invexp3(cut_exp, smith, comp)].min
|
111
|
+
opt.armor_max = [opt.armor_max, Mgmg.invexp3(opt.cut_exp, smith, comp)].min
|
139
112
|
rescue
|
140
113
|
raise Mgmg::SearchCutException
|
141
114
|
end
|
142
115
|
end
|
143
|
-
if irep.para_call(para, smith, armor_max, comp) < target
|
116
|
+
if opt.irep.para_call(para, smith, opt.armor_max, comp) < target
|
144
117
|
raise Mgmg::SearchCutException
|
145
|
-
elsif target <= irep.para_call(para, smith, armor_min, comp)
|
146
|
-
return armor_min
|
118
|
+
elsif target <= opt.irep.para_call(para, smith, opt.armor_min, comp)
|
119
|
+
return opt.armor_min
|
147
120
|
end
|
148
|
-
while 1 < armor_max - armor_min do
|
149
|
-
armor = (armor_max - armor_min).div(2) + armor_min
|
150
|
-
if irep.para_call(para, smith, armor, comp) < target
|
151
|
-
armor_min = armor
|
121
|
+
while 1 < opt.armor_max - opt.armor_min do
|
122
|
+
armor = (opt.armor_max - opt.armor_min).div(2) + opt.armor_min
|
123
|
+
if opt.irep.para_call(para, smith, armor, comp) < target
|
124
|
+
opt.armor_min = armor
|
152
125
|
else
|
153
|
-
armor_max = armor
|
126
|
+
opt.armor_max = armor
|
154
127
|
end
|
155
128
|
end
|
156
|
-
armor_max
|
129
|
+
opt.armor_max
|
157
130
|
end
|
158
|
-
def sa_search(para, target, comp,
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
minex, ret = exp, [smith_max, armor_min]
|
176
|
-
(armor_min+1).upto(armor_max-1) do |armor|
|
177
|
-
break if minex < Mgmg.exp(smith_min, armor, comp)
|
178
|
-
smith = smith_search(para, target, armor, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
|
131
|
+
def sa_search(para, target, comp, opt: Mgmg::Option.new)
|
132
|
+
opt = opt.dup.set_default(self)
|
133
|
+
opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
|
134
|
+
opt.smith_min = smith_search(para, target, opt.armor_max, comp, opt: opt_nocut)
|
135
|
+
opt.armor_min = armor_search(para, target, opt.smith_max, comp, opt: opt_nocut)
|
136
|
+
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, comp)
|
137
|
+
opt.smith_max = smith_search(para, target, opt.armor_min, comp, opt: opt_nocut)
|
138
|
+
opt.armor_max = armor_search(para, target, opt.smith_min, comp, opt: opt_nocut)
|
139
|
+
ret = nil
|
140
|
+
exp = Mgmg.exp(opt.smith_min, opt.armor_max, comp)
|
141
|
+
opt.cut_exp, ret = exp, [opt.smith_min, opt.armor_max] if exp < opt.cut_exp
|
142
|
+
exp2 = Mgmg.exp(opt.smith_max, opt.armor_min, comp)
|
143
|
+
if exp2 < exp
|
144
|
+
opt.cut_exp, ret = exp2, [opt.smith_max, opt.armor_min] if exp2 < opt.cut_exp
|
145
|
+
(opt.armor_min+1).upto(opt.armor_max-1) do |armor|
|
146
|
+
break if opt.cut_exp < Mgmg.exp(opt.smith_min, armor, comp)
|
147
|
+
smith = smith_search(para, target, armor, comp, opt: opt)
|
179
148
|
exp = Mgmg.exp(smith, armor, comp)
|
180
|
-
if exp <
|
181
|
-
|
182
|
-
elsif exp ==
|
183
|
-
if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
|
149
|
+
if exp < opt.cut_exp
|
150
|
+
opt.cut_exp, ret = exp, [smith, armor]
|
151
|
+
elsif exp == opt.cut_exp
|
152
|
+
if ret.nil? or opt.irep.para_call(para, *ret, comp) < opt.irep.para_call(para, smith, armor, comp) then
|
184
153
|
ret = [smith, armor]
|
185
154
|
end
|
186
155
|
end
|
187
156
|
rescue Mgmg::SearchCutException
|
188
157
|
end
|
189
158
|
else
|
190
|
-
(smith_min+1).upto(smith_max-1) do |smith|
|
191
|
-
break if
|
192
|
-
armor = armor_search(para, target, smith, comp,
|
159
|
+
(opt.smith_min+1).upto(opt.smith_max-1) do |smith|
|
160
|
+
break if opt.cut_exp < Mgmg.exp(smith, opt.armor_min, comp)
|
161
|
+
armor = armor_search(para, target, smith, comp, opt: opt)
|
193
162
|
exp = Mgmg.exp(smith, armor, comp)
|
194
|
-
if exp <
|
195
|
-
|
196
|
-
elsif exp ==
|
197
|
-
if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
|
163
|
+
if exp < opt.cut_exp
|
164
|
+
opt.cut_exp, ret = exp, [smith, armor]
|
165
|
+
elsif exp == opt.cut_exp
|
166
|
+
if ret.nil? or opt.irep.para_call(para, *ret, comp) < opt.irep.para_call(para, smith, armor, comp) then
|
198
167
|
ret = [smith, armor]
|
199
168
|
end
|
200
169
|
end
|
201
170
|
rescue Mgmg::SearchCutException
|
202
171
|
end
|
203
172
|
end
|
204
|
-
raise Mgmg::SearchCutException if
|
173
|
+
raise Mgmg::SearchCutException if ret.nil?
|
205
174
|
ret
|
206
175
|
end
|
207
|
-
def comp_search(para, target, smith, armor,
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
comp_min = comp
|
176
|
+
def comp_search(para, target, smith, armor, opt: Mgmg::Option.new)
|
177
|
+
opt = opt.dup.set_default(self)
|
178
|
+
if opt.comp_max < opt.comp_min
|
179
|
+
raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{opt.comp_min}, #{opt.comp_max}) are given"
|
180
|
+
end
|
181
|
+
if target <= opt.irep.para_call(para, smith, armor, opt.comp_min)
|
182
|
+
return opt.comp_min
|
183
|
+
elsif opt.irep.para_call(para, smith, armor, opt.comp_max) < target
|
184
|
+
raise ArgumentError, "given comp_max=#{opt.comp_max} does not satisfies the target"
|
185
|
+
end
|
186
|
+
while 1 < opt.comp_max - opt.comp_min do
|
187
|
+
comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
|
188
|
+
if opt.irep.para_call(para, smith, armor, comp) < target
|
189
|
+
opt.comp_min = comp
|
222
190
|
else
|
223
|
-
comp_max = comp
|
191
|
+
opt.comp_max = comp
|
224
192
|
end
|
225
193
|
end
|
226
|
-
comp_max
|
194
|
+
opt.comp_max
|
227
195
|
end
|
228
|
-
def search(para, target,
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
minex, ret = Mgmg.exp(smith_min, armor_min, comp_max), [smith_min, armor_min, comp_max]
|
244
|
-
exp = Mgmg.exp(smith_max, armor_max, comp_min)
|
245
|
-
minex, ret = exp, [smith_max, armor_max, comp_min] if exp < minex
|
246
|
-
(comp_min+1).upto(comp_max-1) do |comp|
|
247
|
-
break if minex < Mgmg.exp(smith_min, armor_min, comp)
|
248
|
-
smith, armor = sa_search(para, target, comp, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
|
196
|
+
def search(para, target, opt: Mgmg::Option.new)
|
197
|
+
opt = opt.dup.set_default(self)
|
198
|
+
opt.comp_min = comp_search(para, target, opt.smith_max, opt.armor_max, opt: opt)
|
199
|
+
opt.smith_max, opt.armor_max = sa_search(para, target, opt.comp_min, opt: opt)
|
200
|
+
opt.smith_min, opt.armor_min = sa_search(para, target, opt.comp_max, opt: opt)
|
201
|
+
raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_min)
|
202
|
+
opt.comp_max = comp_search(para, target, opt.smith_min, opt.armor_min, opt: opt)
|
203
|
+
ret = nil
|
204
|
+
exp = Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_max)
|
205
|
+
opt.cut_exp, ret = exp, [opt.smith_min, opt.armor_min,opt. comp_max] if exp < opt.cut_exp
|
206
|
+
exp = Mgmg.exp(opt.smith_max, opt.armor_max, opt.comp_min)
|
207
|
+
opt.cut_exp, ret = exp, [opt.smith_max, opt.armor_max, opt.comp_min] if exp < opt.cut_exp
|
208
|
+
(opt.comp_min+1).upto(opt.comp_max-1) do |comp|
|
209
|
+
break if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, comp)
|
210
|
+
smith, armor = sa_search(para, target, comp, opt: opt)
|
249
211
|
exp = Mgmg.exp(smith, armor, comp)
|
250
|
-
if exp <
|
251
|
-
|
252
|
-
elsif exp ==
|
253
|
-
if irep.para_call(para, *ret) < irep.para_call(para, smith, armor, comp)
|
212
|
+
if exp < opt.cut_exp
|
213
|
+
opt.cut_exp, ret = exp, [smith, armor, comp]
|
214
|
+
elsif exp == opt.cut_exp
|
215
|
+
if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, smith, armor, comp) then
|
254
216
|
ret = [smith, armor, comp]
|
255
217
|
end
|
256
218
|
end
|
257
219
|
rescue Mgmg::SearchCutException
|
258
220
|
end
|
259
|
-
raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{cut_exp}" if
|
221
|
+
raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{opt.cut_exp}" if ret.nil?
|
260
222
|
ret
|
261
223
|
end
|
262
224
|
end
|
263
225
|
|
264
226
|
module Mgmg
|
265
|
-
module_function def find_lowerbound(a, b, para, start, term,
|
227
|
+
module_function def find_lowerbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
|
266
228
|
if term <= start
|
267
229
|
raise ArgumentError, "start < term is needed, (start, term) = (#{start}, #{term}) are given"
|
268
230
|
end
|
269
|
-
|
270
|
-
|
231
|
+
if a.kind_of?(Recipe)
|
232
|
+
opt_a = a.option.dup
|
233
|
+
a = a.recipe
|
234
|
+
else
|
235
|
+
opt_a = opt_a.dup.set_default(a)
|
236
|
+
end
|
237
|
+
if b.kind_of?(Recipe)
|
238
|
+
opt_b = b.option.dup
|
239
|
+
b = b.recipe
|
240
|
+
else
|
241
|
+
opt_b = opt_b.dup.set_default(b)
|
242
|
+
end
|
243
|
+
sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
|
271
244
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
272
|
-
if eb < ea || ( ea == eb &&
|
273
|
-
a, b,
|
274
|
-
smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
|
245
|
+
if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
|
246
|
+
a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
|
275
247
|
end
|
276
|
-
tag =
|
277
|
-
sca, scb = a.search(para, term,
|
248
|
+
tag = opt_a.irep.para_call(para, *sca) + 1
|
249
|
+
sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
|
278
250
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
279
|
-
if ea < eb || ( ea == eb &&
|
251
|
+
if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
|
280
252
|
raise Mgmg::SearchCutException
|
281
253
|
end
|
282
254
|
while tag < term
|
283
|
-
sca, scb = a.search(para, tag,
|
255
|
+
sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
|
284
256
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
285
|
-
pa, pb =
|
257
|
+
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
286
258
|
if eb < ea
|
287
259
|
return [tag-1, pb]
|
288
260
|
elsif ea == eb
|
@@ -298,65 +270,75 @@ module Mgmg
|
|
298
270
|
raise UnexpectedError
|
299
271
|
end
|
300
272
|
|
301
|
-
module_function def find_upperbound(a, b, para, start, term,
|
273
|
+
module_function def find_upperbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
|
302
274
|
if start <= term
|
303
275
|
raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
|
304
276
|
end
|
305
|
-
|
306
|
-
|
277
|
+
if a.kind_of?(Recipe)
|
278
|
+
opt_a = a.option.dup
|
279
|
+
a = a.recipe
|
280
|
+
else
|
281
|
+
opt_a = opt_a.dup.set_default(a)
|
282
|
+
end
|
283
|
+
if b.kind_of?(Recipe)
|
284
|
+
opt_b = b.option.dup
|
285
|
+
b = b.recipe
|
286
|
+
else
|
287
|
+
opt_b = opt_b.dup.set_default(b)
|
288
|
+
end
|
289
|
+
sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
|
307
290
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
308
|
-
if ea < eb || ( ea == eb &&
|
309
|
-
a, b,
|
310
|
-
smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
|
291
|
+
if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
|
292
|
+
a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
|
311
293
|
end
|
312
|
-
tagu =
|
294
|
+
tagu = opt_a.irep.para_call(para, *sca)
|
313
295
|
sca[-1] -= 2
|
314
|
-
tagl =
|
315
|
-
sca, scb = a.search(para, term,
|
296
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
297
|
+
sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
|
316
298
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
317
|
-
if eb < ea || ( ea == eb &&
|
299
|
+
if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
|
318
300
|
raise Mgmg::SearchCutException
|
319
301
|
end
|
320
302
|
while term < tagu
|
321
303
|
ret = nil
|
322
|
-
sca = a.search(para, tagl,
|
304
|
+
sca = a.search(para, tagl, opt: opt_a)
|
323
305
|
next_tagu, next_sca = tagl, sca
|
324
|
-
scb = b.search(para, tagl,
|
306
|
+
scb = b.search(para, tagl, opt: opt_b)
|
325
307
|
while tagl < tagu
|
326
308
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
327
|
-
pa, pb =
|
309
|
+
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
328
310
|
if ea < eb
|
329
311
|
ret = tagl
|
330
|
-
sca = a.search(para, pa + 1,
|
331
|
-
tagl =
|
332
|
-
scb = b.search(para, tagl,
|
312
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
313
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
314
|
+
scb = b.search(para, tagl, opt: opt_b)
|
333
315
|
elsif ea == eb
|
334
316
|
if pb < pa
|
335
317
|
ret = tagl
|
336
|
-
sca = a.search(para, pa + 1,
|
337
|
-
tagl =
|
338
|
-
scb = b.search(para, tagl,
|
318
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
319
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
320
|
+
scb = b.search(para, tagl, opt: opt_b)
|
339
321
|
else
|
340
|
-
scb = b.search(para, pb + 1,
|
341
|
-
tagl =
|
342
|
-
sca = a.search(para, tagl,
|
322
|
+
scb = b.search(para, pb + 1, opt: opt_b)
|
323
|
+
tagl = opt_b.irep.para_call(para, *scb)
|
324
|
+
sca = a.search(para, tagl, opt: opt_a)
|
343
325
|
end
|
344
326
|
else
|
345
|
-
sca = a.search(para, pa + 1,
|
346
|
-
tagl =
|
347
|
-
scb = b.search(para, tagl,
|
327
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
328
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
329
|
+
scb = b.search(para, tagl, opt: opt_b)
|
348
330
|
end
|
349
331
|
end
|
350
332
|
if ret.nil?
|
351
333
|
tagu = next_tagu
|
352
334
|
next_sca[-1] -= 2
|
353
|
-
tagl =
|
335
|
+
tagl = opt_a.irep.para_call(para, *next_sca)
|
354
336
|
if tagl == tagu
|
355
337
|
tagl = term
|
356
338
|
end
|
357
339
|
else
|
358
|
-
pa =
|
359
|
-
pb =
|
340
|
+
pa = opt_a.irep.para_call(para, *a.search(para, ret+1, opt: opt_a))
|
341
|
+
pb = opt_b.irep.para_call(para, *b.search(para, ret+1, opt: opt_b))
|
360
342
|
return [ret, [pa, pb].min]
|
361
343
|
end
|
362
344
|
end
|
data/lib/mgmg/system_equip.rb
CHANGED
@@ -323,4 +323,10 @@ module Mgmg
|
|
323
323
|
SystemEquip.store(k.sub(/脛当て\Z/, 'すね当て'), SystemEquip[k])
|
324
324
|
end
|
325
325
|
end
|
326
|
+
SystemEquip.freeze
|
327
|
+
SystemEquipRegexp = Hash.new
|
328
|
+
SystemEquip.keys.each do |k|
|
329
|
+
SystemEquipRegexp.store(k.freeze, Regexp.compile(k))
|
330
|
+
end
|
331
|
+
SystemEquipRegexp.freeze
|
326
332
|
end
|