mgmg 1.4.1 → 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 +5 -0
- data/README.md +12 -2
- data/lib/mgmg/cuisine.rb +140 -0
- data/lib/mgmg/ir.rb +407 -373
- data/lib/mgmg/poly.rb +2 -2
- data/lib/mgmg/reinforce.rb +70 -0
- data/lib/mgmg/search.rb +21 -21
- data/lib/mgmg/utils.rb +25 -0
- data/lib/mgmg/version.rb +1 -1
- data/lib/mgmg.rb +29 -13
- data/reference.md +100 -15
- metadata +5 -3
data/lib/mgmg/poly.rb
CHANGED
@@ -301,8 +301,8 @@ module Mgmg
|
|
301
301
|
raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
|
302
302
|
end
|
303
303
|
kind = EquipIndex[m[1].to_sym]
|
304
|
-
main_m, main_s, main_mc =
|
305
|
-
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])
|
306
306
|
para = ParamIndex[para]
|
307
307
|
|
308
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
|
data/lib/mgmg/search.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
class String
|
2
|
-
def smith_search(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
3
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
2
|
+
def smith_search(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
3
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
4
4
|
if smith_min.nil?
|
5
5
|
if min_smith
|
6
6
|
smith_min = self.min_smith.min_smith
|
@@ -32,8 +32,8 @@ class String
|
|
32
32
|
end
|
33
33
|
smith_max
|
34
34
|
end
|
35
|
-
def comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true, irep: nil)
|
36
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
35
|
+
def comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true, irep: nil, reinforcement: [])
|
36
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
37
37
|
comp_min = min_comp(left_associative: left_associative)
|
38
38
|
if comp_max < comp_min
|
39
39
|
raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
|
@@ -53,8 +53,8 @@ class String
|
|
53
53
|
end
|
54
54
|
comp_max
|
55
55
|
end
|
56
|
-
def search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
57
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
56
|
+
def search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
57
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
58
58
|
if smith_min.nil?
|
59
59
|
if min_smith
|
60
60
|
smith_min = self.min_smith
|
@@ -73,7 +73,7 @@ class String
|
|
73
73
|
minex, ret = exp, [smith_max, comp_min] if exp < minex
|
74
74
|
(comp_min+step).step(comp_max-1, step) do |comp|
|
75
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)
|
76
|
+
smith = smith_search(para, target, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
|
77
77
|
exp = Mgmg.exp(smith, comp)
|
78
78
|
if exp < minex
|
79
79
|
minex, ret = exp, [smith, comp]
|
@@ -89,8 +89,8 @@ class String
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
module Enumerable
|
92
|
-
def smith_search(para, target, armor, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
93
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
92
|
+
def smith_search(para, target, armor, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
93
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
94
94
|
if smith_min.nil?
|
95
95
|
if min_smith
|
96
96
|
smith_min = self.min_smith[0]
|
@@ -122,8 +122,8 @@ module Enumerable
|
|
122
122
|
end
|
123
123
|
smith_max
|
124
124
|
end
|
125
|
-
def armor_search(para, target, smith, comp, armor_min=nil, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
126
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
125
|
+
def armor_search(para, target, smith, comp, armor_min=nil, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
126
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
127
127
|
if armor_min.nil?
|
128
128
|
if min_smith
|
129
129
|
armor_min = self.min_smith[1]
|
@@ -155,8 +155,8 @@ module Enumerable
|
|
155
155
|
end
|
156
156
|
armor_max
|
157
157
|
end
|
158
|
-
def sa_search(para, target, comp, smith_min=nil, armor_min=nil, smith_max=10000, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
159
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
158
|
+
def sa_search(para, target, comp, smith_min=nil, armor_min=nil, smith_max=10000, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
159
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
160
160
|
if min_smith
|
161
161
|
s, a = self.min_smith
|
162
162
|
else
|
@@ -204,8 +204,8 @@ module Enumerable
|
|
204
204
|
raise Mgmg::SearchCutException if cut_exp < minex
|
205
205
|
ret
|
206
206
|
end
|
207
|
-
def comp_search(para, target, smith, armor, comp_min=nil, comp_max=10000, left_associative: true, irep: nil)
|
208
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
207
|
+
def comp_search(para, target, smith, armor, comp_min=nil, comp_max=10000, left_associative: true, irep: nil, reinforcement: [])
|
208
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
209
209
|
comp_min = min_comp(left_associative: left_associative)
|
210
210
|
if comp_max < comp_min
|
211
211
|
raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
|
@@ -225,8 +225,8 @@ module Enumerable
|
|
225
225
|
end
|
226
226
|
comp_max
|
227
227
|
end
|
228
|
-
def search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil)
|
229
|
-
irep = ir(left_associative: left_associative) if irep.nil?
|
228
|
+
def search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
|
229
|
+
irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
|
230
230
|
if min_smith
|
231
231
|
s, a = self.min_smith
|
232
232
|
else
|
@@ -262,11 +262,11 @@ module Enumerable
|
|
262
262
|
end
|
263
263
|
|
264
264
|
module Mgmg
|
265
|
-
module_function def find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)
|
265
|
+
module_function def find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])
|
266
266
|
if term <= start
|
267
267
|
raise ArgumentError, "start < term is needed, (start, term) = (#{start}, #{term}) are given"
|
268
268
|
end
|
269
|
-
ira, irb = a.ir, b.ir
|
269
|
+
ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
|
270
270
|
sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
|
271
271
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
272
272
|
if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
|
@@ -298,11 +298,11 @@ module Mgmg
|
|
298
298
|
raise UnexpectedError
|
299
299
|
end
|
300
300
|
|
301
|
-
module_function def find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)
|
301
|
+
module_function def find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])
|
302
302
|
if start <= term
|
303
303
|
raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
|
304
304
|
end
|
305
|
-
ira, irb = a.ir, b.ir
|
305
|
+
ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
|
306
306
|
sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
|
307
307
|
ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
|
308
308
|
if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
|
data/lib/mgmg/utils.rb
CHANGED
@@ -14,6 +14,31 @@ module Mgmg
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
+
refine Float do
|
18
|
+
alias :cdiv :quo # Floatの場合は普通の割り算
|
19
|
+
def comma3
|
20
|
+
s = self.to_s
|
21
|
+
case s
|
22
|
+
when %r|e|
|
23
|
+
s
|
24
|
+
when %r|\.|
|
25
|
+
ary = s.split('.')
|
26
|
+
ary[0].gsub(/(\d)(?=(\d{3})+(?!\d))/, '\1,') + '.' + ary[1]
|
27
|
+
else
|
28
|
+
s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
refine Rational do
|
33
|
+
alias :cdiv :quo # Rationalの場合は普通の割り算
|
34
|
+
def comma3
|
35
|
+
if self.denominator == 1
|
36
|
+
self.numerator.comma3
|
37
|
+
else
|
38
|
+
self.to_f.comma3
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
17
42
|
end
|
18
43
|
using Refiner
|
19
44
|
|
data/lib/mgmg/version.rb
CHANGED
data/lib/mgmg.rb
CHANGED
@@ -5,6 +5,8 @@ require_relative './mgmg/equip'
|
|
5
5
|
require_relative './mgmg/poly'
|
6
6
|
require_relative './mgmg/ir'
|
7
7
|
require_relative './mgmg/system_equip'
|
8
|
+
require_relative './mgmg/cuisine'
|
9
|
+
require_relative './mgmg/reinforce'
|
8
10
|
require_relative './mgmg/search'
|
9
11
|
require_relative './mgmg/optimize'
|
10
12
|
|
@@ -24,8 +26,8 @@ class String
|
|
24
26
|
def build(smith=-1, comp=smith, left_associative: true)
|
25
27
|
Mgmg::Equip.build(self, smith, comp, left_associative: left_associative)
|
26
28
|
end
|
27
|
-
def ir(left_associative: true)
|
28
|
-
Mgmg::IR.build(self, left_associative: left_associative)
|
29
|
+
def ir(left_associative: true, reinforcement: [])
|
30
|
+
Mgmg::IR.build(self, left_associative: left_associative, reinforcement: reinforcement)
|
29
31
|
end
|
30
32
|
def poly(para=:cost, left_associative: true)
|
31
33
|
la = left_associative
|
@@ -70,13 +72,20 @@ class String
|
|
70
72
|
def peff(para, smith, comp=smith, left_associative: true)
|
71
73
|
poly(para, left_associative: left_associative).eff(smith, comp)
|
72
74
|
end
|
73
|
-
def show(smith=-1, comp=smith, left_associative: true, para: :power)
|
74
|
-
|
75
|
+
def show(smith=-1, comp=smith, left_associative: true, para: :power, reinforcement: [])
|
76
|
+
rein = case reinforcement
|
77
|
+
when Array
|
78
|
+
reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
79
|
+
else
|
80
|
+
[Mgmg::Reinforcement.compile(reinforcement)]
|
81
|
+
end
|
82
|
+
built = self.build(smith, comp, left_associative: left_associative).reinforce(*rein)
|
75
83
|
pstr = '%.3f' % built.para_call(para)
|
76
84
|
pstr.sub!(/\.?0+\Z/, '')
|
77
85
|
puts "Building"
|
78
86
|
puts " #{self}"
|
79
|
-
|
87
|
+
rein = rein.empty? ? '' : " reinforced by {#{rein.join(',')}}"
|
88
|
+
puts "with levels (#{smith}, #{comp})#{rein} yields (#{pstr}, #{built.total_cost})"
|
80
89
|
puts " #{built}"
|
81
90
|
end
|
82
91
|
def phydef_optimize(smith=nil, comp=smith, left_associative: true, magdef_maximize: true)
|
@@ -88,27 +97,34 @@ class String
|
|
88
97
|
end
|
89
98
|
module Enumerable
|
90
99
|
def build(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true)
|
91
|
-
self.
|
100
|
+
self.sum do |str|
|
92
101
|
m = /\A\[*([^\+]+)/.match(str)
|
93
102
|
if Mgmg::EquipPosition[m[1].build(0).kind] == 0
|
94
103
|
str.build(smith, comp, left_associative: left_associative)
|
95
104
|
else
|
96
105
|
str.build(armor, comp, left_associative: left_associative)
|
97
106
|
end
|
98
|
-
end
|
107
|
+
end
|
99
108
|
end
|
100
|
-
def ir(left_associative: true)
|
101
|
-
self.
|
109
|
+
def ir(left_associative: true, reinforcement: [])
|
110
|
+
self.sum do |str|
|
102
111
|
str.ir(left_associative: left_associative)
|
103
|
-
end.
|
112
|
+
end.add_reinforcement(reinforcement)
|
104
113
|
end
|
105
|
-
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true, para: :power)
|
106
|
-
|
114
|
+
def show(smith=-1, armor=smith, comp=armor.tap{armor=smith}, left_associative: true, para: :power, reinforcement: [])
|
115
|
+
rein = case reinforcement
|
116
|
+
when Array
|
117
|
+
reinforcement.map{|r| Mgmg::Reinforcement.compile(r)}
|
118
|
+
else
|
119
|
+
[Mgmg::Reinforcement.compile(reinforcement)]
|
120
|
+
end
|
121
|
+
built = self.build(smith, armor, comp, left_associative: left_associative).reinforce(*rein)
|
107
122
|
pstr = '%.3f' % built.para_call(para)
|
108
123
|
pstr.sub!(/\.?0+\Z/, '')
|
109
124
|
puts "Building"
|
110
125
|
puts " #{self.join(', ')}"
|
111
|
-
|
126
|
+
rein = rein.empty? ? '' : " reinforced by {#{rein.join(',')}}"
|
127
|
+
puts "with levels (#{smith}, #{armor}, #{comp})#{rein} yields (#{pstr}, #{built.total_cost})"
|
112
128
|
puts " #{built}"
|
113
129
|
end
|
114
130
|
def min_levels(w=1, left_associative: true)
|
data/reference.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
本ライブラリで定義される主要なメソッドを以下に解説します.
|
3
3
|
|
4
4
|
## `String#build(smith=-1, comp=smith, left_associative: true)`
|
5
|
-
レシピ文字列である`self`を解釈し,鍛冶・防具製作Lvを`smith`,道具製作Lvを`comp
|
5
|
+
レシピ文字列である`self`を解釈し,鍛冶・防具製作Lvを`smith`,道具製作Lvを`comp`として鍛冶・防具製作及び武器・防具合成を行った結果を[後述](#mgmgequip)の`Mgmg::Equip`クラスのインスタンスとして生成し,返します.例えば,
|
6
6
|
```ruby
|
7
7
|
'[杖(水玉10火玉5)+本(骨10鉄1)]+[本(水玉5綿2)+杖(骨10鉄1)]'.build(112, 176)
|
8
8
|
```
|
@@ -55,38 +55,45 @@
|
|
55
55
|
|
56
56
|
また,`:cost`を渡すことで,消費エレメント量に関する近似多項式を得られます.`self`に`"+"`が含まれていれば合成品とみなし,最後の合成に必要な地エレメント量を,それ以外では,武器なら消費火エレメント量を,防具なら消費水エレメント量を返します.ただし,`self`が既成品そのものの場合,零多項式を返します.
|
57
57
|
|
58
|
-
## `String#ir(left_associative: true)`
|
59
|
-
レシピ文字列である`self`を解釈し,9パラ値について,丸めを考慮した鍛冶・防具製作Lvと道具製作Lvの2変数からなる関数オブジェクトを保持する`Mgmg::IR
|
58
|
+
## `String#ir(left_associative: true, reinforcement: [])`
|
59
|
+
レシピ文字列である`self`を解釈し,9パラ値について,丸めを考慮した鍛冶・防具製作Lvと道具製作Lvの2変数からなる関数オブジェクトを保持する`Mgmg::IR`クラスのインスタンスを生成し,返します.詳しくは,[後述](#mgmgir)の`Mgmg::IR`クラスの説明を参照ください.
|
60
60
|
|
61
|
-
|
61
|
+
`reinforcement`には,[後述](#mgmgequipreinforcearg)の`Mgmg::Equip#reinforce`に渡す引数と同様のものを,一つの配列にまとめて渡します.強化が一つだけの場合,その引数を裸で渡すこともできます.
|
62
|
+
|
63
|
+
## `Enumerable#ir(left_associative: true, reinforcement: [])`
|
62
64
|
複数のレシピ文字列からなる`self`の各要素を製作し,そのすべてを装備したときの`Mgmg::IR`を返します.この場合,鍛冶Lv,防具製作Lv,道具製作Lvの3変数からなる関数オブジェクトを保持するものとして扱われます.各装備の種別に応じ,鍛冶Lvまたは防具製作Lvを適用し,9パラ値を計算します.
|
63
65
|
|
64
|
-
## `String#smith_seach(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)`
|
66
|
+
## `String#smith_seach(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])`
|
65
67
|
`para`の値が`target`以上となるのに必要な最小の鍛冶・防具製作Lvを二分探索で探索して返します.
|
66
68
|
道具製作Lvは`comp`で固定,鍛冶・防具製作Lvを`smith_min`と`smith_max`で挟み込んで探索します.
|
69
|
+
|
67
70
|
`smith_min`が`nil`のとき,`min_smith`が真なら重量を問わず☆的に必要な最小の鍛冶・防具製作Lv (`self.min_smith`),偽なら最小重量で製作するのに必要な鍛冶・防具製作Lv (`self.build.min_level`)を使用します.
|
68
71
|
`smith_min<smith_max`でないとき,`smith_max`で`para`が`target`以上でないときは`ArgumentError`となります.
|
72
|
+
|
69
73
|
`para`は,`Mgmg::Equip`のメソッド名をシンボルで指定(`:power, :fpower`も可)します.
|
70
74
|
反転などの影響で,探索範囲において`para`の値が(広義)単調増加になっていない場合,正しい結果を返しません.
|
71
75
|
`cut_exp`以下の経験値で`target`以上を達成できない場合,`Mgmg::SearchCutException`を発生します.
|
72
76
|
|
73
|
-
|
77
|
+
`irep`に`Mgmg::IR`オブジェクトが渡された場合,`self`を無視して`irep`を使って探索します.
|
78
|
+
`reinforcement`が渡された場合,`para`を強化された値として計算します.`irep`が指定されている場合は無視されます.
|
79
|
+
|
80
|
+
## `String#comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true, irep: nil, reinforcement: [])`
|
74
81
|
`String#smith_seach`とは逆に,鍛冶・防具製作Lvを固定して最小の道具製作Lvを探索します.
|
75
82
|
`comp_min`が`nil`のときは,製作に必要な最小の道具製作Lv (`self.min_comp`)を使用します.
|
76
83
|
その他は`String#smith_seach`と同様です.
|
77
84
|
|
78
|
-
## `String#search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false)`
|
85
|
+
## `String#search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])`
|
79
86
|
`c_min=comp_search(para, target, smith_max, comp_min, comp_max)` から `c_max=comp_search(para, target, smith_max, comp_min, comp_max)` まで,`step`ずつ動かして,
|
80
87
|
`smith_search`を行い,その過程で得られた最小経験値の鍛冶・防具製作Lvと道具製作Lvからなる配列を返します.
|
81
88
|
レシピ中の,対象パラメータの種別値がすべて奇数,または全て偶数であるなら,`step`を`2`にしても探索すべき範囲を網羅できます.
|
82
|
-
|
89
|
+
その他は`String#smith_seach`と同様です.
|
83
90
|
|
84
|
-
## `Enumerable#search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false)`
|
91
|
+
## `Enumerable#search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])`
|
85
92
|
複数装備の組について,`para`の値が`target`以上となる最小経験値の`[鍛冶Lv,防具製作Lv,道具製作Lv]`を返します.
|
86
93
|
武器のみなら防具製作Lvは`0`,防具のみなら鍛冶Lvは`0`,合成なしなら道具製作Lvは`0`となります.
|
87
|
-
|
94
|
+
その他は`String#smith_seach`と同様です.
|
88
95
|
|
89
|
-
## `Mgmg.#find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)`
|
96
|
+
## `Mgmg.#find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])`
|
90
97
|
レシピ`a`とレシピ`b`について,`para`の値を目標値以上にする最小経験値の組において,目標値`start`における優劣が逆転する目標値の下限を探索し,返します.
|
91
98
|
返り値は`[逆転しない最大目標値, 逆転時の最小para値]`です.前者は逆転目標値の下限,後者は,目標値が前者よりも少しだけ大きいときの`para`値です.
|
92
99
|
ここで,最小経験値が小さい方,または最小経験値が同じなら,そのときの`para`値が大きい方をよりよいものと解釈します.
|
@@ -96,7 +103,7 @@
|
|
96
103
|
`smith_min_a`,`smith_min_b`,`armor_min_a`,`armor_min_b`は,それぞれ`a`と`b`の探索最小鍛冶・防具製作Lvを指定します.`a`,`b`が`String`の場合,防具についても`smith_min_a`,`smith_min_b`を指定します.`Enumerable`の場合は,鍛冶と防具製作についてそれぞれ指定します.
|
97
104
|
これらが`nil`で,`min_smith`が真ならば,重量を無視した製作可能最小Lvが指定されます.`min_smith`が偽(デフォルト)ならば,最小重量で製作可能な製作Lvが指定されます.重量を無視した製作可能Lvでの重量が3で,重量が2以下となる製作Lvで探索したい場合などは,`smith_min_a`,`smith_min_b`,`armor_min_a`,`armor_min_b`を具体的に指定してください.
|
98
105
|
|
99
|
-
## `Mgmg.#find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false)`
|
106
|
+
## `Mgmg.#find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])`
|
100
107
|
`Mgmg.#find_lowerbound`とは逆に,目標値を下げながら,優劣が逆転する最大の目標値を探索し,返します.返り値は`[逆転する最大目標値, 逆転前の最小para値]`です.目標値が,前者よりも少しでも大きいと逆転が起こらず(逆転する目標値の上限),少しだけ大きい時の`para`値が後者になります.
|
101
108
|
|
102
109
|
## `String#eff(para, smith, comp=smith, left_associative: true)`
|
@@ -119,7 +126,7 @@
|
|
119
126
|
鍛冶Lvを0から`smith`に,防具製作Lvを0から`armor`に,道具製作Lvを0から`comp`に上げるのに必要な総経験値を返します.鍛冶Lvと防具製作Lvは逆でも同じです.
|
120
127
|
|
121
128
|
## `Mgmg::Equip`
|
122
|
-
|
129
|
+
[前述](#stringbuildsmith-1-compsmith-left_associative-true)の`String#build`によって生成される装備品のクラスです.複数装備の合計値を表す「複数装備」という種別の装備品の場合もあります.以下のようなインスタンスメソッドが定義されています.
|
123
130
|
|
124
131
|
## `Mgmg::Equip#to_s`
|
125
132
|
```ruby
|
@@ -208,8 +215,28 @@
|
|
208
215
|
## `Mgmg::Equip#min_level(weight=1)`
|
209
216
|
`min_levels(weight)`の値の最大値を返します.「複数装備」の場合,`[鍛冶の必要レベル,防具製作の必要レベル]`を返します.
|
210
217
|
|
218
|
+
## `Mgmg::Equip#reinforce(*arg)`
|
219
|
+
`self`を破壊的に変更し,スキルや料理で強化した値をシミュレートします.
|
220
|
+
引数には,スキル名または[後述](#mgmgcuisine)する`Mgmg::Cuisine`オブジェクトを並べます.
|
221
|
+
[料理店の料理](#引数1つ)および[登録されている料理](#引数3つ)については,料理名の`String`を直接指定することもできます.
|
222
|
+
同一のスキルを複数並べるなど,実際には重複しない組み合わせであっても,特に配慮せずにすべて重ねて強化します.
|
223
|
+
現在対応しているスキルは以下の通りです(効果に誤りがあればご指摘ください).
|
224
|
+
|
225
|
+
|スキル|効果|備考|
|
226
|
+
|:-|:-|:-|
|
227
|
+
|物防御UP|物防x1.1|剣パッシブ|
|
228
|
+
|魔防御UP|魔防x1.1|本パッシブ|
|
229
|
+
|腕力UP|腕力x1.1|斧パッシブ|
|
230
|
+
|メンテナンス|攻撃x1.5|弩アクティブ|
|
231
|
+
|ガードアップ|物防x1.5|剣アクティブ|
|
232
|
+
|パワーアップ|腕力x1.5|本アクティブ|
|
233
|
+
|デックスアップ|器用x1.5|弓アクティブ|
|
234
|
+
|スピードアップ|素早x1.5|短剣アクティブ|
|
235
|
+
|マジックアップ|魔力x1.5|本アクティブ|
|
236
|
+
|オールアップ|物防,腕力,器用,素早,魔力x1.5|本アクティブ|
|
237
|
+
|
211
238
|
## `Mgmg::TPolynomial`
|
212
|
-
|
239
|
+
[前述](#stringpolyparacost-left_associative-true)の`String#poly`によって生成される二変数多項式のクラスです.最初のTはtwo-variableのTです.以下のようなメソッドが定義されています.
|
213
240
|
|
214
241
|
## `Mgmg::TPolynomial#to_s(fmt=nil)`
|
215
242
|
鍛冶・防具製作LvをS,道具製作LvをCとして,`self`を表す数式文字列を返します.係数`coeff`を文字列に変換する際,`fmt`の値に応じて次の方法を用います.
|
@@ -255,7 +282,7 @@ alias として`*`があるほか`scalar(1.quo(value))`として`quo`,`/`,`s
|
|
255
282
|
一方のみが欲しい場合,`Mgmg::TPolynomial#smith_eff(smith, comp=smith)`,`Mgmg::TPolynomial#smith_eff(smith, comp=smith)`が使えます.
|
256
283
|
|
257
284
|
## `Mgmg::IR`
|
258
|
-
|
285
|
+
[前述](#stringirleft_associative-true-reinforcement-)の`String#ir`または`Enumerable#ir`によって生成される,9パラ値を計算するための,2変数または3変数の関数オブジェクトを保持するクラスです.`Mgmg::IR`では,`Mgmg::Equip`と異なり,重量,EL値,総消費エレメントを取り扱いません.
|
259
286
|
|
260
287
|
## `Mgmg::IR#to_s`
|
261
288
|
例えば,「斧(牙9皮9)+短剣(鉄9皮2)」のレシピに対して,
|
@@ -287,3 +314,61 @@ alias として`*`があるほか`scalar(1.quo(value))`として`quo`,`/`,`s
|
|
287
314
|
|
288
315
|
## `Mgmg::IR#smith_cost, comp_cost(s, c=s, outsourcing=false)`
|
289
316
|
`Mgmg::Equip`における同名メソッドと同様に,鍛冶・防具製作コストまたは武具合成コストを計算して返します.複数装備では意味のある値を計算できないため,製作Lvの3種入力はできません.
|
317
|
+
また,これらのメソッドのみ,`reinforcement`を無視します.
|
318
|
+
|
319
|
+
## `Mgmg::Cuisine`
|
320
|
+
[前述](#mgmgequipreinforcearg)の`Mgmg::Equip#reinforce`で使用する料理オブジェクトです.料理効果のうち,攻撃,物防,魔防のみが装備を強化できるため,この3パラメータのみを取り扱います.
|
321
|
+
|
322
|
+
## `Mgmg.#cuisine(*arg)`
|
323
|
+
`Mgmg::Cuisine`オブジェクトを生成するためのモジュール関数です.引数の数によって,下記のように生成します.
|
324
|
+
|
325
|
+
### 引数1つ
|
326
|
+
街の料理点の料理名を指定します.対応している料理は以下のとおりです.サボテン焼きは☆1と☆7の2種類があるため,区別のために数字を付与した名前を指定します.
|
327
|
+
また,次節のプリセット料理も,同様に料理名のみで指定できます.
|
328
|
+
|
329
|
+
|料理名|攻撃|物防|魔防|
|
330
|
+
|:-|-:|-:|-:|
|
331
|
+
|焼き肉|5|0|0|
|
332
|
+
|焼き金肉|10|0|0|
|
333
|
+
|焼き黄金肉|15|0|0|
|
334
|
+
|焼きリンゴ|0|5|0|
|
335
|
+
|焼きイチゴ|0|10|0|
|
336
|
+
|焼きネギタマ|0|15|0|
|
337
|
+
|サボテン焼き1|5|5|0|
|
338
|
+
|サボテンバーガー|10|10|0|
|
339
|
+
|サボテン焼き7|15|15|0|
|
340
|
+
|
341
|
+
### 引数3つ
|
342
|
+
攻撃,物防,魔防の強化値を,この順で直接整数で指定します.任意の強化値を指定できますが,強化値は別で調べておく必要があります.
|
343
|
+
以下の料理については,作成できる最小料理Lvで作成したときの強化値は表の通りで,これらはプリセットとして,料理名のみを引数として指定できます.
|
344
|
+
これらの料理名については,エイリアスとして,「(主食材)の(副食材)(焼き|蒸し)」の形式も受け付けます.
|
345
|
+
|
346
|
+
|料理名|料理Lv|攻撃|物防|魔防|
|
347
|
+
|:-|-:|-:|-:|-:|
|
348
|
+
|獣肉とカエン酒の丸焼き|0|8|0|0|
|
349
|
+
|ウッチと氷酒の蒸し焼き|0|0|11|10|
|
350
|
+
|ウッチとカエン酒の蒸し焼き|0|0|10|11|
|
351
|
+
|ゴッチと氷酒の蒸し焼き|3|0|15|13|
|
352
|
+
|ゴッチとカエン酒の蒸し焼き|3|0|13|15|
|
353
|
+
|ガガッチと氷水酒の蒸し焼き|6|0|19|15|
|
354
|
+
|ガガッチと爆炎酒の蒸し焼き|6|0|15|19|
|
355
|
+
|ガガッチと氷河酒の蒸し焼き|12|0|22|16|
|
356
|
+
|ガガッチと煉獄酒の蒸し焼き|12|0|16|22|
|
357
|
+
|ドランギョと煉獄酒の丸焼き|15|15|11|6|
|
358
|
+
|ドランギョと煉獄酒の蒸し焼き|15|9|18|15|
|
359
|
+
|ドランギョと氷河酒の蒸し焼き|15|6|24|11|
|
360
|
+
|ドラバーンと煉獄酒の丸焼き|24|23|17|9|
|
361
|
+
|ドラバーンと煉獄酒の蒸し焼き|24|14|26|25|
|
362
|
+
|ドラバーンと氷河酒の蒸し焼き|24|10|35|19|
|
363
|
+
|フレドランと煉獄酒の丸焼き|27|59|0|0|
|
364
|
+
|ダークドンと煉獄酒の丸焼き|27|35|26|21|
|
365
|
+
|ダークドンと氷河酒の丸焼き|27|26|35|15|
|
366
|
+
|ダークドンと煉獄酒の蒸し焼き|27|21|38|52|
|
367
|
+
|ダークドンと氷河酒の蒸し焼き|27|15|52|38|
|
368
|
+
|アースドランと氷河酒の蒸し焼き|27|0|87|0|
|
369
|
+
|アクアドランと煉獄酒の蒸し焼き|27|0|0|87|
|
370
|
+
|
371
|
+
### 引数4つ
|
372
|
+
調理法,主食材,副食材,料理Lvを指定し,対応する料理の効果の**概算値**を計算します.計算式は [Wikiの記述](https://wikiwiki.jp/guruguru/%E3%82%A2%E3%82%A4%E3%83%86%E3%83%A0/%E9%A3%9F%E7%B3%A7%E5%93%81#y1576f2d) に基づきますが,正確ではないことがわかっています.例えば,`('蒸す', 'アースドラン', '氷河酒', 27)`の物防は87ですが,この計算式では88になります.調理法,主食材,副食材は文字列で,料理Lvは整数で指定します.
|
373
|
+
|
374
|
+
調理法は「焼き」か「蒸す」,主食材は「獣肉」「ウッチ」「ゴッチ」「ガガッチ」「ドランギョ」「ドラバーン」「フレドラン」「アースドラン」「アクアドラン」「ダークドン」,副食材は「氷酒」「氷水酒」「氷河酒」「カエン酒」「爆炎酒」「煉獄酒」のみ対応しています.攻撃,物防,魔防の強化を考える場合,これらで十分と判断しての選択となっています.なお,副食材の数値は,Wikiの表で順番が間違っていると思われる部分を修正しています.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mgmg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- KAZOON
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -69,10 +69,12 @@ files:
|
|
69
69
|
- bin/setup
|
70
70
|
- lib/mgmg.rb
|
71
71
|
- lib/mgmg/const.rb
|
72
|
+
- lib/mgmg/cuisine.rb
|
72
73
|
- lib/mgmg/equip.rb
|
73
74
|
- lib/mgmg/ir.rb
|
74
75
|
- lib/mgmg/optimize.rb
|
75
76
|
- lib/mgmg/poly.rb
|
77
|
+
- lib/mgmg/reinforce.rb
|
76
78
|
- lib/mgmg/search.rb
|
77
79
|
- lib/mgmg/system_equip.rb
|
78
80
|
- lib/mgmg/utils.rb
|
@@ -100,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
100
102
|
- !ruby/object:Gem::Version
|
101
103
|
version: '0'
|
102
104
|
requirements: []
|
103
|
-
rubygems_version: 3.3.
|
105
|
+
rubygems_version: 3.3.15
|
104
106
|
signing_key:
|
105
107
|
specification_version: 4
|
106
108
|
summary: Calculate specs of equipments of Megurimeguru, a game produced by Kou.
|