mgmg 1.4.2 → 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 +11 -0
- data/README.md +25 -13
- data/lib/mgmg/equip.rb +18 -23
- data/lib/mgmg/ir.rb +3 -10
- data/lib/mgmg/optimize.rb +21 -9
- data/lib/mgmg/option.rb +85 -0
- data/lib/mgmg/reinforce.rb +3 -3
- data/lib/mgmg/search.rb +182 -222
- data/lib/mgmg/system_equip.rb +6 -0
- data/lib/mgmg/utils.rb +9 -2
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +161 -72
- data/mgmg.gemspec +4 -4
- data/reference.md +127 -48
- metadata +11 -10
data/lib/mgmg/search.rb
CHANGED
@@ -1,288 +1,249 @@
|
|
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, irep: irep)
|
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
|
-
sca, scb = a.search(para, start,
|
231
|
+
opt_a, opt_b = opt_a.dup.set_default(a), opt_b.dup.set_default(b)
|
232
|
+
sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
|
271
233
|
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
|
234
|
+
if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
|
235
|
+
a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
|
275
236
|
end
|
276
|
-
tag =
|
277
|
-
sca, scb = a.search(para, term,
|
237
|
+
tag = opt_a.irep.para_call(para, *sca) + 1
|
238
|
+
sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
|
278
239
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
279
|
-
if ea < eb || ( ea == eb &&
|
240
|
+
if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
|
280
241
|
raise Mgmg::SearchCutException
|
281
242
|
end
|
282
243
|
while tag < term
|
283
|
-
sca, scb = a.search(para, tag,
|
244
|
+
sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
|
284
245
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
285
|
-
pa, pb =
|
246
|
+
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
286
247
|
if eb < ea
|
287
248
|
return [tag-1, pb]
|
288
249
|
elsif ea == eb
|
@@ -298,65 +259,64 @@ module Mgmg
|
|
298
259
|
raise UnexpectedError
|
299
260
|
end
|
300
261
|
|
301
|
-
module_function def find_upperbound(a, b, para, start, term,
|
262
|
+
module_function def find_upperbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
|
302
263
|
if start <= term
|
303
264
|
raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
|
304
265
|
end
|
305
|
-
|
306
|
-
sca, scb = a.search(para, start,
|
266
|
+
opt_a, opt_b = opt_a.dup.set_default(a), opt_b.dup.set_default(b)
|
267
|
+
sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
|
307
268
|
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
|
269
|
+
if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
|
270
|
+
a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
|
311
271
|
end
|
312
|
-
tagu =
|
272
|
+
tagu = opt_a.irep.para_call(para, *sca)
|
313
273
|
sca[-1] -= 2
|
314
|
-
tagl =
|
315
|
-
sca, scb = a.search(para, term,
|
274
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
275
|
+
sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
|
316
276
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
317
|
-
if eb < ea || ( ea == eb &&
|
277
|
+
if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
|
318
278
|
raise Mgmg::SearchCutException
|
319
279
|
end
|
320
280
|
while term < tagu
|
321
281
|
ret = nil
|
322
|
-
sca = a.search(para, tagl,
|
282
|
+
sca = a.search(para, tagl, opt: opt_a)
|
323
283
|
next_tagu, next_sca = tagl, sca
|
324
|
-
scb = b.search(para, tagl,
|
284
|
+
scb = b.search(para, tagl, opt: opt_b)
|
325
285
|
while tagl < tagu
|
326
286
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
327
|
-
pa, pb =
|
287
|
+
pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
|
328
288
|
if ea < eb
|
329
289
|
ret = tagl
|
330
|
-
sca = a.search(para, pa + 1,
|
331
|
-
tagl =
|
332
|
-
scb = b.search(para, tagl,
|
290
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
291
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
292
|
+
scb = b.search(para, tagl, opt: opt_b)
|
333
293
|
elsif ea == eb
|
334
294
|
if pb < pa
|
335
295
|
ret = tagl
|
336
|
-
sca = a.search(para, pa + 1,
|
337
|
-
tagl =
|
338
|
-
scb = b.search(para, tagl,
|
296
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
297
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
298
|
+
scb = b.search(para, tagl, opt: opt_b)
|
339
299
|
else
|
340
|
-
scb = b.search(para, pb + 1,
|
341
|
-
tagl =
|
342
|
-
sca = a.search(para, tagl,
|
300
|
+
scb = b.search(para, pb + 1, opt: opt_b)
|
301
|
+
tagl = opt_b.irep.para_call(para, *scb)
|
302
|
+
sca = a.search(para, tagl, opt: opt_a)
|
343
303
|
end
|
344
304
|
else
|
345
|
-
sca = a.search(para, pa + 1,
|
346
|
-
tagl =
|
347
|
-
scb = b.search(para, tagl,
|
305
|
+
sca = a.search(para, pa + 1, opt: opt_a)
|
306
|
+
tagl = opt_a.irep.para_call(para, *sca)
|
307
|
+
scb = b.search(para, tagl, opt: opt_b)
|
348
308
|
end
|
349
309
|
end
|
350
310
|
if ret.nil?
|
351
311
|
tagu = next_tagu
|
352
312
|
next_sca[-1] -= 2
|
353
|
-
tagl =
|
313
|
+
tagl = opt_a.irep.para_call(para, *next_sca)
|
354
314
|
if tagl == tagu
|
355
315
|
tagl = term
|
356
316
|
end
|
357
317
|
else
|
358
|
-
pa =
|
359
|
-
pb =
|
318
|
+
pa = opt_a.irep.para_call(para, *a.search(para, ret+1, opt: opt_a))
|
319
|
+
pb = opt_b.irep.para_call(para, *b.search(para, ret+1, opt: opt_b))
|
360
320
|
return [ret, [pa, pb].min]
|
361
321
|
end
|
362
322
|
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
|
data/lib/mgmg/utils.rb
CHANGED
@@ -71,6 +71,13 @@ module Mgmg
|
|
71
71
|
end
|
72
72
|
attr_accessor :equip
|
73
73
|
end
|
74
|
+
class InvalidReinforcementNameError < StandardError
|
75
|
+
def initialize(str)
|
76
|
+
@name = str
|
77
|
+
super("Unknown skill or preset cuisine name `#{@name}' is given.")
|
78
|
+
end
|
79
|
+
attr_accessor :name
|
80
|
+
end
|
74
81
|
class SearchCutException < StandardError; end
|
75
82
|
class UnexpectedError < StandardError
|
76
83
|
def initialize()
|
@@ -116,7 +123,7 @@ module Mgmg
|
|
116
123
|
Math.sqrt(exp - ((sa-1)**2) - (2*((comp-1)**2)) - 4).round + 1
|
117
124
|
end
|
118
125
|
|
119
|
-
CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]
|
126
|
+
CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]/.freeze
|
120
127
|
module_function def check_string(str)
|
121
128
|
str = str.gsub(/[\s \\]/, '')
|
122
129
|
if m = CharacterList.match(str)
|
@@ -159,7 +166,7 @@ module Mgmg
|
|
159
166
|
end
|
160
167
|
str
|
161
168
|
end
|
162
|
-
|
169
|
+
|
163
170
|
module_function def parse_material(str)
|
164
171
|
m = /\A.+?(\d+)\Z/.match(str)
|
165
172
|
mat = MaterialIndex[str.to_sym]
|
data/lib/mgmg/version.rb
CHANGED